wenjin272 opened a new pull request, #1269: URL: https://github.com/apache/flink-agents/pull/1269
Closes #1231 ### Purpose of change YAML can now register internal sub-agents by referencing another Agent in the same file or one already loaded into the same execution environment. The Prompt loader also preserves message templates when `text` is empty, matching the existing validation rule. The YAML reference now separates configuration from implementation code, clarifies required fields and aliases, links to Tool Use and Skills for behavior, and documents sub-agents. The changes are split into three commits: Prompt fix, sub-agent support, and documentation. The implementation description covers the two code changes. #### Runtime flow Each loader creates all Agents in a file, then binds agent-local `subagents` entries against those Agents and the environment's previously registered Agents. Internal references use the existing descriptor builder; plan compilation serializes the child and checks cycles. Runtime invocation follows the existing sub-agent path. Files are loaded in order. Prompt construction selects non-empty `text`; otherwise it constructs the validated message list. #### Key decisions - Resolve references at load time, supporting forward references within a file and requiring child files to load first across files. - Keep internal references local to a parent. A shared internal descriptor could register itself on its own child when that child is applied independently. - Use `clazz` to select the existing external descriptor form, preserving arbitrary provider configuration, including an `agent` argument. ### Behavioral Semantics #### Interaction decisions | Declaration/location | Result | | --- | --- | | Parent-local entry without `clazz`, with `agent` | Internal reference; `name` is the parent's resource name | | Parent-local or shared entry with `clazz` | Existing external setup descriptor | | Shared entry with only an internal `agent` reference | Rejected during parsing | | Child in current file, in either order | Resolved after all in-file Agents exist | | Child already registered in this environment | Resolved to that Agent | | Child only in a later file or another environment | Loading fails; no deferred lookup | | Non-empty `messages` with omitted/null/empty `text` | Message prompt is constructed | #### Behavioral contracts - A child can be referenced before its declaration within a file, or from a later-loaded parent file. - Separate loading calls and a list of files follow the same ordered resolution rule. - Agent names remain unique; a new declaration cannot replace a registered child. - Nested children and multiple references to one child retain metadata and compile into child plans. - Internal `description` may be omitted/null; `input_schema`, when supplied, is a YAML mapping. Model delegation retains the existing input-schema requirement. - Existing external setup arguments continue to pass through unchanged. - Omitted/null/empty Prompt text preserves message roles, order, and formatting when messages are non-empty. #### Failure behavior Invalid internal declarations, unsupported shared internal references, duplicate names, and unknown children raise during loading. Unknown-child and duplicate-Agent failures leave the failing file's Agents/resources unregistered and preserve earlier registrations. Self-reference and indirect cycles raise during plan construction. No retry or deferred resolution is added; provider/service failures are unchanged. ### Tests Verification: **152 Java tests and 171 Python tests passed**. Hugo built successfully; 761 internal links/anchors and the bundled schema/hash were checked. | Contract | Tests | | --- | --- | | In-file forward references | `YamlSubagentTest.resolvesChildInEitherOrder`; Python `test_internal_reference_preserves_child_and_metadata` | | Earlier-file resolution, separate calls/list order, environment isolation | `YamlLoaderLoadYamlTest.resolvesPreviouslyLoadedChild`; Python `test_child_in_previously_loaded_file_is_resolved` | | Unknown child fails without registering the failing file | `childMustBeLoadedFirstAndFailurePreservesState`; Python matching failure/state tests | | Registered child cannot be replaced | `currentFileCannotReplaceRegisteredChild`; Python `test_current_file_cannot_replace_registered_child` | | Nested/reused children preserve metadata and serialize | `YamlSubagentPlanTest`; Python `test_yaml_subagents.py` | | Invalid fields/shared internal declarations fail; null metadata defaults | `YamlSubagentTest`; Python `test_subagents.py` | | External setup arguments remain unchanged | `externalDeclarationsPreserveProviderArguments`; Python `test_external_subagents_preserve_provider_arguments` | | Cycles fail compilation | `recursiveReferencesFailPlanConstruction`; Python `test_yaml_cycles_use_existing_plan_validation` | | YAML parent invokes child after serialization, within/across files | `InternalSubagentCallTest.yamlParentInvokesChildAfterPlanSerialization` (JDK 21) | | Empty/unset Prompt text preserves messages | `YamlLoaderBuildersTest.buildPromptMessagesWithUnsetText`; Python `test_build_agents_preserves_prompt_messages_with_unset_text` | Coverage concentrates on reference binding, failure state, plan serialization, and actual Java operator invocation. Not verified: full cluster/cross-language E2E or live model/external-provider calls; the full repository test suite was not run. ### API Adds the agent-local internal YAML form (`name`, `agent`, optional `description` and mapping `input_schema`) in both languages and the published schema. External declarations and runtime APIs are unchanged. Existing valid Prompt YAML with empty `text` plus messages now produces the intended message prompt. Files with duplicate Agent names remain invalid. ### Documentation - [ ] `doc-needed` - [ ] `doc-not-needed` - [x] `doc-included` ### Was this patch authored or co-authored using generative AI tooling? - [x] Yes - [ ] No Generated-by: Codex CLI 0.153.4 (GPT-6) -- 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]
