yunfengzhou-hub commented on code in PR #1268:
URL: https://github.com/apache/flink-agents/pull/1268#discussion_r4300859145


##########
docs/content/docs/development/multi-agent/subagents.md:
##########
@@ -67,156 +207,147 @@ parent.add_resource(
         .build(),
 )
 ```
+{{< /tab >}}
 
-`ReviewAgent` is your child workflow; the Java `ReviewRequest` is a data class
-with fields describing its input. Alternatively, pass a JSON schema string to
-`inputSchema(...)` in Java or `input_schema(...)` in Python. Choose either an
-input type or an explicit schema. The schema describes the submitted arguments,
-which the child receives as its input event payload; it does not convert that
-payload into an instance of the input type.
-
-When a chat model is configured with `subagents=["reviewer"]`, the description
-helps it choose when to delegate, and the schema tells it which arguments to
-send. A schema is required for model-selected calls. A missing description uses
-a generic delegation description.
-
-For calls made explicitly by an action, the existing shorthand remains 
available:
-
+{{< tab "Java" >}}
 ```java
-parent.addResource("reviewer", ResourceType.AGENT, new ReviewAgent());
-```
+import org.apache.flink.agents.api.resource.ResourceType;
+import 
org.apache.flink.agents.api.subagent.InternalSubagentResourceDescriptorBuilder;
 
-```python
-parent.add_resource("reviewer", ResourceType.AGENT, ReviewAgent())
+parent.addResource(
+    "reviewer",
+    ResourceType.AGENT,
+    new InternalSubagentResourceDescriptorBuilder()
+        .agent(new ReviewAgent())
+        .description("Review code for correctness and potential defects")
+        .inputType(ReviewRequest.class)
+        .build());
 ```
+{{< /tab >}}
 
-This shorthand does not declare an input schema. Use the builder when exposing
-the child to a model. Recursive registration, such as a child registering its
-parent, is rejected when the plan is built.
+{{< /tabs >}}
 
-Register the resources a child uses, such as its chat model connection, on the
-child itself. In Python, a child resolves resources against its own plan only,
-so a resource registered solely on the parent is not visible to the child.
+`ReviewRequest` describes the arguments the child accepts, and the Java form 
is a bean.
+Where no type fits, a JSON schema string declares the same arguments:
 
-## Declare an external sub-agent
+{{< tabs "Declare the Input as a Schema" >}}
 
-Implement `SubagentSetup` (or the appropriate runtime base class) and register 
a
-resource descriptor naming that implementation. Do not register a setup 
instance.
+{{< tab "Python" >}}
+```python
+parent.add_resource(
+    "reviewer",
+    ResourceType.AGENT,
+    InternalSubagentResourceDescriptorBuilder()
+        .agent(ReviewAgent())
+        .description("Review code for correctness and potential defects")
+        .input_schema(
+            '{"type":"object","properties":{"code":{"type":"string"}},'
+            '"required":["code"]}'
+        )
+        .build(),
+)
+```
+{{< /tab >}}
 
+{{< tab "Java" >}}
 ```java
 parent.addResource(
-    "remote_reviewer",
+    "reviewer",
     ResourceType.AGENT,
-    ResourceDescriptor.Builder.newBuilder(RemoteReviewSetup.class.getName())
-        .addInitialArgument("endpoint", "https://example.com/review";)
-        .addInitialArgument("description", "Review code using the remote 
service")
-        .addInitialArgument("input_schema", inputSchema)
+    new InternalSubagentResourceDescriptorBuilder()
+        .agent(new ReviewAgent())
+        .description("Review code for correctness and potential defects")
+        .inputSchema(
+                
"{\"type\":\"object\",\"properties\":{\"code\":{\"type\":\"string\"}},"
+                        + "\"required\":[\"code\"]}")
         .build());
 ```
+{{< /tab >}}
 
-The Java setup exposes a public `(ResourceDescriptor, ResourceContext)`
-constructor and implements the sub-agent invocation contract. `endpoint` above
-is configuration read by the example implementation, not a built-in transport.
+{{< /tabs >}}
 
-```python
-parent.add_resource(
-    "remote_reviewer",
-    ResourceType.AGENT,
-    ResourceDescriptor(
-        clazz="my_app.agents.RemoteReviewSetup",
-        endpoint="https://example.com/review";,
-        description="Review code using the remote service",
-        input_schema=input_schema,
-    ),
-)
-```
+Declare either an input type or an input schema, not both. A declaration that 
carries
+both is rejected when the descriptor is built. In Python the type must be a 
pydantic
+model, and a type that is not is rejected there too.
 
-The Python setup declares these configuration fields and implements the
-invocation contract. Both languages construct the setup at runtime from the
-descriptor. Existing code that passes a setup instance to `addResource` or
-`add_resource` must instead pass a descriptor with the same configuration.
+An input type is a shorthand for a schema. The framework derives the schema 
from the
+type and registers that, so use a type when you already have one and a schema 
when
+you do not. Nothing is ever converted into an instance of the type. The 
sub-agent
+receives the arguments as a map keyed by the schema's field names.
 
-## Delegate from a chat model
+For calls an action makes itself, the child registers as-is:
 
-List the child's registered name under `subagents` of the parent's chat model:
+{{< tabs "Register the Child Agent Directly" >}}
 
-```java
-ResourceDescriptor.Builder.newBuilder(ResourceName.ChatModel.OLLAMA_SETUP)
-    .addInitialArgument("connection", "ollamaConnection")
-    .addInitialArgument("model", "qwen3:8b")
-    .addInitialArgument("subagents", List.of("reviewer"))
-    .build();
+{{< tab "Python" >}}
+```python
+parent.add_resource("reviewer", ResourceType.AGENT, ReviewAgent())
 ```
+{{< /tab >}}
 
-```python
-ResourceDescriptor(
-    clazz=ResourceName.ChatModel.OLLAMA_SETUP,
-    connection="ollama_connection",
-    model="qwen3:8b",
-    subagents=["reviewer"],
-)
+{{< tab "Java" >}}
+```java
+parent.addResource("reviewer", ResourceType.AGENT, new ReviewAgent());
 ```
+{{< /tab >}}
 
-The model sees the child as a tool named `_subagent_reviewer`, described by the
-registration's description and input schema. The arguments the model sends
-become the child's input, and the child's outputs return to the model as the
-tool observation, so it can continue reasoning over them. For an internal
-sub-agent, the observation is the JSON encoding of the full output list
-described in [Call from an action](#call-from-an-action), even when the child
-emits a single output, so its shape does not depend on how many outputs the
-child emits.
+{{< /tabs >}}
 
-## Call from an action
+This form carries no description and no input declaration, so a chat model 
rejects
+the sub-agent at setup time rather than calling it with no arguments. Only the
+descriptor form exposes a child to a model.
 
-An action can submit input to a child directly and await its outcome. This path
-does not need an input schema.
+There is no third form. An internal sub-agent cannot be declared in YAML, 
because

Review Comment:
   Fixed in the rebase. The restriction is gone, the Declare section links to 
Declaring sub-agents, and the internal section states the agent field. Loaded 
all three YAML forms against the new loaders to confirm.



##########
docs/content/docs/development/multi-agent/subagents.md:
##########
@@ -24,30 +24,170 @@ specific language governing permissions and limitations
 under the License.
 -->
 
-A sub-agent handles a task delegated by a parent agent. An internal sub-agent 
runs
-an agent workflow in the same job. An external sub-agent calls an agent service
-through a `SubagentSetup` implementation.
+## Overview
 
-## Declare an internal sub-agent
+A sub-agent is an agent that another agent delegates a task to. The parent 
hands it
+input, the sub-agent does the work, and the parent receives the outcome as a
+`SubagentResult`. Use one when the delegated work is multi-step or 
long-running and
+should run isolated from the parent.
 
-Use `InternalSubagentResourceDescriptorBuilder` to attach a description and 
input
-schema to a child agent. The builder returns a normal resource descriptor for 
`addResource`
-or `add_resource`.
+The work runs either inside the job or outside it. An *internal* sub-agent is a
+child `Agent`, including a `ReActAgent`, compiled into the parent's plan. The
+child's own actions and events run in the same job. An *external* sub-agent 
has no
+plan of its own. The work happens in your own code or in a remote agent 
service,
+outside the parent's event loop. It takes one of two forms, *deferred* or 
*async
+(pub/sub)*.
 
+Either way, the call is initiated by the model or by you. In *model-driven
+delegation* you list the sub-agent on a chat model setup and the model chooses 
when
+to delegate. In *caller-driven delegation* one of your actions submits the task
+itself.
+
+Every sub-agent call runs through
+[durable execution]({{< ref 
"docs/development/create-agent/actions#durable-execution" >}}).
+There is no durability toggle and no sub-agent timeout option.
+
+## Declare a sub-agent
+
+A sub-agent enters the parent's plan as a resource registered under
+`ResourceType.AGENT`. The name you register it under is the name that 
invocations and
+metrics use. What you register depends on the form. An internal sub-agent 
registers
+a child `Agent`. An external sub-agent registers a descriptor that names your 
setup
+class, and a YAML file can declare it.
+
+### Internal: compile a child agent
+
+Nothing in a child's own code marks it as a sub-agent. The child is an ordinary
+agent with its own resources, actions, and event loop, and it runs standalone
+exactly as written. A parent registers it as an `AGENT` resource, and that
+registration is the whole of the difference. It gives the child a name in the
+parent's plan. It can also give the child an input schema, so a chat model can 
call
+it. And it supplies the caller that submits input and awaits the child's 
outputs.
+
+Any `Agent` can serve as the child. The two common kinds are a workflow agent 
and a
+`ReActAgent`. Either way, the child's plan is compiled into the parent's when 
the
+parent's plan is built.
+
+#### A workflow agent as the child
+
+The example child owns a chat model and answers each review request with its

Review Comment:
   All three done. The child example links to chat#usage-example and keeps only 
the input adaptation. The toggle and timeout detail now survives only in 
Durability and failover. The table uses your three rows.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to