sangkyoonnam opened a new pull request, #1373:
URL: https://github.com/apache/flink-agents/pull/1373

   Linked issue: #606
   
   ### Purpose of change
   
   Agent plans can be built and serialized without a reachable MCP server. 
Discovery runs when the operator starts, so the deployed task uses the server's 
current tools and prompts. This continues the Java implementation from #639 by 
@yanand0909 and adds the Python path.
   
   #### Runtime flow
   
   Plan construction records server descriptors. Java operator initialization 
and Python runner-context initialization discover resources into their resource 
caches; tool calls resolve them there. Internal sub-agent caches initialize 
both language paths before the first action, including children that declare 
MCP servers without AGENT resources. Python MCP tools/prompts are also 
registered as Java-side wrappers for Java actions. Caches retain servers even 
when discovery returns no tools or prompts, and close them during shutdown.
   
   #### Key decisions
   
   Discovery remains synchronous and fails startup on errors. Server-specific 
timeout and Java retry settings bound requests. Dynamic refresh and graceful 
startup without a declared server are outside this change.
   
   ### Behavioral Semantics
   
   #### Interactions
   
   | Declaration / result | Behavior |
   | --- | --- |
   | Java or Python MCP declaration; plan construction | Preserve the server 
descriptor without connecting |
   | Python YAML alias at shared or agent scope | Preserve the declaration and 
discover through the same runtime path |
   | Successful discovery | Cache tools and prompts; attach server identity to 
tools |
   | No tools and no prompts | Retain and close the server itself |
   | Duplicate tool/prompt, including an existing Java resource seen through 
the Python bridge | Reject startup without overwriting the existing resource |
   | Tool name starts with `_subagent_` | Reject the reserved name |
   | Server does not answer | Fail discovery after its configured request 
timeout/retries |
   
   #### Contracts and failures
   
   Compilation makes no discovery calls. Discovered resources become available 
from the corresponding cache. Duplicate names are checked within each resource 
namespace, so a tool and prompt may share a name. A failed Python runner or 
child-cache discovery closes resources created by that attempt and preserves 
the discovery error; a Java child-cache failure also closes its partial cache. 
Normal operator shutdown closes servers that advertised nothing.
   
   No discovery error silently degrades into a partial tool set. 
Endpoint/authentication errors remain errors; there is no new fallback. Server 
resources are rediscovered on restart, rather than frozen in the serialized 
plan.
   
   ### Tests
   
   | Contract | Test |
   | --- | --- |
   | No compile-time network | `AgentPlanMCPDeferredDiscoveryTest`; 
`test_mcp_server_is_registered_without_contacting_it` |
   | Runtime tools/prompts and server identity | 
`JavaMCPResourceDiscoveryTest`; 
`test_startup_discovers_and_registers_tools_and_prompts` |
   | Empty-server client lifetime | 
`JavaMCPStartupIntegrationTest.emptyDiscoveryClosesTheRealClientSession`; 
`test_server_is_closed_with_the_cache_even_when_nothing_is_discovered` |
   | Operator startup/close wiring | 
`ActionExecutionOperatorTest.testOpenDiscoversJavaMCPServerAndCloseReleasesIt` |
   | Actual HTTP request timeout | Java 
`startupTimesOutWhenTheServerAcceptsButNeverAnswersInitialize`; Python 
`test_real_startup_timeout_without_a_json_rpc_response` |
   | Shared/local YAML declarations | 
`test_yaml_shared_and_local_servers_are_discovered_only_at_startup` |
   | Duplicate and reserved names | `JavaMCPResourceDiscoveryTest`, 
`PythonMCPResourceDiscoveryTest`, `test_mcp_resource_discovery.py` |
   | Java child-cache discovery and close | 
`childScopeDiscoversOnceAndReleasesItsEmptyServer` |
   | Python MCP-only child startup and Java access | 
`mcpOnlyChildInitializesPythonAndExposesToolsToJavaBeforeActions`; 
`test_child_mcp_is_discovered_before_the_first_action` |
   | Python construction failure cleanup | 
`test_runner_context_creation_fails_when_the_server_is_unreachable`; 
`test_failed_child_scope_discovery_closes_the_new_cache` |
   
   On current main, `test_mcp_resource_discovery.py`, `test_agent_plan.py`, 
`integrations/mcp/tests/test_mcp.py` and `api/yaml/tests/test_loader.py` pass 
in three runs, as does the full Python unit suite. The Java tests in the table 
plus `ActionExecutionOperatorTest`, `ResourceCacheTest` and the internal 
sub-agent tests pass on JDK17 and JDK21, and `tools/lint.sh -c` passes on 
JDK11. Loopback HTTP tests require no external MCP service.
   
   Not verified: full cluster end-to-end deployment, TLS/OAuth server 
integration, or real Pemja transport for the mixed-language child test (the 
bridge contract is mocked, and Python scope behavior is tested directly). 
Python actions calling Java-owned MCP tools were not supported by the existing 
resource-provider bridge and are not added here.
   
   <details>
   <summary>Regression evidence</summary>
   
   Before the rebase onto current main, the controls ran against upstream main 
64e9e0f9: the Python compile-time discovery test fails behaviorally there in 
three runs, then passes with this change. Removing only the server-cache 
insertion reproduces an unclosed real empty MCP session in three runs. Omitting 
the child Python initialization hook also fails the MCP-only child regression. 
These controls test network invocation, client shutdown, and startup wiring. 
Java API/plan/runtime modules were rebuilt from source for JDK17 and JDK21 
tests.
   
   </details>
   
   ### API
   
   MCP declaration syntax is unchanged. Python already rejected duplicate and 
reserved names at plan compilation; those checks now run at startup. Java 
already rejected reserved `_subagent_` names, but registered duplicate tool or 
prompt names last-wins; a duplicate now fails startup instead of silently 
replacing a resource. Plan JSON no longer embeds remotely discovered 
tool/prompt providers. Python's configured `timeout` also bounds client-session 
requests, including discovery. Existing server authentication and Java retry 
settings remain in effect.
   
   ### 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: Claude Code 2.1.319 (Claude Opus 5.5)
   Generated-by: Codex CLI 0.166.0 (gpt-6-astra)
   
   The first commit is @yanand0909's change from #639 with its original author 
and date; only the conflict resolution and the `provide(ResourceContext)` test 
adaptation were changed, as its message and its own `Generated-by` line say. 
The fix for the #639 review comments and everything else are in the second 
commit.
   


-- 
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