ag-ui-protocol / ag-ui-protocol/ag-ui

feat(ag-ui-adk): surface HITL pauses as AG-UI interrupts on RUN_FINISHED.outcome

Đang mở
#2,101 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
enhancement Integration
Ngôn ngữ chính
Python
Star
15.9k
Fork
1.4k
Merge trung bình
1 ngày 17 giờ
Pull request đã merge (30 ngày)
163

Mô tả

## Summary

AG-UI defines an **interrupt protocol**: a run can finish with `RunFinishedEvent.outcome = RunFinishedInterruptOutcome(interrupts=[Interrupt(...)])`, the client surfaces them as `pendingInterrupts`, and resumes by addressing each in the `resume: ResumeEntry[]` array of the next `RunAgentInput`.

`ag-ui-adk` implements Human-in-the-Loop through its own mechanism (a frontend / long-running tool call pauses the run: `TOOL_CALL_START/ARGS/END` with no `TOOL_CALL_RESULT`, then `RUN_FINISHED`; the client resumes by sending a tool-result message). That works for CopilotKit, but the pause is **not represented as a spec `Interrupt`** — `RUN_FINISHED` is emitted with no `outcome`, so spec-compliant AG-UI clients never see `pendingInterrupts` and can't use the standard interrupt/resume UI.

## Proposal (emit side)

Add an **opt-in** `emit_interrupts: bool = False` to `ADKAgent`. When enabled, a run that pauses on unresolved HITL/long-running tool calls finishes with a `RunFinishedInterruptOutcome` carrying one `Interrupt` per pending tool call (`id` and `tool_call_id` = the tool call id, `reason="tool_call"`). Off by default → existing CopilotKit-style resume flows are unaffected; `outcome` stays absent unless enabled.

Detection is transport-level and self-contained: in the run's event consumer, track `TOOL_CALL_END` ids and drop those that get a `TOOL_CALL_RESULT`; whatever remains at `RUN_FINISHED` is what the run paused on.

```python
agui_agent = ADKAgent(adk_agent=root_agent, emit_interrupts=True)
# a HITL pause now finishes as:
# RUN_FINISHED { outcome: { type: "interrupt", interrupts: [{ id, reason:"tool_call", toolCallId }] } }
```

## Scope

- **This issue/PR covers the emit side** — surfacing ADK HITL pauses as spec interrupts so clients get `pendingInterrupts`.
- **Follow-up (not in this PR):** consuming the standard `resume: ResumeEntry[]` array on the way back. Today ag-ui-adk resumes via a tool-result message; mapping `ResumeEntry` (resolved/cancelled + payload) onto that resume path is a larger, separate change. Tracking it here so the two halves are explicit.

## Non-goals

- No change to the existing HITL/tool-result resume mechanism.
- Additive and orthogonal to SSE/WebSocket/httpBinary and the default translation.

Happy to send the emit-side PR (flag on `ADKAgent` + outcome on `RUN_FINISHED`, with tests).

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.