Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7146820
Python: A2UI (Agent-to-UI) support for the AG-UI adapter
ranst91 Jul 30, 2026
25763de
Python: A2UI review feedback — declarative wiring, no agent swap
ranst91 Aug 4, 2026
4f9e403
Python: A2UI review round 2 — mixed-batch pipeline, client tools, sna…
ranst91 Aug 5, 2026
e063a25
Python: A2UI review round 2 — fold context wrapper, typed runner
ranst91 Aug 5, 2026
c0d3432
Python: A2UI — bridge test for client tool + generate_a2ui in one turn
ranst91 Aug 5, 2026
31c7144
Merge branch 'main' into feat/a2ui-python-finish
moonbox3 Aug 12, 2026
6062c9e
Python: A2UI review round 3 — manual-path delegation, per-request con…
ranst91 Aug 12, 2026
b0461d5
Python: A2UI review round 3 — mixed-batch reuses the core invocation …
ranst91 Aug 13, 2026
2fbe0fc
Merge remote-tracking branch 'upstream/main' into feat/a2ui-python-fi…
ranst91 Aug 14, 2026
7042363
Python: A2UI review round 4 — core batch executor, budget/iteration p…
ranst91 Aug 14, 2026
99015e6
Merge branch 'main' into feat/a2ui-python-finish
moonbox3 Aug 18, 2026
a1f173c
Python: A2UI review round 5 — force tools off on the final narration …
ranst91 Aug 18, 2026
e96b669
Python: A2UI review round 5 — move the budget lifecycle into a core o…
ranst91 Aug 18, 2026
4c10e58
Python: A2UI review round 5 follow-up — keep budgeting local, narrate…
ranst91 Aug 19, 2026
2555e6c
Python: A2UI — feed the current surface to the budget-exhausted final…
ranst91 Aug 19, 2026
0a3c2aa
Merge remote-tracking branch 'upstream/main' into feat/a2ui-python-fi…
ranst91 Aug 19, 2026
5b47bb0
Python: A2UI — keep batch execution in the adapter; fix CI typing
ranst91 Aug 20, 2026
a5462ab
Python: A2UI — propagate MiddlewareFailure through the inline server-…
ranst91 Aug 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions python/packages/ag-ui/agent_framework_ag_ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""AG-UI protocol integration for Agent Framework."""

import importlib.metadata
from typing import TYPE_CHECKING, Any

from ._agent import AgentFrameworkAgent
from ._client import AGUIChatClient
Expand All @@ -22,6 +23,9 @@
from ._types import AgentState, AGUIChatOptions, AGUIRequest, PredictStateConfig, RunMetadata
from ._workflow import AgentFrameworkWorkflow, WorkflowFactory

if TYPE_CHECKING:
from ._a2ui import A2UIAgent, enable_a2ui, plan_a2ui_injection

try:
__version__ = importlib.metadata.version(__name__)
except importlib.metadata.PackageNotFoundError:
Expand Down Expand Up @@ -53,4 +57,20 @@
"DEFAULT_TAGS",
"state_update",
"__version__",
# A2UI (lazy — require ag-ui-a2ui-toolkit)
"A2UIAgent",
"enable_a2ui",
"plan_a2ui_injection",
]

# A2UI symbols are loaded lazily so importing this package does not require
# ag-ui-a2ui-toolkit unless A2UI is actually used.
_A2UI_LAZY = {"A2UIAgent", "enable_a2ui", "plan_a2ui_injection"}


def __getattr__(name: str) -> Any:
if name in _A2UI_LAZY:
import importlib

return getattr(importlib.import_module("._a2ui", __name__), name)
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
50 changes: 50 additions & 0 deletions python/packages/ag-ui/agent_framework_ag_ui/_a2ui/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright (c) Microsoft. All rights reserved.

"""A2UI (agent-generated UI) support for the AG-UI Agent Framework adapter.

Toolkit-dependent exports (``A2UIAgent`` / ``enable_a2ui`` / ``plan_a2ui_injection`` /
``is_a2ui_runner``) are loaded lazily via PEP 562 so this package — and the toolkit-free
context-plumbing helpers in :mod:`._state` it re-exports — can be imported by the hosting
loop even when ``ag-ui-a2ui-toolkit`` is not installed.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

# Toolkit-free helpers — safe to import eagerly (no ag_ui_a2ui_toolkit dependency).
from ._state import (
A2UI_SCHEMA_CONTEXT_DESCRIPTION,
build_ag_ui_context_slice,
read_inject_a2ui_flag,
)

if TYPE_CHECKING:
from ._agent import A2UIAgent
from ._factory import enable_a2ui, is_a2ui_runner, plan_a2ui_injection

__all__ = [
"A2UI_SCHEMA_CONTEXT_DESCRIPTION",
"A2UIAgent",
"build_ag_ui_context_slice",
"enable_a2ui",
"is_a2ui_runner",
"plan_a2ui_injection",
"read_inject_a2ui_flag",
]

# Lazy (toolkit-dependent) exports: module -> symbols defined there.
_LAZY: dict[str, tuple[str, ...]] = {
"_agent": ("A2UIAgent",),
"_factory": ("enable_a2ui", "is_a2ui_runner", "plan_a2ui_injection"),
}


def __getattr__(name: str) -> Any:
for module, symbols in _LAZY.items():
if name in symbols:
import importlib

mod = importlib.import_module(f".{module}", __name__)
return getattr(mod, name)
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
Loading
Loading