wenjin272 opened a new issue, #1130: URL: https://github.com/apache/flink-agents/issues/1130
### Search before asking - [x] I searched in the [issues](https://github.com/apache/flink-agents/issues) and found nothing similar. ### Description This is a child issue of #1055. We plan to keep Event–Action orchestration as the lowest-level and most flexible API, and build managed call-style APIs on top of it. For example, a future `ctx.chat(...)` call would send a `ChatRequestEvent`, suspend the caller, and resume it when the corresponding terminal `ChatResponseEvent` arrives. This requires a total request-response contract: every handled logical `ChatRequestEvent` must eventually produce exactly one logical terminal `ChatResponseEvent`, regardless of whether the chat succeeds or fails. The current Chat action does not provide this contract: - With `IGNORE`, a provider or routing failure is logged and the request is dropped without a response event. - With `FAIL`, or after retries are exhausted, the exception is propagated without a response event. - `ChatResponseEvent` can only represent success because it requires a `ChatMessage` and has no failure status or error information. An Event-backed call waiting for that response can therefore remain unresolved or must rely on failure handling outside the request-response protocol. `ToolCallAction` already demonstrates a more composable model: ordinary tool execution failures are represented in `ToolResponseEvent`, allowing the consumer to decide how to handle them. #### Proposed direction - Extend `ChatResponseEvent` in both Java and Python so that it can represent a terminal success or failure. A possible shape is: ```text ChatResponseEvent - request_id - status: SUCCESS | FAILED - response: ChatMessage? # present on success - error: ChatError? # present on failure and serializable across Java/Python - retry_count - total_retry_wait_sec ``` - Replace `FAIL` and `IGNORE` as terminal Chat action behaviors. For an ordinary chat-level failure, emit one failed `ChatResponseEvent` and let the receiving Action decide whether to ignore it, branch on it, or throw. - Keep retry as an execution policy rather than an alternative terminal outcome. Retry attempts must not emit intermediate response events; after the retry or routed-model fallback budget is exhausted, emit one failed terminal response. - Preserve the original request ID across routed-model fallback and multi-round tool use so that a terminal failure can still complete the original logical request. - Do not convert cancellation/interruption, JVM `Error`, state corruption, or other framework/system failures into ordinary chat responses. Those failures must retain explicit propagation and Flink recovery semantics. - Review the shared `ErrorHandlingStrategy` API separately from the Chat action behavior because the same configuration is also used by model routing. Routing fallback/retry policy should not be conflated with how a terminal chat result is represented. "Exactly one" here means one logical terminal outcome for a request. Flink may physically replay event delivery during recovery, so consumers and a future managed-call waiter must correlate by request ID and complete idempotently rather than assuming exactly-once physical delivery. #### Compatibility This changes the public event contract. Existing handlers commonly assume that `ChatResponseEvent.response` is always present, while users of `IGNORE` currently observe no response at all. Java, Python, YAML, cross-language serialization snapshots, built-in agents, examples, and migration documentation therefore need to be updated together. #### Acceptance criteria - Every handled logical `ChatRequestEvent` produces exactly one logical terminal `ChatResponseEvent` after all retries, routing fallbacks, and tool rounds finish. - `ChatResponseEvent` has aligned Java and Python fields for terminal status and serializable failure information; the success and failure payload invariants are documented and validated. - Provider failures, routing failures, timeouts, invalid or truncated responses, structured-output failures, and retry exhaustion have defined terminal behavior. - Retry attempts and routed-model fallbacks do not emit intermediate terminal response events. - Cancellation/interruption and framework/system failures retain explicit propagation semantics. - Recovery tests verify that replay does not create a second logical outcome and that a waiter can complete idempotently by request ID. - Existing Event API users have a documented migration path. Related: #1105 ### Are you willing to submit a PR? - [x] 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]
