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]

Reply via email to