wenjin272 opened a new issue, #1338:
URL: https://github.com/apache/flink-agents/issues/1338
### Search before asking
- [x] I searched the existing issues. #1140 covers subagent batch execution;
this issue tracks the broader Future and tool execution consolidation.
### Description
I would like to explore consolidating the execution path from framework
Futures to tool calls. This is an initial direction to validate with a PoC, not
a settled interface design.
#### Motivation
We currently expose overlapping execution mechanisms:
- Ordinary asynchronous and durable calls use `AsyncFuture` /
`DurableFuture` and `ctx.gather`.
- Chat and internal subagent calls both use subgraph execution, but maintain
separate `ChatDurableFuture` and `InternalSubagentFuture` implementations.
- Subagent handles have their own grouping path and separate deferred /
already-submitted execution models.
- `SubagentTool` currently provides model-facing metadata, while
`ToolCallAction` recognizes subagent calls and handles their submission,
waiting, result conversion, and cleanup separately from ordinary tools.
As a result, sharing a batch execution entry point is difficult, and adding
a tool execution model requires changes in the caller. The goal is to reduce
duplicated lifecycle logic and move execution-specific behavior behind common
interfaces.
#### Proposed direction
**1. Converge on `AsyncFuture` as the common waiting interface.**
All framework call handles should be usable as `AsyncFuture`; durability
remains an additional capability rather than an assumption about every Future.
- Consolidate the shared execution machinery of `ChatDurableFuture` and
`InternalSubagentFuture` into a reusable `SubgraphFuture`, with result
conversion and subagent-specific bookkeeping at the appropriate boundary.
- Let deferred subagent calls delegate to the existing durable Future
implementation, removing redundant execution/result state where possible.
Whether `DeferredSubagentFuture` can disappear entirely needs validation.
- Keep `AsyncSubagentFuture`'s already-submitted semantics: gathering it
should execute its durable result-waiting phase, not submit the remote call
again.
- Keep session/call identifiers, remote status queries, and remote
cancellation within subagent-specific APIs and implementations. Generic callers
should not need to understand these details.
The current cold-handle contract of `AsyncFuture` must be clarified for
handles representing already-submitted work. We should not obtain apparent
uniformity by silently changing when remote work starts.
**2. Make `ctx.gather` schedule mixed Futures through a common internal
protocol.**
Support ordinary async/durable calls, subgraph calls, and the waiting phase
of submitted subagent calls in the same batch.
The protocol needs to cover preparation/replay, nonblocking start,
completion, result recording, and cleanup. Exact method names and
inheritance/composition choices should come from the PoC. The shared scheduler
should use this protocol rather than enumerate concrete subagent or Chat Future
classes.
In particular:
- Reserve durable identities/slots in a deterministic order before starting
the corresponding new work.
- Allow child graphs to progress while the parent waits; do not occupy a
worker just to block on an internal subgraph.
- Preserve input/result association, replay behavior, execution ownership
checks, and failure/cancellation cleanup.
- Reuse this path for existing subagent grouping rather than maintain a
second batch scheduler.
This should reduce implementations and state machines, not merely rename
each Future implementation to a separate execution class.
**3. Build one tool execution entry point on top of that foundation.**
Add a preparation entry point to `Tool`, conceptually:
```java
// Illustrative only; signature and result adaptation need a PoC.
AsyncFuture<ToolResponse> prepare(RunnerContext ctx, ToolParameters
parameters);
```
- The default implementation prepares a framework-managed durable call
around an ordinary tool's `call`. Tool authors should not need to write durable
wrappers themselves.
- `SubagentTool` implements executable preparation itself: resolve/invoke
the subagent through its supported lifecycle and expose a compatible
Future/result. It should not remain a metadata-only placeholder requiring
special execution branches in `ToolCallAction`.
- `ToolCallAction` resolves executable tools, prepares their calls, gathers
the resulting Futures, and processes tool responses through one path.
```text
ToolCallAction
-> Tool.prepare(...)
ordinary Tool -> framework-managed durable call
SubagentTool -> subagent call / result-waiting handle
-> ctx.gather(AsyncFuture...)
-> tool responses
```
Resource lookup and subagent adaptation should be encapsulated behind this
entry point. `ToolCallAction` should not need to distinguish ordinary tools
from subagents to schedule and execute them. A tool-specific `callBatch` API
should not be necessary.
#### PoC and acceptance criteria
Start with Future/gather consolidation, then build the tool entry point on
it.
- Demonstrate one mixed gather containing an ordinary durable call, a
Chat/internal-subagent subgraph call, and an already-submitted async subagent's
result wait.
- Verify actual concurrent progress, ordered results, repeated awaits, and
recovery of partially completed batches without re-executing recorded calls or
adding another submission during result waiting.
- Verify failure/cancellation propagation and pending-handle cleanup,
including failures during preparation.
- Demonstrate ordinary tools and subagents in the same `ToolCallAction`
batch without subagent-specific scheduling branches.
- Preserve model-visible tool schemas and response/reporting behavior, and
document any intentional public API migration.
- Keep Java and Python behavior aligned and preserve the `runtime -> plan ->
api` dependency direction.
#### Related work and scope
- #1140 and #1199 cover subagent batch execution. The shared gather work
overlaps and could be developed together; the broader tool entry point builds
on it. #1199's batch preparation, completion recording, and nonblocking child
execution are useful references.
- Dedicated subagent concurrency limits can be considered separately from
the common execution protocol.
- #1322 tracks failure cleanup/propagation concerns. This refactoring must
preserve the required behavior, but does not define a new exception taxonomy or
change which failures durable execution persists.
### Are you willing to submit a PR?
- [ ] I'm willing to submit a PR!
--
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]