Python: [BREAKING]: Canonicalize AG-UI interrupt and resume handling#6925
Python: [BREAKING]: Canonicalize AG-UI interrupt and resume handling#6925moonbox3 wants to merge 11 commits into
Conversation
Key decisions: raise ag-ui-protocol to 0.1.19, type AGUIRequest/AGUIChatOptions with protocol Interrupt and ResumeEntry, and emit interrupted runs through RUN_FINISHED.outcome.interrupts instead of the legacy top-level interrupt field. Preserve existing internal resume/snapshot compatibility by translating legacy interruption metadata into canonical Interrupt metadata. Files changed: packages/ag-ui pyproject, AG-UI run/type/workflow/snapshot helpers, AG-UI protocol-shape tests, and uv.lock. Verification: uv run poe test -P ag-ui; uv run poe syntax -P ag-ui -C; uv run poe typing -P ag-ui; uv run poe validate-dependency-bounds-test -P ag-ui; uv run poe check -P ag-ui; git diff --cached --check. Notes: README and local PRD/Ralph planning files were left unstaged. Follow-up slices still own richer approval/workflow response schemas and full client-side resume forwarding.
Key decisions: build Agent Framework approval pauses as canonical AG-UI Interrupt entries under RUN_FINISHED.outcome.interrupts; use reason=tool_call with toolCallId routing; advertise generic approval response schemas using the existing accepted/edited-argument payload contract; keep legacy Agent Framework approval metadata nested under metadata.agent_framework.value for internal snapshot/resume compatibility while avoiding any top-level interrupt value in emitted protocol JSON. Files changed: packages/ag-ui/agent_framework_ag_ui/_run_common.py adds canonical approval interrupt/schema helpers and uses them for function approval requests; packages/ag-ui/agent_framework_ag_ui/_agent_run.py emits canonical interrupts for predictive confirm_changes pauses; packages/ag-ui/tests/ag_ui/test_endpoint.py covers endpoint/SSE approval pause shape; packages/ag-ui/tests/ag_ui/test_run.py covers helper and run-level confirmation interrupt behavior. Verification: uv run pytest packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_pause_emits_canonical_interrupt_outcome packages/ag-ui/tests/ag_ui/test_run.py::test_emit_approval_request_populates_interrupt_metadata packages/ag-ui/tests/ag_ui/test_run.py::test_predictive_confirmation_run_finished_interrupt_links_tool_call -q; uv run pytest packages/ag-ui/tests/ag_ui/test_run.py::test_run_agent_stream_accumulates_multiple_confirm_interrupts packages/ag-ui/tests/ag_ui/test_endpoint.py::test_agent_endpoint_hydrates_interrupted_thread_without_invoking_agent packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_pause_emits_canonical_interrupt_outcome packages/ag-ui/tests/ag_ui/test_run.py::test_predictive_confirmation_run_finished_interrupt_links_tool_call -q; uv run poe test -P ag-ui; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe typing -P ag-ui; uv run poe check -P ag-ui; git diff --check; git diff --cached --check. Notes: local README, PRD, .ralph, and issue planning artifacts remain unstaged. Follow-up slices still own canonical ResumeEntry approval continuation, workflow request_info canonical resume, client-side forwarding, pending interrupt contract enforcement, snapshot stale-prompt clearing, and documentation/examples.
Key decisions: translate canonical ResumeEntry approval payloads into the existing Agent Framework function approval response path at the AG-UI agent-run boundary; route by canonical interruptId while preserving pending approval registry validation; allow edited arguments only through canonical resume translation by updating the stored pending argument fingerprint before execution; emit RUN_ERROR for cancelled, unknown, or malformed approval resumes instead of proceeding. Files changed: packages/ag-ui/agent_framework_ag_ui/_agent_run.py adds canonical approval resume translation, interrupt-id registry aliasing, explicit approval resume RUN_ERROR handling, and alias cleanup on consumption; packages/ag-ui/tests/ag_ui/test_endpoint.py adds endpoint/SSE coverage for approved, denied, edited, cancelled, and unknown canonical approval resumes. Verification: uv run pytest packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_resume_entry_executes_approved_tool packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_resume_entry_denial_does_not_execute_tool packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_resume_entry_applies_edited_arguments packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_cancelled_resume_entry_emits_run_error packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_unknown_resume_entry_emits_run_error -q; uv run pytest packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_pause_emits_canonical_interrupt_outcome packages/ag-ui/tests/ag_ui/test_endpoint.py::test_agent_endpoint_confirm_changes_clears_persisted_interrupt packages/ag-ui/tests/ag_ui/test_approval_result_event.py -q; uv run pytest packages/ag-ui/tests/ag_ui/test_agent_wrapper_comprehensive.py::test_approval_argument_mismatch_is_blocked packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_resume_entry_applies_edited_arguments packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_resume_entry_executes_approved_tool -q; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe typing -P ag-ui; uv run poe test -P ag-ui; uv run poe check -P ag-ui; git diff --check; git diff --cached --check. Notes: issues/agui-int-03-agent-approval-resume-entry.md was moved to issues/done locally but remains unstaged. Existing local README, PRD, and .ralph artifacts remain unstaged. Follow-up slices still own workflow request_info canonical resume, client-side forwarding, stricter pending interrupt contract enforcement, snapshot stale-prompt clearing, and documentation/examples.
Key decisions: emit workflow request_info pauses as canonical input_required interrupt outcomes with response schemas and Agent Framework metadata; normalize typed ResumeEntry model dumps through the shared resume parser while preserving status; translate resolved workflow resume payloads through the existing workflow response coercion path; emit RUN_ERROR for cancelled workflow resumes before invoking the workflow. Files changed: packages/ag-ui/agent_framework_ag_ui/_run_common.py preserves canonical resume status/model dumps and merges interrupt metadata values; packages/ag-ui/agent_framework_ag_ui/_workflow_run.py builds canonical workflow request_info interrupts and cancellation errors; packages/ag-ui/tests/ag_ui/test_endpoint.py adds endpoint/SSE workflow pause, resolved resume, and cancelled resume coverage; packages/ag-ui/tests/ag_ui/test_run_common.py and packages/ag-ui/tests/ag_ui/test_workflow_run.py update canonical helper expectations. Verification: uv run pytest packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_workflow_request_info_emits_canonical_interrupt_and_resumes packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_workflow_request_info_cancelled_resume_emits_run_error -q; uv run pytest packages/ag-ui/tests/ag_ui/test_workflow_run.py -q; uv run pytest packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_resume_entry_executes_approved_tool packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_resume_entry_denial_does_not_execute_tool packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_resume_entry_applies_edited_arguments packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_cancelled_resume_entry_emits_run_error packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_agent_approval_unknown_resume_entry_emits_run_error -q; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe test -P ag-ui; uv run poe typing -P ag-ui; uv run poe check -P ag-ui; git diff --check; git diff --cached --check. Notes: issue bookkeeping and local PRD files were not staged; existing unstaged packages/ag-ui/README.md remains untouched. Follow-up slices still own client-side forwarding, stricter pending interrupt contract enforcement, snapshot stale-prompt clearing, and documentation/examples.
Key decisions: normalize typed Interrupt and ResumeEntry values at the AGUIChatClient and AGUIHttpService boundaries using protocol aliases; map legacy request_info available-interrupt hints to canonical input_required reason while preserving legacy resume wrapper shapes; preserve remote RUN_FINISHED.outcome metadata and expose outcome.interrupts for Agent Framework callers without changing normal success completion handling. Files changed: packages/ag-ui/agent_framework_ag_ui/_client.py forwards normalized available_interrupts/resume values; packages/ag-ui/agent_framework_ag_ui/_http_service.py serializes typed protocol models and compatible values to camelCase wire JSON; packages/ag-ui/agent_framework_ag_ui/_event_converters.py preserves canonical outcomes/interruption metadata; packages/ag-ui/tests/ag_ui/test_ag_ui_client.py, test_http_service.py, and test_event_converters.py cover outgoing typed JSON, canonical interrupted conversion, and success outcome behavior. Verification: uv run pytest packages/ag-ui/tests/ag_ui/test_http_service.py::test_post_run_serializes_typed_interrupts_and_resume_with_protocol_aliases packages/ag-ui/tests/ag_ui/test_ag_ui_client.py::TestAGUIChatClient::test_typed_interrupt_options_forward_canonical_protocol_shape packages/ag-ui/tests/ag_ui/test_event_converters.py::TestAGUIEventConverter::test_run_finished_event_with_canonical_interrupt_outcome packages/ag-ui/tests/ag_ui/test_event_converters.py::TestAGUIEventConverter::test_run_finished_event_with_success_outcome_preserves_normal_completion -q; uv run pytest packages/ag-ui/tests/ag_ui/test_http_service.py packages/ag-ui/tests/ag_ui/test_ag_ui_client.py packages/ag-ui/tests/ag_ui/test_event_converters.py -q; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe test -P ag-ui; uv run poe typing -P ag-ui; uv run poe check -P ag-ui; git diff --check; git diff --cached --check. Notes: issues/agui-int-05-chat-client-http-forwarding.md was moved to issues/done locally but not staged. Existing unstaged packages/ag-ui/README.md, .ralph, PRD, and snapshot planning artifacts remain untouched. Follow-up slices still own stricter pending interrupt contract enforcement, snapshot stale-prompt clearing, and documentation/examples.
Key decisions: validate pending AG-UI interrupts before agent or workflow execution; require resume entries to address every open interrupt exactly once; emit RUN_ERROR for missing, unknown, duplicate, malformed, cancelled, or schema-invalid resume payloads; keep successful canonical approval and workflow resume flows working while removing heuristic non-resume workflow continuation for interrupted threads. Files changed: packages/ag-ui/agent_framework_ag_ui/_run_common.py adds strict resume parsing and exact pending-interrupt contract validation; _agent_run.py applies the contract to approval resumes, validates edited approval argument types, and considers stored canonical interrupt ids; _workflow_run.py applies the contract to request_info resumes and fails invalid response coercion explicitly; AG-UI endpoint, workflow, golden, wrapper, and subgraph tests now cover RUN_ERROR failures and canonical resume entries. Verification: uv run pytest focused new resume-contract endpoint tests -q; uv run pytest existing approval/workflow resume endpoint tests -q; uv run pytest packages/ag-ui/tests/ag_ui/test_workflow_run.py packages/ag-ui/tests/ag_ui/test_run.py packages/ag-ui/tests/ag_ui/golden/test_scenario_workflow.py -q; uv run poe test -P ag-ui; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe typing -P ag-ui; uv run poe check -P ag-ui; git diff --check; git diff --cached --check. Notes: issues/agui-int-06-resume-contract-validation.md was moved to issues/done locally but not staged. Existing unstaged packages/ag-ui/README.md and local .ralph/PRD artifacts remain untouched. Follow-up slices still own canonical snapshot stale-prompt clearing and documentation/examples.
Key decisions: treat cancelled canonical approval and workflow resumes as completion of the stored interruption for AG-UI Thread Snapshot hydration; clear only the persisted interrupt field while preserving replayable messages and Shared State; consume cancelled approval registry entries so server-side approval state does not remain open; preserve existing RUN_ERROR responses for cancelled resumes. Files changed: packages/ag-ui/agent_framework_ag_ui/_snapshots.py adds shared persisted-interrupt clearing; _agent_run.py clears snapshots and consumes pending approvals on cancelled approval resumes; _workflow.py clears snapshots on cancelled workflow resumes; test_endpoint.py covers agent/workflow cancelled-resume stale prompt clearing; test_run_common.py covers canonical interrupt toolCallId trusted suffix filtering. Verification: uv run pytest focused interrupted snapshot/resume tests -q; uv run poe test -P ag-ui; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe typing -P ag-ui; uv run poe check -P ag-ui; git diff --check; git diff --cached --check. Notes: issues/agui-int-07-thread-snapshot-interrupt-hydration.md was moved to issues/done locally but not staged. Existing unstaged packages/ag-ui/README.md and local .ralph/PRD artifacts remain untouched. Follow-up docs/examples slice still owns public guidance updates.
Key decisions: document the clean release-candidate interrupt cutover around canonical AG-UI protocol models; direct users to RUN_FINISHED.outcome.interrupts and canonical resume arrays; make clear that Interrupt and ResumeEntry come from ag_ui.core rather than an Agent Framework-specific model; retain normal RUN_FINISHED completion guidance for non-interrupted runs. Files changed: packages/ag-ui/AGENTS.md updates package guidance; packages/ag-ui/README.md adds interrupt/resume protocol and migration notes; packages/ag-ui/agent_framework_ag_ui_examples/README.md documents canonical resume shape for examples; packages/ag-ui/getting_started/README.md teaches outcome.interrupts and ResumeEntry usage. Verification: uv run poe markdown-code-lint failed on pre-existing packages/mistral/README.md; uv run python scripts/check_md_code_blocks.py packages/ag-ui/README.md packages/ag-ui/agent_framework_ag_ui_examples/README.md packages/ag-ui/getting_started/README.md packages/ag-ui/AGENTS.md; git diff --check; git diff --cached --check. Notes: no issue or PRD artifacts were staged. Root AGENTS.md could not be read because access was denied; package and Python workspace guidance were applied. Follow-up docs/examples issue appears complete; no remaining AG-UI interrupt cutover tasks were found locally.
…rrupt # Conflicts: # python/packages/ag-ui/pyproject.toml
There was a problem hiding this comment.
Pull request overview
This PR updates the Python AG-UI integration to use the canonical AG-UI interrupt/resume contract, moving interrupted-run data to RUN_FINISHED.outcome.type == "interrupt" with outcome.interrupts, and requiring canonical resume entries to continue or cancel pauses (approvals and workflow request_info).
Changes:
- Canonicalizes interrupted run completion shape to
RUN_FINISHED.outcome.interrupts(removing the stable top-levelinterruptfield for interrupted runs). - Implements strict resume-contract validation (missing/unknown/invalid/cancelled/resolved) with streamed
RUN_ERRORcodes, and clears only completed/cancelled interrupt state (including snapshot-backed hydration). - Updates docs, examples, client serialization, and extensive test coverage; bumps
ag-ui-protocolto>=0.1.19,<0.2.
Reviewed changes
Copilot reviewed 31 out of 32 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| python/uv.lock | Bumps locked dependency to ag-ui-protocol>=0.1.19,<0.2. |
| python/packages/ag-ui/pyproject.toml | Raises ag-ui-protocol minimum version for canonical models. |
| python/packages/ag-ui/README.md | Documents canonical interrupt/resume wire shape and breaking change. |
| python/packages/ag-ui/getting_started/README.md | Adds canonical resume-entry documentation to the tutorial. |
| python/packages/ag-ui/AGENTS.md | Updates contributor guidance to canonical outcome.interrupts shape. |
| python/packages/ag-ui/agent_framework_ag_ui/_types.py | Types available_interrupts as canonical Interrupt; makes resume permissive at the HTTP trust boundary. |
| python/packages/ag-ui/agent_framework_ag_ui/_run_common.py | Adds canonical interrupt construction, resume-entry parsing/validation helpers, and emits RunFinishedInterruptOutcome. |
| python/packages/ag-ui/agent_framework_ag_ui/_workflow_run.py | Canonicalizes workflow request_info interrupts + strict resume validation and response coercion. |
| python/packages/ag-ui/agent_framework_ag_ui/_workflow.py | Reads canonical outcome interrupts for snapshots; clears snapshot interrupts on cancelled workflow resumes. |
| python/packages/ag-ui/agent_framework_ag_ui/_agent.py | Migrates pending-approval registry keys to structured (thread_id, request_id) tuples. |
| python/packages/ag-ui/agent_framework_ag_ui/_agent_run.py | Implements canonical approval resume handling, cancellation semantics, snapshot seeding, and registry validation. |
| python/packages/ag-ui/agent_framework_ag_ui/_http_service.py | Serializes typed and legacy interrupt/resume inputs into canonical wire JSON (aliases). |
| python/packages/ag-ui/agent_framework_ag_ui/_client.py | Ensures chat client forwards canonical availableInterrupts/resume wire shapes. |
| python/packages/ag-ui/agent_framework_ag_ui/_event_converters.py | Preserves canonical outcome/interrupts metadata on converted ChatResponseUpdate. |
| python/packages/ag-ui/agent_framework_ag_ui/_snapshots.py | Adds helper to clear stored snapshot interrupt state (all or by interrupt id set). |
| python/packages/ag-ui/tests/ag_ui/event_stream.py | Adds helpers to assert canonical RUN_FINISHED.outcome.interrupts in tests. |
| python/packages/ag-ui/tests/ag_ui/test_types.py | Updates request typing tests for canonical Interrupt + permissive resume. |
| python/packages/ag-ui/tests/ag_ui/test_http_service.py | Verifies canonical serialization for typed + legacy interrupt/resume inputs. |
| python/packages/ag-ui/tests/ag_ui/test_ag_ui_client.py | Ensures client forwards canonical interrupt/resume payloads to HTTP service. |
| python/packages/ag-ui/tests/ag_ui/test_event_converters.py | Tests converter behavior for canonical RUN_FINISHED.outcome shapes. |
| python/packages/ag-ui/tests/ag_ui/test_run_common.py | Adds tests for canonical run-finished outcome shape and snapshot reconstruction. |
| python/packages/ag-ui/tests/ag_ui/test_run.py | Updates/expands agent-stream tests for canonical interrupts, approvals, and resume/cancel behavior. |
| python/packages/ag-ui/tests/ag_ui/test_multi_turn.py | Updates multi-turn round-trip tests to read canonical interrupts and validate no-outcome completion. |
| python/packages/ag-ui/tests/ag_ui/test_workflow_run.py | Updates workflow stream tests for canonical interrupts and strict resume-required errors. |
| python/packages/ag-ui/tests/ag_ui/test_workflow_agent.py | Updates workflow wrapper tests for canonical interrupt outcome. |
| python/packages/ag-ui/tests/ag_ui/test_subgraphs_example_agent.py | Updates subgraphs example tests for canonical interrupts + resume-required error behavior. |
| python/packages/ag-ui/tests/ag_ui/test_endpoint.py | Adds extensive SSE endpoint coverage for canonical pause/resume/cancel + snapshot hydration behavior. |
| python/packages/ag-ui/tests/ag_ui/test_agent_wrapper_comprehensive.py | Updates comprehensive wrapper tests to use canonical resume entries and new registry keying. |
| python/packages/ag-ui/tests/ag_ui/golden/test_scenario_workflow.py | Updates golden workflow scenarios for canonical outcome shape and strict resume requirements. |
| python/packages/ag-ui/tests/ag_ui/golden/test_scenario_subgraphs.py | Updates golden subgraphs scenarios for canonical outcome shape. |
| python/packages/ag-ui/tests/ag_ui/golden/test_scenario_hitl.py | Updates golden HITL scenarios for canonical outcome shape. |
| python/packages/ag-ui/agent_framework_ag_ui_examples/README.md | Documents canonical interrupt/resume shape used by examples. |
There was a problem hiding this comment.
Automated Code Review
Reviewers: 4 | Confidence: 74%
✓ Correctness
This is a large, well-structured breaking change that canonicalizes AG-UI interrupt/resume handling. The core logic is sound and the test coverage is comprehensive. I found one inconsistency between
_coerce_responses_for_pending_requests_strictand its non-strict sibling: the strict version does not index pending events byevent.request_id(only by dict key), while the non-strict version was updated in this same PR to include both lookups. When dict keys andevent.request_idattributes diverge, responses may bypass type validation in the strict path.
✓ Security Reliability
The PR implements solid input validation and contract enforcement for the canonical interrupt/resume protocol. The security model (pending approval registry, resume contract validation, argument type checking) is well-designed. One reliability issue: the AGUIChatClient pre-serializes available_interrupts and resume before passing to post_run, which internally re-serializes them, creating wasteful double-validation that could surface unexpected Pydantic validation errors if the models evolve.
✓ Failure Modes
The PR canonicalizes AG-UI interrupt/resume handling with thorough validation. The primary failure-mode concern is in _serialize_resume where unrecognized Mapping structures silently pass through without canonical validation, potentially sending invalid wire data. The snapshot cleanup uses a catch-all exception handler that, while logging, could leave threads in a wedged state if the clear fails after pending-approval registry entries have already been consumed.
✗ Design Approach
I found two design-level regressions in the new pause/resume contract handling. First, the strict resume validator no longer accepts the legacy
toolCallIdalias even though the rest of this package still treats it as a compatibility input, so direct server callers can now fail before their resume payload is canonicalized. Second, the new strict workflow-response coercion dropped the existing alias mapping between the workflow runner’s internal dict key andrequest_event.request_id, which means some canonical interrupt IDs now bypass the very type/approval validation this PR is trying to enforce.
Flagged Issues
-
_run_common.py:158–_strict_resume_entriesrejects resume entries using the legacytoolCallIdkey even though_normalize_resume_interrupts(line 80-85) and_serialize_resume_entry(_http_service.py:59-64) still accept it as a compatibility alias. Direct AG-UI requests withtoolCallIdnow fail validation instead of being canonicalized. -
_workflow_run.py:549– The strict coercion helper indexespending_by_idonly by the raw dict key, unlike the non-strict sibling which also indexes byevent.request_id. Since_pending_workflow_interrupt_idsprefersevent.request_idover the dict key (line 242), resume payloads addressed to the canonical interrupt ID bypass_coerce_response_for_request()and_approval_response_matches_request()entirely.
Suggestions
- The client at
_client.py:443-444pre-serializesavailable_interruptsandresume, butpost_run(_http_service.py:209,213) re-serializes them internally. Consider passing raw values topost_runand letting it handle serialization exclusively, or removing the redundant internal serialization for the client path.
Automated review by moonbox3's agents
|
Flagged issue
Source: automated DevFlow PR review |
|
Flagged issue
Source: automated DevFlow PR review |
|
|
||
|
|
||
| def _evict_oldest_approvals(registry: dict[str, PendingApprovalEntry], max_size: int = 10_000) -> None: | ||
| def _pending_approval_request_id(entry: PendingApprovalEntry) -> str | None: |
There was a problem hiding this comment.
I'm never a big fan of these kinds of helper functions that are only used once...
| pending_approvals: dict[PendingApprovalKey, PendingApprovalEntry] | None, | ||
| thread_id: str, | ||
| ) -> bool: | ||
| if pending_approvals is None: |
There was a problem hiding this comment.
might as well cover the empty dict case early:
| if pending_approvals is None: | |
| if not pending_approvals: |
| pending_approvals: dict[PendingApprovalKey, PendingApprovalEntry] | None, | ||
| thread_id: str, | ||
| ) -> set[str]: | ||
| if pending_approvals is None: |
|
|
||
| converter = AGUIEventConverter() | ||
|
|
||
| available_interrupts = options.get("available_interrupts") |
There was a problem hiding this comment.
| available_interrupts = options.get("available_interrupts") | |
| available_interrupts = options.get("available_interrupts", options.get("availableInterrupts")) |
| if "outcome" in event: | ||
| outcome = event.get("outcome") | ||
| additional_properties["outcome"] = outcome | ||
| if isinstance(outcome, dict) and outcome.get("type") == "interrupt": |
There was a problem hiding this comment.
is there ever a case where we would accept outcome not to be a dict, and what should happen? wonderign if this should just fail loudly instead of silently ignoring
Motivation & Context
AG-UI agent and workflow interrupts need a single protocol-level pause/resume contract that matches the canonical AG-UI
InterruptandResumeEntrymodels. The current integration exposes an undesired interrupt shape, and several resume/cancel paths can leave approval, workflow, or snapshot state stale.Description & Review Guide
What are the major changes?
RUN_FINISHED.outcome.type == "interrupt"with canonicaloutcome.interrupts.request_infopauses through canonical AG-UI interrupt/resume data.ResumeEntryarrays.RUN_ERRORevents.ag-ui-protocoldependency to the version that contains the canonical models.What is the impact of these changes?
RUN_FINISHED.outcome.interruptsinstead of the legacy top-level interrupt field.resumeentries withinterruptId,status, and optionalpayload.What do you want reviewers to focus on?
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.