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]
