This is an automated email from the ASF dual-hosted git repository.

wenjin272 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/flink-agents.git

commit c36d084d38805206f146aafc930f71f4c79f0011
Author: WenjinXie <[email protected]>
AuthorDate: Fri Oct 16 13:06:20 2026 +0800

    [docs] Clarify YAML declarations and document subagents
    
    Explain the boundary between YAML configuration and implementation code.
    Clarify prompt validation, required fields, type applicability and provider
    aliases. Keep tool injection and skill source behavior in their dedicated
    guides, and remove maintainer-only mapping and consistency details.
    
    Document internal child references and external subagent setups, including
    examples, input schema configuration, cross-file loading order, name
    uniqueness and cycle validation. Link the YAML and Subagents guides in
    both directions.
    
    Validated with Hugo and internal links/anchors in both the current tree and
    a temporary documentation overlay of PR #1261. Subagent examples pass the 
Pydantic models and generated JSON Schema,
    with the incremental fragment combined with the earlier single-agent 
example.
    
    Generated-by: Codex CLI 0.153.4 (GPT-6)
    
    Co-authored-by: Codex <[email protected]>
---
 docs/content/docs/development/create-agent/yaml.md | 334 +++++++++++++--------
 .../docs/development/multi-agent/subagents.md      |   5 +
 2 files changed, 210 insertions(+), 129 deletions(-)

diff --git a/docs/content/docs/development/create-agent/yaml.md 
b/docs/content/docs/development/create-agent/yaml.md
index b00b0f65..c0a81e80 100644
--- a/docs/content/docs/development/create-agent/yaml.md
+++ b/docs/content/docs/development/create-agent/yaml.md
@@ -26,15 +26,27 @@ under the License.
 
 ## Overview
 
-Beyond the Python and Java programmatic APIs, Flink Agents offers a 
**declarative YAML API** for describing agents. Compared with the programmatic 
APIs, the YAML API has the following advantages:
+Flink Agents provides a **declarative YAML API** for defining and 
orchestrating Agents.
+It uses the same Events, Actions, and Resources as the Java and Python APIs, 
described in
+[Core Concepts]({{< ref "docs/development/create-agent/overview#core-concepts" 
>}}).
 
-- **Human-friendly**: low entry barrier and easy to templatize across 
deployments.
-- **Coding-agent-friendly**: a fixed schema reduces token cost, enables strict 
schema validation, and decouples configuration changes (declared parameters) 
from logic changes (action code).
+Parts of an Agent definition can be expressed directly in YAML, while the
+implementation logic remains in Java or Python code:
 
-The YAML API uses the same Events, Actions, and Resources described in
-[Core Concepts]({{< ref "docs/development/create-agent/overview#core-concepts" 
>}}).
+**What can be defined in YAML:**
+
+- Which Actions make up an Agent and which Events trigger them.
+- Which Resources are available and how components reference them.
+- The existing implementations to use and their configuration.
+- Inline prompt text or messages.
 
-A YAML file describes **Resources** and **Actions** declaratively; the 
**Event** types are referenced by name (built-in event aliases like `input` / 
`chat_response`, or your own event-type strings). The implementation classes 
(action functions, tool functions, custom types) still live in your Python or 
Java code; the YAML file only describes *how* those pieces are wired together.
+**What remains in code:**
+
+- Action and tool logic.
+- Custom Resource implementations.
+- Custom Event classes.
+
+This lets you change component configuration and wiring while reusing the same 
code.
 
 If you'd rather declare agents directly in code, see [Agent]({{< ref 
"docs/development/create-agent/overview" >}}) and [Built-in ReAct Agent]({{< 
ref "docs/development/react_agent" >}}).
 
@@ -45,6 +57,7 @@ This section walks through:
 1. Declaring a single agent in one YAML file.
 2. Declaring multiple agents in one YAML file.
 3. Declaring shared Resources and Actions that any agent in the file (or any 
later-loaded file) can reuse.
+4. Declaring sub-agents and referencing them from a parent Agent.
 
 ### Declaring a single agent
 
@@ -101,28 +114,33 @@ agents:
 
 | Field | Required | Description |
 |-------|----------|-------------|
-| `name` | yes | Agent name. Must be unique across the environment. Used to 
apply the agent by name later. |
-| `description` | no | Free-form description of what the agent does. Not 
surfaced at runtime. |
+| `name` | Required | Agent name. Must be unique across the environment. Used 
to apply the agent by name later. |
+| `description` | Optional | Free-form description of what the agent does. Not 
surfaced at runtime. |
 
 #### Resources
 
 Declare Resources as lists under the agent, with a `name` unique within each 
section.
 The section determines the resource type: for example, `chat_model_setups` 
registers
-`CHAT_MODEL` Resources and `tools` registers `TOOL` Resources. The optional 
`type: python`
-or `type: java` field selects the implementation language.
+`CHAT_MODEL` Resources and `tools` registers `TOOL` Resources. For Resources 
configured
+by implementation class and for Tools, the optional `type: python` or `type: 
java`
+field selects the implementation language. Prompts and Skills do not accept 
`type`.
 
 These declarations register Resources for use by name, just like decorators, 
annotations,
 or `add_resource` / `addResource`. Actions can get their instances through
 `ctx.get_resource` / `ctx.getResource`; see
 [Registering and Referencing Resources]({{< ref 
"docs/development/create-agent/overview#registering-and-referencing-resources" 
>}}).
 
-**Prompt** — declarative prompt template; pick exactly one of `text` or 
`messages`.
+**Prompt** — declarative prompt template. Exactly one of `text` or `messages` 
must be non-empty.
 
 | Field | Required | Description |
 |-------|----------|-------------|
-| `name` | yes | Prompt name (referenced by chat-model setups). |
-| `text` | one-of | Single-string prompt template. Corresponds to 
`Prompt.from_text` / `Prompt.fromText`. |
-| `messages` | one-of | Multi-turn message template. Corresponds to 
`Prompt.from_messages` / `Prompt.fromMessages`. Each entry has `role` (`system` 
/ `user` / `assistant` / `tool`) and `content`. |
+| `name` | Required | Prompt name (referenced by chat-model setups). |
+| `text` | Required if `messages` is unset or empty | Non-empty string prompt 
template. Corresponds to `Prompt.from_text` / `Prompt.fromText`. |
+| `messages` | Required if `text` is unset or empty | Non-empty list of 
message templates. Corresponds to `Prompt.from_messages` / 
`Prompt.fromMessages`. Each entry has `role` (`system` / `user` / `assistant` / 
`tool`) and `content`. |
+
+Omitted or `null` fields, `text: ""`, and `messages: []` are treated as unset.
+If both alternatives are non-empty, or neither is non-empty, YAML loading fails
+validation. Neither alternative takes precedence over the other.
 
 ```yaml
 prompts:
@@ -140,11 +158,11 @@ prompts:
 
 | Field | Required | Description |
 |-------|----------|-------------|
-| `name` | yes | Tool name (referenced from `chat_model_setups[].tools`). |
-| `function` | yes | Fully-qualified callable in the form 
`<module-or-class>:<qualname>`. See [Function 
references](#function-references). |
-| `type` | no | Implementation language: `python` or `java`. Defaults to 
`python` (see [Selecting the implementation 
language](#selecting-the-implementation-language)). |
-| `parameter_types` | java only | Required for Java tools — one Java type FQN 
per declared parameter, in order. Forbidden for Python tools (the signature is 
reflected from the callable). |
-| `injected_args` | no | Tool arguments injected by the framework at execution 
time. Declare a map from tool parameter name to `{source, key}`. These 
arguments are hidden from the model-facing tool schema. |
+| `name` | Required | Tool name (referenced from `chat_model_setups[].tools`). 
|
+| `function` | Required | Fully-qualified callable in the form 
`<module-or-class>:<qualname>`. See [Function 
references](#function-references). |
+| `type` | Optional | Implementation language: `python` or `java`. Defaults to 
`python` (see [Selecting the implementation 
language](#selecting-the-implementation-language)). |
+| `parameter_types` | Required for Java / Forbidden for Python | One Java type 
per declared parameter, in order. Use `[]` for a Java tool with no parameters. 
Python tool signatures are reflected from the callable. |
+| `injected_args` | Optional | Tool arguments injected by the framework at 
execution time. Declare a map from tool parameter name to `{source, key}`. 
These arguments are hidden from the model-facing tool schema. |
 
 ```yaml
 tools:
@@ -153,7 +171,7 @@ tools:
     type: python
 ```
 
-For **Java tools**, `parameter_types` is required because Java methods can be 
overloaded — list one FQN per declared parameter, in order. Generic type 
arguments are not part of the JVM method descriptor and must not be included 
(`java.util.List`, not `java.util.List<String>`). Boxed primitives 
(`java.lang.Integer`, etc.) and bare primitives (`int`, `boolean`, ...) are 
both accepted.
+For **Java tools**, `parameter_types` is required because Java methods can be 
overloaded — list one Java type per declared parameter, in order.
 
 ```yaml
 tools:
@@ -163,84 +181,52 @@ tools:
     parameter_types: [java.lang.Integer, java.lang.Integer]
 ```
 
-To hide framework-owned arguments from the model, declare them in 
`injected_args` and bind each argument to a runtime source:
-
-```yaml
-agents:
-  - name: order_agent
-    tools:
-      - name: query_order
-        function: my_pkg.tools:query_order
-        injected_args:
-          tenant_id:
-            source: config
-            key: tenant_id
-```
-
-The supported `source` values are `config`, `sensory_memory`, and 
`short_term_memory`. If omitted, `source` defaults to `sensory_memory`. For 
`config`, `key` is read from the agent execution environment configuration. For 
memory sources, `key` is the memory path.
+{{< hint info >}}
+Generic type arguments are not part of the JVM method descriptor and must not 
be
+included (`java.util.List`, not `java.util.List<String>`). Boxed primitives
+(`java.lang.Integer`, etc.) and bare primitives (`int`, `boolean`, ...) are 
both accepted.
+{{< /hint >}}
 
-See [Tool Parameter Injection]({{< ref 
"docs/development/calling-llms/tool_use#tool-parameter-injection" >}}) for 
runtime value resolution, overriding model-supplied arguments, and 
missing-value behavior.
+`injected_args` maps tool parameter names to injection settings. Each entry 
must be
+an object with the following optional fields. Omit `injected_args` or use `{}` 
if
+you do not need to declare parameter injection in YAML.
 
-For Java tools loaded from YAML, the `injected_args` entry itself marks the 
parameter
-as framework-injected and hides it from the model-facing schema. The Java 
method may
-use `@ToolParam(name = "...")` to provide stable parameter names, but it does 
not need
-`@ToolParam(injected = true)` when injection is declared in YAML.
-If both YAML and the tool function declare the same injected parameter, they 
must use
-the same source and key; conflicting declarations fail during agent plan 
construction.
+| Field | Required | Description |
+|-------|----------|-------------|
+| `source` | Optional | One of `config`, `sensory_memory`, or 
`short_term_memory`. Defaults to `sensory_memory`. |
+| `key` | Optional | Configuration key or memory path. If omitted, `null`, or 
empty, defaults to the tool parameter name. |
 
-Per-request values, such as a trace id written to sensory memory before tool 
execution, can be injected the same way:
+For example, declare injection for the `tenant_id` parameter of `query_order`:
 
 ```yaml
-agents:
-  - name: traced_order_agent
-    tools:
-      - name: lookup_order
-        function: my_pkg.tools:lookup_order
-        injected_args:
-          trace_id:
-            source: sensory_memory
-            key: request.trace_id
+tools:
+  - name: query_order
+    function: my_pkg.tools:query_order
+    injected_args:
+      tenant_id:
+        source: config
+        key: tenant_id
 ```
 
-```yaml
-# Java-loaded YAML
-agents:
-  - name: java_order_agent
-    tools:
-      - name: queryOrder
-        type: java
-        function: com.example.OrderTools:queryOrder
-        parameter_types: [java.lang.String, java.lang.String]
-        injected_args:
-          tenant_id:
-            source: config
-            key: tenant_id
-```
+See [Tool Parameter Injection]({{< ref 
"docs/development/calling-llms/tool_use#tool-parameter-injection" >}})
+for when to use injection, runtime value resolution, Java annotations, and
+conflict and failure rules.
 
-**Skills** — bundles of agent skill assets loaded from one or more sources. At 
least one of `paths` / `urls` / `url_sources` / `classpath` / `package` must be 
non-empty; multiple sources can coexist.
+**Skills** — bundles of agent skill assets loaded from one or more sources.
 
 | Field | Required | Description |
 |-------|----------|-------------|
-| `name` | yes | Skills resource name. |
-| `paths` | one-of | `local` scheme: list of directories or `.zip` files. |
-| `urls` | one-of | `url` scheme: list of HTTPS URLs without embedded user 
information, pointing to `.zip` archives. |
-| `url_sources` | one-of | `url` scheme: list of `{url, sha256?, 
allow_insecure_http?}` archive sources without embedded user information. HTTPS 
is required by default; `sha256` pins the downloaded archive, and 
`allow_insecure_http: true` is an explicit unsafe compatibility opt-in. |
-| `classpath` | one-of | `classpath` scheme (Java runtime only): list of 
classpath resource paths. |
-| `package` | one-of | `package` scheme (Python runtime only): list of 
`{package, resource}` pairs. |
-
-`urls` entries must use HTTPS. To keep an existing plain-HTTP source, move it 
to `url_sources` and opt in explicitly:
+| `name` | Required | Skills resource name. |
+| `paths` | Optional | `local` scheme: list of directories or `.zip` files. |
+| `urls` | Optional | `url` scheme: list of HTTPS URLs pointing to `.zip` 
archives. |
+| `url_sources` | Optional | `url` scheme: list of objects with a required 
`url`, optional `sha256` digest, and optional `allow_insecure_http` flag 
(defaults to `false`). Set the flag to `true` to allow plain HTTP. |
+| `classpath` | Optional | `classpath` scheme: list of Java classpath resource 
paths. |
+| `package` | Optional | `package` scheme: list of Python `{package, 
resource}` pairs. |
 
-```yaml
-skills:
-  - name: agent_skills
-    url_sources:
-      - url: http://example.com/skills.zip
-        allow_insecure_http: true
-```
-
-Use this compatibility option only on trusted development networks; prefer 
HTTPS.
-
-URL source hosts must use DNS-compatible ASCII syntax. Names containing 
underscores, such as `skill_server`, are rejected; use a DNS-compatible name 
such as `skill-server`. Internationalized hostnames must use IDNA/Punycode 
rather than raw Unicode, and scoped IPv6 literals with zone identifiers are 
rejected. This validation is stricter than in earlier releases.
+{{< hint info >}}
+At least one of `paths`, `urls`, `url_sources`, `classpath`, or `package` must 
be non-empty.
+Multiple sources can be configured together.
+{{< /hint >}}
 
 ```yaml
 skills:
@@ -259,22 +245,25 @@ skills:
         resource: skills/
 ```
 
-`classpath` is accepted by the Python parser for schema parity with Java but 
rejected at runtime, because the Python runtime does not register a `classpath` 
handler.
-
-Remote skill archives contain trusted agent instructions and may contain 
executable scripts. Pin remote sources with `sha256`, or use 
`Skills.from_url_with_sha256(...)` (Python) / `Skills.fromUrlWithSha256(...)` 
(Java) in code.
+Both `classpath` and `package` sources are supported by Java and Python agents.
+See
+[Skill Sources]({{< ref "docs/development/calling-llms/skills#skill-sources" 
>}})
+for URL restrictions, archive integrity and security guidance, and dependency 
and
+cross-language runtime requirements.
 
 **Resources configured by implementation class** — `chat_model_connections`,
 `chat_model_setups`, `embedding_model_connections`, `embedding_model_setups`, 
`vector_stores`,
-and `mcp_servers`. Declare the implementation and its configuration using the 
fields below.
+and `mcp_servers`, plus `subagents` for external sub-agents. Declare the 
implementation
+and its configuration using the fields below.
 This corresponds to a `ResourceDescriptor` in Java or Python; the framework 
creates the
 Resource instance at runtime.
 
 | Field | Required | Description |
 |-------|----------|-------------|
-| `name` | yes | Resource name (referenced by other resources or actions). |
-| `clazz` | yes | Either a built-in [alias](#class-aliases) (e.g. `ollama`, 
`openai`) or a fully-qualified class path. |
-| `type` | no | Implementation language: `python` or `java`. Defaults to 
`python` (see [Selecting the implementation 
language](#selecting-the-implementation-language)). |
-| *extras* | no | Additional configuration for the selected implementation 
(e.g. `base_url`, `endpoint`, `model`, `request_timeout`). |
+| `name` | Required | Resource name (referenced by other resources or 
actions). |
+| `clazz` | Required | Either a built-in [alias](#class-aliases) (e.g. 
`ollama`, `openai`) or a fully-qualified class path. |
+| `type` | Optional | Implementation language: `python` or `java`. Defaults to 
`python` (see [Selecting the implementation 
language](#selecting-the-implementation-language)). |
+| *extras* | Depends on the selected implementation | Additional configuration 
for the selected implementation (e.g. `base_url`, `endpoint`, `model`, 
`request_timeout`). See its provider documentation for required fields and 
defaults. |
 
 ```yaml
 chat_model_connections:
@@ -290,6 +279,10 @@ mcp_servers:
     endpoint: http://127.0.0.1:8000/mcp
 ```
 
+**Sub-agents** are registered under `subagents` as `AGENT` Resources. Internal
+sub-agents reference another Agent in the same file or already loaded into the 
same
+environment; external sub-agents name a setup implementation. See [Declaring 
sub-agents](#declaring-sub-agents).
+
 **References between Resources.** Fields such as `connection`, `prompt`, and 
`tools`
 refer to registered Resource names. The Agent's own registrations take 
precedence over
 shared Resources from the execution environment. In the [single-agent 
example](#declaring-a-single-agent):
@@ -299,6 +292,7 @@ shared Resources from the execution environment. In the 
[single-agent example](#
 | `chat_model_setups[].connection` | a `chat_model_connections[]` name | 
`connection: ollama_server` |
 | `chat_model_setups[].prompt` | a `prompts[]` name | `prompt: 
review_analysis_prompt` |
 | `chat_model_setups[].tools` | a list of `tools[]` names | `tools: 
[notify_shipping_manager]` |
+| `chat_model_setups[].subagents` | a list of `subagents[]` resource names | 
`subagents: [reviewer]` |
 | `embedding_model_setups[].connection` | an `embedding_model_connections[]` 
name | `connection: my_embedding_server` |
 
 The referenced Resource must be registered on the Agent or its execution 
environment.
@@ -321,11 +315,11 @@ Inline action (map) fields:
 
 | Field | Required | Description |
 |-------|----------|-------------|
-| `name` | yes | Action name (unique within the agent). |
-| `function` | yes | Fully-qualified callable in the form 
`<module-or-class>:<qualname>`. See [Function 
references](#function-references). |
-| `trigger_conditions` | yes | Non-empty list of strings containing exact 
event types or condition expressions that return a Boolean. Each string must 
contain at least one non-whitespace character. Built-in [event 
aliases](#event-aliases) (`input`, `chat_request`, ...) may be used as complete 
entries. All entries use OR semantics. |
-| `type` | no | Implementation language: `python` or `java`. Defaults to 
`python` (see [Selecting the implementation 
language](#selecting-the-implementation-language)). |
-| `config` | no | Free-form configuration map passed to the action at runtime. 
|
+| `name` | Required | Action name (unique within the agent). |
+| `function` | Required | Fully-qualified callable in the form 
`<module-or-class>:<qualname>`. See [Function 
references](#function-references). |
+| `trigger_conditions` | Required | Non-empty list of strings containing exact 
event types or condition expressions that return a Boolean. Each string must 
contain at least one non-whitespace character. Built-in [event 
aliases](#event-aliases) (`input`, `chat_request`, ...) may be used as complete 
entries. All entries use OR semantics. |
+| `type` | Optional | Implementation language: `python` or `java`. Defaults to 
`python` (see [Selecting the implementation 
language](#selecting-the-implementation-language)). |
+| `config` | Optional | Free-form configuration map passed to the action at 
runtime. |
 
 For built-in event types, prefer an [event alias](#event-aliases) such as 
`input`. Trigger-condition
 matching and expression semantics are shared with annotated and 
programmatically registered actions;
@@ -442,6 +436,107 @@ actions:
 Composing one agent across multiple YAML files is **not** supported. If two 
files loaded into the same environment declare the same agent name, or the same 
shared resource/action name, the second `load_yaml` call raises an error.
 {{< /hint >}}
 
+### Declaring sub-agents
+
+Use an internal sub-agent to delegate to another Agent defined in your 
application,
+or an external sub-agent to call an agent hosted by another system.
+
+#### Internal sub-agents
+
+To make a child Agent available to a parent Agent, add an entry to the parent's
+`subagents` list. Each entry uses the following fields:
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `name` | Required | Resource name the parent uses to call this sub-agent. |
+| `agent` | Required | Value of the child Agent's `name` field in the 
top-level `agents` list. |
+| `description` | Optional | Describes when the model should delegate to this 
child. Defaults to an empty string; a generic description is used if none is 
supplied. |
+| `input_schema` | Required for model-selected calls | JSON Schema written as 
a YAML mapping describing the child's input arguments. It can be omitted when 
calling the sub-agent directly from an Action. |
+
+The following fragment extends the [single-agent 
example](#declaring-a-single-agent).
+Keep the parent's existing configuration and add the declarations shown below.
+The child Agent's Actions and Resources are omitted.
+
+```yaml
+agents:
+  - name: review_analysis_agent
+    # Existing Actions and Resources omitted.
+    subagents:
+      - name: reviewer
+        agent: review_workflow
+        description: Analyze product review details
+        input_schema:
+          type: object
+          properties:
+            review: {type: string}
+          required: [review]
+    chat_model_setups:
+      - name: review_analysis_model
+        # Keep the existing model configuration.
+        subagents: [reviewer]
+
+  - name: review_workflow
+    # Define the child's Actions and Resources here.
+```
+
+Here, `agent: review_workflow` refers to the child defined with
+`name: review_workflow`. The parent model uses the Resource name `reviewer` to 
call it.
+
+Multiple parents may reference the same child definition. Declare internal
+references under each parent's `subagents`; file-level `subagents` supports 
only
+external setup declarations.
+
+The referenced child Agent must be defined in the same YAML file or already 
loaded
+into the same execution environment. Within one file, the child may appear 
before
+or after its parent. For Agents split across files, load the child file before 
the
+parent file. Files in a list are loaded in order, and separate loading calls 
use
+the same rule:
+
+{{< tabs "Load Sub-agent Files" >}}
+{{< tab "Python" >}}
+```python
+agents_env.load_yaml(["child.yaml", "parent.yaml"])
+```
+{{< /tab >}}
+{{< tab "Java" >}}
+```java
+agentsEnv.loadYaml(List.of(Paths.get("child.yaml"), Paths.get("parent.yaml")));
+```
+{{< /tab >}}
+{{< /tabs >}}
+
+An unknown child name fails loading of the referencing file; the loader does 
not
+wait for later files. Agent names must remain unique across the environment.
+Self-references and indirect cycles fail when the Agent plan is built. 
Register the
+child's required Resources on the child itself, as described in
+[Declare an internal sub-agent]({{< ref 
"docs/development/multi-agent/subagents#declare-an-internal-sub-agent" >}}).
+
+For input/output behavior, model delegation, and execution requirements, see
+[Subagents]({{< ref "docs/development/multi-agent/subagents" >}}).
+
+#### External sub-agents
+
+Use `clazz` to name a custom sub-agent setup implementation. Its additional 
fields
+are passed to that implementation as configuration:
+
+```yaml
+subagents:
+  - name: remote_reviewer
+    clazz: my_app.agents.RemoteReviewSetup
+    type: python
+    endpoint: https://example.com/review
+    description: Review code using the remote service
+    input_schema: 
'{"type":"object","properties":{"code":{"type":"string"}},"required":["code"]}'
+```
+
+This example assumes `RemoteReviewSetup` accepts `endpoint`, `description`, 
and a
+JSON string `input_schema`. Use `type: java` and a Java class name when 
loading an
+external Java setup from a Java job. YAML external sub-agent declarations 
currently
+require the setup language to match the loader; an omitted `type` defaults to 
Python.
+Reference `remote_reviewer` in the chat model's `subagents` list to enable 
model delegation.
+See [Declare an external sub-agent]({{< ref 
"docs/development/multi-agent/subagents#declare-an-external-sub-agent" >}})
+for the implementation contract.
+
 ## Loading and Running
 
 YAML describes an Agent but is not submitted to Flink by itself. Create a Java 
Flink
@@ -559,9 +654,12 @@ function: com.example.Outer$Inner:processInput
 
 ### Selecting the implementation language
 
-Every resource, tool, and action accepts an optional `type:` field with values 
`python` or `java`. When omitted, the default is **`python`** — both the Python 
loader and the Java loader treat a missing `type:` as `python`.
+Resources configured by implementation class, Tools, and Actions accept an 
optional
+`type:` field with values `python` or `java`. When omitted, the default is 
**`python`**
+in both loaders. Prompts, Skills, and internal sub-agent references do not 
accept this field.
 
-This means a YAML file loaded by the **Java loader** must set `type: java` 
explicitly on every resource, tool, and action whose implementation is in Java. 
Omitting `type:` on a Java resource in a Java-loaded YAML will make the loader 
try to build a Python-wrapping descriptor — usually not what you want.
+For components that accept `type`, set `type: java` explicitly when selecting 
a Java
+implementation, even when loading the YAML from a Java job.
 
 When `type:` resolves to the **opposite** language of the loader, the loader 
builds a cross-language descriptor that delegates to the other-language 
implementation — see [Cross-language agents](#cross-language-agents).
 
@@ -592,6 +690,10 @@ For custom event types defined in your code, write the 
event's full `EVENT_TYPE`
 
 #### Class aliases
 
+Class aliases cover built-in providers. For custom providers, set `clazz:` to 
the
+fully-qualified class name in Java or class path in Python; custom alias 
registration
+is not supported.
+
 Aliases for `clazz:` are keyed on resource type **and** implementation 
language. The same alias (e.g. `ollama`) resolves to a different class for 
`chat_model_connections` vs `chat_model_setups`, and for `python` vs `java`.
 
 Common chat-model aliases:
@@ -632,8 +734,6 @@ Vector-store aliases:
 
 The full alias tables live in `flink_agents.api.yaml.aliases` (Python) and 
`org.apache.flink.agents.api.yaml.Aliases` (Java).
 
-If `clazz:` is not a known alias, the loader passes it through as-is — write a 
fully-qualified class path (e.g. 
`flink_agents.integrations.chat_models.ollama_chat_model.OllamaChatModelSetup`) 
for providers you've added yourself.
-
 ### Cross-language agents
 
 Setting `type:` to the **opposite** language of the loader bridges Python and 
Java pieces in the same agent. The loader resolves the alias against the 
cross-language bucket and wraps the resource in the appropriate cross-language 
proxy.
@@ -694,7 +794,7 @@ in a Java Flink job and use each component's `type:` to 
select its implementatio
 Application payloads must use the supported
 [Java and Python data types]({{< ref 
"docs/development/create-agent/choose-apis-and-languages#data-passed-between-java-and-python"
 >}}).
 
-Not every resource type is cross-language. Currently `actions`, `tools`, 
`chat_model_connections`, `chat_model_setups`, `embedding_model_connections`, 
`embedding_model_setups`, and `vector_stores` support `type:` on the opposite 
language; others (e.g. `mcp_servers`) do not.
+Not every resource type is cross-language. Currently `actions`, `tools`, 
`chat_model_connections`, `chat_model_setups`, `embedding_model_connections`, 
`embedding_model_setups`, and `vector_stores` support `type:` on the opposite 
language; others (e.g. `mcp_servers` and external `subagents`) do not.
 
 ## YAML API Specification
 
@@ -705,31 +805,7 @@ The schema benefits both humans and machines:
 - It defines an interface contract, so LLMs and external systems can interact 
with Flink Agents declaratively.
 - It is language-neutral, so it doubles as the compatibility contract between 
the Python and the Java loader.
 
-### Python and Java mapping
-
-When loading a YAML file, both runtimes parse it into typed in-memory 
representations and validate it against them using the framework's native 
validation:
-
-- The **Python loader** parses YAML into Pydantic `BaseModel`s declared in 
`flink_agents.api.yaml.specs`. Pydantic enforces the schema (required fields, 
value types, `extra="forbid"` on unknown keys, mutually-exclusive 
`text`/`messages` on prompts, ...).
-- The **Java loader** parses YAML into POJOs declared in 
`org.apache.flink.agents.api.yaml.spec`, validated by Jackson with equivalent 
rules.
-
-### Consistency guarantees
-
-Because Pydantic models are easier to author and evolve than raw JSON Schema, 
the **ground truth** is the Pydantic spec — the checked-in 
`docs/yaml-schema.json` is exported from it. After changing the specs, 
regenerate the schema with:
-
-```bash
-python -m flink_agents.api.yaml.specs > docs/yaml-schema.json
-```
-
-The coding-agent skill under `dev/agent-skills/` bundles a copy of the schema 
so it can work offline, so refresh that copy in the same change. `python3 
tools/check-skill-schema.py` reports whether it is current and prints the two 
edits needed when it is not.
-
-Continuous tests then verify cross-runtime consistency:
-
-- the JSON Schema exported by the Pydantic specs matches the checked-in 
`docs/yaml-schema.json`;
-- the Java POJOs match the checked-in `docs/yaml-schema.json` in property 
names, required fields, and `additionalProperties` strictness;
-- the Pydantic specs stay aligned with the Python `Agent` API;
-- the Java POJOs stay aligned with the Java `Agent` API.
-
-These checks keep the YAML structure aligned across loaders. Schema validation 
does
+Schema validation checks the document structure. It does
 not verify that referenced classes/functions are installed, that a component 
supports
 the selected implementation language, or that its provider is reachable. Before
 running the job, follow [Choose APIs and Languages]({{< ref 
"docs/development/create-agent/choose-apis-and-languages" >}})
diff --git a/docs/content/docs/development/multi-agent/subagents.md 
b/docs/content/docs/development/multi-agent/subagents.md
index 0871c679..aa089320 100644
--- a/docs/content/docs/development/multi-agent/subagents.md
+++ b/docs/content/docs/development/multi-agent/subagents.md
@@ -28,6 +28,11 @@ A sub-agent handles a task delegated by a parent agent. An 
internal sub-agent ru
 an agent workflow in the same job. An external sub-agent calls an agent service
 through a `SubagentSetup` implementation.
 
+To declare parent and child workflows in YAML, see
+[Declaring sub-agents]({{< ref 
"docs/development/create-agent/yaml#declaring-sub-agents" >}}).
+YAML supports references to internal child Agents in the same file and 
descriptors
+for external sub-agents.
+
 ## Declare an internal sub-agent
 
 Use `InternalSubagentResourceDescriptorBuilder` to attach a description and 
input

Reply via email to