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

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

Abierto
#2,101 1 comentario 0 reacciones 0 asignados Ver en GitHub
enhancement Integration
Lenguaje dominante
Python
Estrellas
15.9k
Forks
1.4k
Merge medio
1 d 17 h
PR fusionados (30 d)
163

Descripción

## 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).

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.