agent-framework-ag-ui 1.2.2__tar.gz → 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/AGENTS.md +9 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/PKG-INFO +27 -8
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/README.md +24 -5
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/__init__.py +4 -1
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_agent.py +28 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_agent_run.py +261 -44
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_approval_lifecycle.py +69 -2
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_approval_state.py +2 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_client.py +86 -25
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_endpoint.py +5 -1
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_message_adapters.py +423 -59
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_run_common.py +57 -29
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_snapshot_session.py +2 -2
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_snapshots.py +34 -2
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_state.py +43 -2
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_types.py +10 -2
- agent_framework_ag_ui-1.3.0/agent_framework_ag_ui/_utils.py +519 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_workflow.py +38 -18
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_workflow_run.py +90 -14
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/pyproject.toml +3 -3
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_ag_ui_client.py +258 -17
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_endpoint.py +1010 -10
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_message_adapters.py +1150 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_public_exports.py +5 -3
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_run.py +130 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_run_common.py +376 -1
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_snapshot_session.py +32 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_snapshots.py +69 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_workflow_run.py +186 -4
- agent_framework_ag_ui-1.2.2/agent_framework_ag_ui/_utils.py +0 -285
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/.gitignore +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/LICENSE +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_a2ui/__init__.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_a2ui/_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_a2ui/_factory.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_a2ui/_state.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_event_converters.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_feature_usage.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_http_service.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_predictive_state.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/_tooling.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/py.typed +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/.env.example +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/.vscode/settings.json +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/README.md +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/__init__.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/__main__.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/__init__.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/a2ui_agents.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/document_writer_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/human_in_the_loop_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/recipe_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/research_assistant_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/simple_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/subgraphs_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/task_planner_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/task_steps_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/ui_generator_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/weather_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/agents/weather_state_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/server/__init__.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/server/api/backend_tool_rendering.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui_examples/server/main.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/getting_started/README.md +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/getting_started/client.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/getting_started/client_advanced.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/getting_started/client_with_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/getting_started/server.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/conftest.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/event_stream.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/__init__.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/conftest.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_agentic_chat.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_backend_tools.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_deterministic_state.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_generative_ui_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_generative_ui_tool.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_hitl.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_predictive_state.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_shared_state.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_subgraphs.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/golden/test_scenario_workflow.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/sse_helpers.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_a2ui.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_agent_wrapper_comprehensive.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_approval_lifecycle.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_approval_result_event.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_approval_state.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_confirm_changes_snapshot.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_event_converters.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_forwarded_props_in_metadata.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_handoff_replay.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_http_round_trip.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_http_service.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_message_hygiene.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_multi_turn.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_predictive_state.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_service_thread_id.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_structured_output.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_subgraphs_example_agent.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_tooling.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_types.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_utils.py +0 -0
- {agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/tests/ag_ui/test_workflow_agent.py +0 -0
|
@@ -8,6 +8,8 @@ AG-UI protocol integration for building agent UIs with the AG-UI standard.
|
|
|
8
8
|
- **`AgentFrameworkWorkflow`** - Wraps native `Workflow` objects, or accepts `workflow_factory(thread_id)` for thread-scoped workflow instances without subclassing
|
|
9
9
|
- **`AGUIChatClient`** - Chat client that speaks AG-UI protocol
|
|
10
10
|
- **`AGUIHttpService`** - HTTP service for AG-UI endpoints
|
|
11
|
+
- **`agent_framework_messages_to_agui_host_history()`** - Converts persisted Agent Framework messages to bounded
|
|
12
|
+
AG-UI Host history while retaining MCP widget payloads and model replay metadata
|
|
11
13
|
- **`AGUIEventConverter`** - Converts between Agent Framework and AG-UI events
|
|
12
14
|
- **`add_agent_framework_fastapi_endpoint()`** - Add AG-UI endpoint to FastAPI app (`SupportsAgentRun` or `Workflow`)
|
|
13
15
|
- **`InMemoryAGUIThreadSnapshotStore`** - Memory-only latest AG-UI Thread Snapshot store for local development, demos, and tests
|
|
@@ -50,6 +52,13 @@ AG-UI protocol integration for building agent UIs with the AG-UI standard.
|
|
|
50
52
|
- AG-UI Thread and Run ids are client-owned protocol correlation ids. Service-session mode stores provider conversation
|
|
51
53
|
or response ids privately in the thread snapshot. Set `service_session_id_from_thread_id=True` only for compatibility
|
|
52
54
|
when the application intentionally uses a provider continuation id as its AG-UI Thread id.
|
|
55
|
+
- A configured Snapshot Scope and the client-owned Thread id are combined into a deterministic internal
|
|
56
|
+
`AgentSession.session_id`. Keep the raw Thread id for protocol events and snapshot addressing so equal Thread ids
|
|
57
|
+
in different trusted scopes cannot collide in context-provider state. The deprecated
|
|
58
|
+
`legacy_session_id_from_thread_id=True` compatibility option preserves raw provider keys only for explicit
|
|
59
|
+
migrations and must warn because it disables that isolation; it is unsafe for shared multi-tenant deployments.
|
|
60
|
+
A configured endpoint resolver must return a non-empty string. Reject invalid results before accessing state or
|
|
61
|
+
invoking the runner; absence of a resolver, not an invalid result, selects intentionally unscoped operation.
|
|
53
62
|
- `confirm_changes` snapshot cleanup resolves the synthetic confirmation back to its original `function_call_id`;
|
|
54
63
|
it must never concatenate unrelated tool results or record accepted changes without a matching real result.
|
|
55
64
|
- SSE keepalive is endpoint-owned transport behavior configured through
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agent-framework-ag-ui
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: AG-UI protocol integration for Agent Framework
|
|
5
5
|
Project-URL: homepage, https://aka.ms/agent-framework
|
|
6
6
|
Project-URL: source, https://github.com/microsoft/agent-framework/tree/main/python
|
|
@@ -19,8 +19,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
19
19
|
Classifier: Typing :: Typed
|
|
20
20
|
Requires-Python: >=3.10
|
|
21
21
|
Requires-Dist: ag-ui-protocol<0.2,>=0.1.19
|
|
22
|
-
Requires-Dist: agent-framework-core<2,>=1.
|
|
23
|
-
Requires-Dist: fastapi<0.
|
|
22
|
+
Requires-Dist: agent-framework-core<2,>=1.18.0
|
|
23
|
+
Requires-Dist: fastapi<0.142.0,>=0.121.0
|
|
24
24
|
Requires-Dist: httpx<1,>=0.28.1
|
|
25
25
|
Requires-Dist: sse-starlette<4,>=3.4.5
|
|
26
26
|
Requires-Dist: uvicorn[standard]<1,>=0.30.0
|
|
@@ -271,12 +271,14 @@ Review focus: whether these names are the right stable contract for Python users
|
|
|
271
271
|
|
|
272
272
|
| Surface | Public exports |
|
|
273
273
|
| --- | --- |
|
|
274
|
-
| `agent_framework.ag_ui` facade | `AgentFrameworkAgent`, `AgentFrameworkWorkflow`, `AGUIChatClient`, `AGUIEventConverter`, `AGUIHttpService`, `AGUIThreadSnapshot`, `AGUIThreadSnapshotStore`, `InMemoryAGUIThreadSnapshotStore`, `SnapshotScopeResolver`, `add_agent_framework_fastapi_endpoint`, `state_update`, `__version__` |
|
|
274
|
+
| `agent_framework.ag_ui` facade | `AgentFrameworkAgent`, `AgentFrameworkWorkflow`, `AGUIChatClient`, `AGUIEventConverter`, `AGUIHttpService`, `AGUIThreadSnapshot`, `AGUIThreadSnapshotStore`, `InMemoryAGUIThreadSnapshotStore`, `SnapshotScopeResolver`, `add_agent_framework_fastapi_endpoint`, `state_carrier`, `state_update`, `__version__` |
|
|
275
275
|
| Direct `agent_framework_ag_ui` package | Facade exports plus `AGUIChatOptions`, `AGUIRequest`, `AGUIThreadID`, `AgentState`, `DEFAULT_MAX_THREAD_SNAPSHOTS`, `DEFAULT_TAGS`, `PredictStateConfig`, `RunMetadata`, `SnapshotScope`, `WorkflowFactory` |
|
|
276
276
|
| AG-UI protocol package (`ag_ui.core`) | `Interrupt`, `ResumeEntry`, `RunFinishedInterruptOutcome`, and related run outcome models |
|
|
277
277
|
|
|
278
278
|
Interrupt support is protocol data rather than a separate Agent Framework Python class. Requests accept canonical `availableInterrupts`/`available_interrupts` and `resume` values; `AGUIChatClient` and `AGUIHttpService.post_run(...)` forward those fields with AG-UI wire aliases; agent approval and workflow `request_info` pauses emit `RUN_FINISHED.outcome.interrupts`; `AGUIEventConverter` preserves canonical interrupt outcome metadata on the final `ChatResponseUpdate`; and thread snapshot hydration replays the canonical interrupt outcome when a scoped snapshot stores an unresolved pause.
|
|
279
279
|
|
|
280
|
+
Use `state_carrier(...)` to mark JSON content that should be sent in the AG-UI request's `state` field rather than as a model-visible document. The client removes explicitly marked carriers from all client-controlled history and uses the most recent carrier. Ordinary `application/json` content remains a document. For migration, pass `allow_legacy_state_carrier=True` in `AGUIChatOptions` to recognize the deprecated final single-content base64 JSON convention; mixed text and document messages remain model-visible. This client-only option emits a `DeprecationWarning` when the legacy convention is used and is not sent to the remote server.
|
|
281
|
+
|
|
280
282
|
## Features
|
|
281
283
|
|
|
282
284
|
This integration supports all 7 AG-UI features:
|
|
@@ -410,10 +412,27 @@ A frontend can then hydrate the latest stored snapshot for the scoped thread:
|
|
|
410
412
|
|
|
411
413
|
Endpoint configuration requires `snapshot_scope_resolver` whenever a snapshot store is configured, including when
|
|
412
414
|
the store is already set on a pre-wrapped `AgentFrameworkAgent` or `AgentFrameworkWorkflow`. The resolver returns
|
|
413
|
-
the application-defined Snapshot Scope used with the AG-UI Thread id as the storage key.
|
|
414
|
-
`
|
|
415
|
-
|
|
416
|
-
|
|
415
|
+
the application-defined Snapshot Scope used with the AG-UI Thread id as the storage key. The endpoint also derives
|
|
416
|
+
the internal `AgentSession.session_id` from this trusted scope and the client-owned Thread id, so context providers
|
|
417
|
+
cannot merge server-side state for equal Thread ids in different scopes. The raw Thread id remains unchanged in
|
|
418
|
+
AG-UI events and snapshot operations. When using `AgentFrameworkWorkflow(workflow_factory=...)`, the same resolver
|
|
419
|
+
also scopes the in-memory workflow cache even without a snapshot store; provide it in multi-user deployments so two
|
|
420
|
+
users who submit the same `threadId` do not share a live `Workflow` instance.
|
|
421
|
+
|
|
422
|
+
Authenticate and authorize the current scope on every request, including hydration and approval resume, rather than
|
|
423
|
+
trusting a scope supplied through Shared State or forwarded properties. A configured resolver must return a non-empty
|
|
424
|
+
string. Returning `None`, an empty string, or another type fails the request with a generic HTTP 500 configuration
|
|
425
|
+
error before accessing snapshots, approval state, or context providers. Resolver failures never fall back to unscoped
|
|
426
|
+
operation. Valid scope strings are used exactly as returned, without trimming or normalization. An endpoint without a
|
|
427
|
+
resolver remains intentionally unscoped; it must not share session-keyed storage across distinct authorization scopes.
|
|
428
|
+
Use endpoint authentication dependencies to reject unauthorized requests before scope resolution.
|
|
429
|
+
|
|
430
|
+
Existing applications that need time to migrate provider records from raw Thread-id keys can temporarily wrap the
|
|
431
|
+
agent with `AgentFrameworkAgent(..., legacy_session_id_from_thread_id=True)`. This deprecated compatibility option
|
|
432
|
+
emits a `DeprecationWarning` and disables Snapshot Scope isolation for context-provider state. It is not safe for a
|
|
433
|
+
shared multi-tenant deployment, even with a trusted resolver. Keep it disabled when establishing scope isolation.
|
|
434
|
+
|
|
435
|
+
### Request state and snapshot authority
|
|
417
436
|
|
|
418
437
|
For hosted agents, request Shared State is also available through `AgentSession.state` during that run, whether or
|
|
419
438
|
not snapshot persistence is configured. Request values are untrusted per-run context: they overlay ordinary restored
|
|
@@ -239,12 +239,14 @@ Review focus: whether these names are the right stable contract for Python users
|
|
|
239
239
|
|
|
240
240
|
| Surface | Public exports |
|
|
241
241
|
| --- | --- |
|
|
242
|
-
| `agent_framework.ag_ui` facade | `AgentFrameworkAgent`, `AgentFrameworkWorkflow`, `AGUIChatClient`, `AGUIEventConverter`, `AGUIHttpService`, `AGUIThreadSnapshot`, `AGUIThreadSnapshotStore`, `InMemoryAGUIThreadSnapshotStore`, `SnapshotScopeResolver`, `add_agent_framework_fastapi_endpoint`, `state_update`, `__version__` |
|
|
242
|
+
| `agent_framework.ag_ui` facade | `AgentFrameworkAgent`, `AgentFrameworkWorkflow`, `AGUIChatClient`, `AGUIEventConverter`, `AGUIHttpService`, `AGUIThreadSnapshot`, `AGUIThreadSnapshotStore`, `InMemoryAGUIThreadSnapshotStore`, `SnapshotScopeResolver`, `add_agent_framework_fastapi_endpoint`, `state_carrier`, `state_update`, `__version__` |
|
|
243
243
|
| Direct `agent_framework_ag_ui` package | Facade exports plus `AGUIChatOptions`, `AGUIRequest`, `AGUIThreadID`, `AgentState`, `DEFAULT_MAX_THREAD_SNAPSHOTS`, `DEFAULT_TAGS`, `PredictStateConfig`, `RunMetadata`, `SnapshotScope`, `WorkflowFactory` |
|
|
244
244
|
| AG-UI protocol package (`ag_ui.core`) | `Interrupt`, `ResumeEntry`, `RunFinishedInterruptOutcome`, and related run outcome models |
|
|
245
245
|
|
|
246
246
|
Interrupt support is protocol data rather than a separate Agent Framework Python class. Requests accept canonical `availableInterrupts`/`available_interrupts` and `resume` values; `AGUIChatClient` and `AGUIHttpService.post_run(...)` forward those fields with AG-UI wire aliases; agent approval and workflow `request_info` pauses emit `RUN_FINISHED.outcome.interrupts`; `AGUIEventConverter` preserves canonical interrupt outcome metadata on the final `ChatResponseUpdate`; and thread snapshot hydration replays the canonical interrupt outcome when a scoped snapshot stores an unresolved pause.
|
|
247
247
|
|
|
248
|
+
Use `state_carrier(...)` to mark JSON content that should be sent in the AG-UI request's `state` field rather than as a model-visible document. The client removes explicitly marked carriers from all client-controlled history and uses the most recent carrier. Ordinary `application/json` content remains a document. For migration, pass `allow_legacy_state_carrier=True` in `AGUIChatOptions` to recognize the deprecated final single-content base64 JSON convention; mixed text and document messages remain model-visible. This client-only option emits a `DeprecationWarning` when the legacy convention is used and is not sent to the remote server.
|
|
249
|
+
|
|
248
250
|
## Features
|
|
249
251
|
|
|
250
252
|
This integration supports all 7 AG-UI features:
|
|
@@ -378,10 +380,27 @@ A frontend can then hydrate the latest stored snapshot for the scoped thread:
|
|
|
378
380
|
|
|
379
381
|
Endpoint configuration requires `snapshot_scope_resolver` whenever a snapshot store is configured, including when
|
|
380
382
|
the store is already set on a pre-wrapped `AgentFrameworkAgent` or `AgentFrameworkWorkflow`. The resolver returns
|
|
381
|
-
the application-defined Snapshot Scope used with the AG-UI Thread id as the storage key.
|
|
382
|
-
`
|
|
383
|
-
|
|
384
|
-
|
|
383
|
+
the application-defined Snapshot Scope used with the AG-UI Thread id as the storage key. The endpoint also derives
|
|
384
|
+
the internal `AgentSession.session_id` from this trusted scope and the client-owned Thread id, so context providers
|
|
385
|
+
cannot merge server-side state for equal Thread ids in different scopes. The raw Thread id remains unchanged in
|
|
386
|
+
AG-UI events and snapshot operations. When using `AgentFrameworkWorkflow(workflow_factory=...)`, the same resolver
|
|
387
|
+
also scopes the in-memory workflow cache even without a snapshot store; provide it in multi-user deployments so two
|
|
388
|
+
users who submit the same `threadId` do not share a live `Workflow` instance.
|
|
389
|
+
|
|
390
|
+
Authenticate and authorize the current scope on every request, including hydration and approval resume, rather than
|
|
391
|
+
trusting a scope supplied through Shared State or forwarded properties. A configured resolver must return a non-empty
|
|
392
|
+
string. Returning `None`, an empty string, or another type fails the request with a generic HTTP 500 configuration
|
|
393
|
+
error before accessing snapshots, approval state, or context providers. Resolver failures never fall back to unscoped
|
|
394
|
+
operation. Valid scope strings are used exactly as returned, without trimming or normalization. An endpoint without a
|
|
395
|
+
resolver remains intentionally unscoped; it must not share session-keyed storage across distinct authorization scopes.
|
|
396
|
+
Use endpoint authentication dependencies to reject unauthorized requests before scope resolution.
|
|
397
|
+
|
|
398
|
+
Existing applications that need time to migrate provider records from raw Thread-id keys can temporarily wrap the
|
|
399
|
+
agent with `AgentFrameworkAgent(..., legacy_session_id_from_thread_id=True)`. This deprecated compatibility option
|
|
400
|
+
emits a `DeprecationWarning` and disables Snapshot Scope isolation for context-provider state. It is not safe for a
|
|
401
|
+
shared multi-tenant deployment, even with a trusted resolver. Keep it disabled when establishing scope isolation.
|
|
402
|
+
|
|
403
|
+
### Request state and snapshot authority
|
|
385
404
|
|
|
386
405
|
For hosted agents, request Shared State is also available through `AgentSession.state` during that run, whether or
|
|
387
406
|
not snapshot persistence is configured. Request values are untrusted per-run context: they overlay ordinary restored
|
{agent_framework_ag_ui-1.2.2 → agent_framework_ag_ui-1.3.0}/agent_framework_ag_ui/__init__.py
RENAMED
|
@@ -10,6 +10,7 @@ from ._client import AGUIChatClient
|
|
|
10
10
|
from ._endpoint import add_agent_framework_fastapi_endpoint
|
|
11
11
|
from ._event_converters import AGUIEventConverter
|
|
12
12
|
from ._http_service import AGUIHttpService
|
|
13
|
+
from ._message_adapters import agent_framework_messages_to_agui_host_history
|
|
13
14
|
from ._snapshots import (
|
|
14
15
|
DEFAULT_MAX_THREAD_SNAPSHOTS,
|
|
15
16
|
AGUIThreadID,
|
|
@@ -19,7 +20,7 @@ from ._snapshots import (
|
|
|
19
20
|
SnapshotScope,
|
|
20
21
|
SnapshotScopeResolver,
|
|
21
22
|
)
|
|
22
|
-
from ._state import state_update
|
|
23
|
+
from ._state import state_carrier, state_update
|
|
23
24
|
from ._types import AgentState, AGUIChatOptions, AGUIRequest, PredictStateConfig, RunMetadata
|
|
24
25
|
from ._workflow import AgentFrameworkWorkflow, WorkflowFactory
|
|
25
26
|
|
|
@@ -39,6 +40,7 @@ __all__ = [
|
|
|
39
40
|
"AgentFrameworkWorkflow",
|
|
40
41
|
"WorkflowFactory",
|
|
41
42
|
"add_agent_framework_fastapi_endpoint",
|
|
43
|
+
"agent_framework_messages_to_agui_host_history",
|
|
42
44
|
"AGUIChatClient",
|
|
43
45
|
"AGUIChatOptions",
|
|
44
46
|
"AGUIEventConverter",
|
|
@@ -55,6 +57,7 @@ __all__ = [
|
|
|
55
57
|
"SnapshotScopeResolver",
|
|
56
58
|
"DEFAULT_MAX_THREAD_SNAPSHOTS",
|
|
57
59
|
"DEFAULT_TAGS",
|
|
60
|
+
"state_carrier",
|
|
58
61
|
"state_update",
|
|
59
62
|
"__version__",
|
|
60
63
|
# A2UI (lazy — require ag-ui-a2ui-toolkit)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"""AgentFrameworkAgent wrapper for AG-UI protocol."""
|
|
4
4
|
|
|
5
|
+
import warnings
|
|
5
6
|
from collections.abc import AsyncGenerator
|
|
6
7
|
from typing import Any, cast
|
|
7
8
|
|
|
@@ -27,6 +28,8 @@ class AgentConfig:
|
|
|
27
28
|
snapshot_store: AGUIThreadSnapshotStore | None = None,
|
|
28
29
|
a2ui_config: dict[str, Any] | None = None,
|
|
29
30
|
service_session_id_from_thread_id: bool = False,
|
|
31
|
+
emit_messages_snapshot: bool = True,
|
|
32
|
+
legacy_session_id_from_thread_id: bool = False,
|
|
30
33
|
):
|
|
31
34
|
"""Initialize agent configuration.
|
|
32
35
|
|
|
@@ -45,6 +48,11 @@ class AgentConfig:
|
|
|
45
48
|
require_confirmation: Whether predictive updates require user confirmation before applying
|
|
46
49
|
a2ui_config: Optional backend A2UI config consumed by auto-injection
|
|
47
50
|
(``forwardedProps.injectA2UITool``). See ``plan_a2ui_injection``.
|
|
51
|
+
emit_messages_snapshot: Whether to emit a terminal MessagesSnapshotEvent at the end of runs.
|
|
52
|
+
Defaults to True for backward compatibility. Set to False when using HistoryProvider
|
|
53
|
+
to prevent redundant full-transcript rewrites on the client.
|
|
54
|
+
legacy_session_id_from_thread_id: Deprecated compatibility option that uses the client-owned
|
|
55
|
+
AG-UI Thread id directly as the internal Agent Session id.
|
|
48
56
|
"""
|
|
49
57
|
self.state_schema = self._normalize_state_schema(state_schema)
|
|
50
58
|
self.predict_state_config = predict_state_config or {}
|
|
@@ -53,6 +61,8 @@ class AgentConfig:
|
|
|
53
61
|
self.require_confirmation = require_confirmation
|
|
54
62
|
self.snapshot_store = snapshot_store
|
|
55
63
|
self.a2ui_config = a2ui_config
|
|
64
|
+
self.emit_messages_snapshot = emit_messages_snapshot
|
|
65
|
+
self.legacy_session_id_from_thread_id = legacy_session_id_from_thread_id
|
|
56
66
|
|
|
57
67
|
@staticmethod
|
|
58
68
|
def _normalize_state_schema(state_schema: Any | None) -> dict[str, Any]:
|
|
@@ -101,6 +111,8 @@ class AgentFrameworkAgent:
|
|
|
101
111
|
snapshot_store: AGUIThreadSnapshotStore | None = None,
|
|
102
112
|
a2ui_config: dict[str, Any] | None = None,
|
|
103
113
|
service_session_id_from_thread_id: bool = False,
|
|
114
|
+
emit_messages_snapshot: bool = True,
|
|
115
|
+
legacy_session_id_from_thread_id: bool = False,
|
|
104
116
|
):
|
|
105
117
|
"""Initialize the AG-UI compatible agent wrapper.
|
|
106
118
|
|
|
@@ -120,7 +132,21 @@ class AgentFrameworkAgent:
|
|
|
120
132
|
snapshot_store: Optional AG-UI Thread Snapshot store. Snapshot persistence remains inactive unless
|
|
121
133
|
endpoint setup also provides an explicit Snapshot Scope resolver.
|
|
122
134
|
a2ui_config: Optional backend A2UI config consumed by auto-injection.
|
|
135
|
+
emit_messages_snapshot: Whether to emit a terminal MessagesSnapshotEvent at the end of runs.
|
|
136
|
+
Defaults to True. Set to False when using HistoryProvider.
|
|
137
|
+
legacy_session_id_from_thread_id: Deprecated compatibility option that uses the client-owned
|
|
138
|
+
AG-UI Thread id directly as the internal Agent Session id. This disables Snapshot Scope
|
|
139
|
+
isolation for context-provider state.
|
|
123
140
|
"""
|
|
141
|
+
if legacy_session_id_from_thread_id:
|
|
142
|
+
warnings.warn(
|
|
143
|
+
"legacy_session_id_from_thread_id=True is deprecated because client-owned AG-UI Thread ids "
|
|
144
|
+
"do not isolate server-side state. Migrate provider state to scoped session ids and remove "
|
|
145
|
+
"this option.",
|
|
146
|
+
DeprecationWarning,
|
|
147
|
+
stacklevel=2,
|
|
148
|
+
)
|
|
149
|
+
|
|
124
150
|
self.agent = agent
|
|
125
151
|
self.name = name or getattr(agent, "name", "agent")
|
|
126
152
|
self.description = description or getattr(agent, "description", "")
|
|
@@ -133,6 +159,8 @@ class AgentFrameworkAgent:
|
|
|
133
159
|
require_confirmation=require_confirmation,
|
|
134
160
|
snapshot_store=snapshot_store,
|
|
135
161
|
a2ui_config=a2ui_config,
|
|
162
|
+
emit_messages_snapshot=emit_messages_snapshot,
|
|
163
|
+
legacy_session_id_from_thread_id=legacy_session_id_from_thread_id,
|
|
136
164
|
)
|
|
137
165
|
|
|
138
166
|
# Server-side Approval State. Populated when approval requests are emitted
|