GitHub user pltbkd added a comment to the discussion: [Feature] Sub-agent 
Resource for Flink Agents - Framework part

Hi, thanks for sharing the thoughtful ideas!

### SubagentCompatible Marker vs. Runtime Enforcement:

The marker is introduced mainly for safety, to prevent unexpected behaviors 
from Agents that do not satisfy the required constraints. Therefore, under the 
current design, such Agents cannot be directly used, which may reduce usability.

For InternalSubagent, we can detect invalid usage and fail at runtime, which 
may satisfy part of the requirement. However, @xintongsong pointed out that 
compile-time detection, especially when issues can be directly surfaced from 
YAML configuration, is also valuable for usability and agent friendliness. WDYT?

### External Idempotency Framework:

The current sessionId/callId design follows the durable call idea. The 
framework derives a scope from the invocation chain and generates a 
deterministic ID by adding the call ordinal within that scope. The ID is part 
of the durable call identifier, so after failover we can short-circuited 
repeated calls and reuse previous results.

For external sessions, if specifying session IDs is supported, the repeated 
calls are skipped and they can use the ID to continue previous conversations 
(with possible reconciliation for the latest message). Otherwise, the 
conversation history should be included in the result and passed back by 
callers in subsequent requests, so the request itself is deterministic.

### Nested Backpressure & Deadlocks:

Since subagent execution relies on durableExecuteAsync yielding and waiting, 
some async threads may be occupied during the wait. If the subagent also 
requires async execution internally, thread pool exhaustion could cause 
deadlocks.

Because Actions cannot execute in parallel, the caller has to yield while 
waiting for InternalSubagent, so returning an unfinished Future and continuing 
execution is not possible under the current model.

For solutions, since durableExecuteAsync mainly performs waiting, we leverage 
it only to reuse the durable execute and yielding mechanism, excluding it from 
the worker thread count or using a dedicated thread pool may be simple options. 
A solution that avoids additional threads while preserving these capabilities 
would be preferable and worth exploring.

Could you clarify what execution model you mean by "non-blocking yield 
mechanics"?

### Timeout & Cancellation Semantics:

These requirements can be divided into timeout configuration, cancellation 
initiation/propagation, and cancellation handling.

Timeout is relatively straightforward: callers can provide timeout parameters, 
and subagents can set timers or propagate them to clients such as gRPC.

Cancellation is more complicated:
- From the caller side, the current API returns a Result containing only the 
final result. Due to Action serialization constraints, callers cannot naturally 
continue execution and actively trigger cancellation. However, cancellation 
caused by timeout or failures in parallel execution can be supported.
- External subagents can expose a non-blocking Future and allow callers to 
invoke cancel(). However, InternalSubagent cannot provide the same semantics 
because the caller cannot cancel an ongoing Action. Do you prefer the Future 
style interface to the current one?

For cancellation propagation, we may need a `cancel` method or Cancellable 
trait for DurableCallable, allowing the caller or framework to propagate 
cancellation signals. How to interrupt an executing DurableCallable still 
requires further design.

Ultimately, subagents need to handle cancellation themselves. External 
subagents need to send cancellation messages through their own mechanisms. For 
InternalSubagent, since Actions generally cannot be interrupted, 
cancellation/timeout checks can be performed between Actions via 
SubagentRunnerContext. Interrupting an ongoing Action (e.g., interrupting 
durable execution) is a separate issue.

### Framework Primitives vs. Application Templates:

This proposal mainly focuses on framework primitives and does not include a 
SupervisorAgent design.

It would be helpful to discuss how a SupervisorAgent works, and how it could 
leverage subagents, which may also help identify further subagent requirements. 
Currently, subagents seem more valuable for InternalSubagent, while the 
distinction from tools/MCP is less obvious for ExternalSubagent. The unique 
value and requirements of subagents still need further exploration.

GitHub link: 
https://github.com/apache/flink-agents/discussions/909#discussioncomment-17808902

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]

Reply via email to