mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
35a8565495
* Add AG-UI integration * Fix tests. PR feedback * Cleanup * PR Feedback * Improve README and getting started experience * Fix links
35a8565495
ยท
2025-11-05 05:25:24 +00:00
History
Agent Framework AG-UI Integration
AG-UI protocol integration for Agent Framework, enabling seamless integration with AG-UI's web interface and streaming protocol.
Installation
pip install agent-framework-ag-ui
Quick Start
from fastapi import FastAPI
from agent_framework import ChatAgent
from agent_framework.azure import AzureOpenAIChatClient
from agent_framework_ag_ui import add_agent_framework_fastapi_endpoint
# Create your agent
agent = ChatAgent(
name="my_agent",
instructions="You are a helpful assistant.",
chat_client=AzureOpenAIChatClient(model_id="gpt-4o"),
)
# Create FastAPI app and add AG-UI endpoint
app = FastAPI()
add_agent_framework_fastapi_endpoint(app, agent, "/agent")
# Run with: uvicorn main:app --reload
Features
This integration supports all 7 AG-UI features:
- Agentic Chat: Basic streaming chat with tool calling support
- Backend Tool Rendering: Tools executed on backend with results streamed via ToolCallResultEvent
- Human in the Loop: Function approval requests for user confirmation before tool execution
- Agentic Generative UI: Async tools for long-running operations with progress updates
- Tool-based Generative UI: Custom UI components rendered on frontend based on tool calls
- Shared State: Bidirectional state sync using StateSnapshotEvent and StateDeltaEvent
- Predictive State Updates: Stream tool arguments as optimistic state updates during execution
Examples
Complete examples for all features are in the examples/ directory:
examples/agents/simple_agent.py- Basic agentic chatexamples/agents/weather_agent.py- Backend tool renderingexamples/agents/task_planner_agent.py- Human in the loop with approvalsexamples/agents/research_assistant_agent.py- Agentic generative UIexamples/agents/ui_generator_agent.py- Tool-based generative UIexamples/agents/recipe_agent.py- Shared state managementexamples/agents/document_writer_agent.py- Predictive state updatesexamples/server/main.py- FastAPI server with all endpoints
Run the example server:
cd examples/server
uvicorn main:app --reload
To enable debug logging:
ENABLE_DEBUG_LOGGING=1 uvicorn main:app --reload
The server exposes endpoints at:
/agentic_chat/backend_tool_rendering/human_in_the_loop/agentic_generative_ui/tool_based_generative_ui/shared_state/predictive_state_updates
Architecture
The package uses a clean, orchestrator-based architecture:
- AgentFrameworkAgent: Lightweight wrapper that delegates to orchestrators
- Orchestrators: Handle different execution flows (default, human-in-the-loop, etc.)
- Confirmation Strategies: Domain-specific confirmation messages (extensible)
- AgentFrameworkEventBridge: Converts AgentRunResponseUpdate to AG-UI events
- Message Adapters: Bidirectional conversion between AG-UI and Agent Framework message formats
- FastAPI Endpoint: Streaming HTTP endpoint with Server-Sent Events (SSE)
Key Design Patterns
- Orchestrator Pattern: Separates flow control from protocol translation
- Strategy Pattern: Pluggable confirmation message strategies
- Context Object: Lazy-loaded execution context passed to orchestrators
- Event Bridge: Stateless translation of Agent Framework events to AG-UI events
Advanced Usage
Shared State
State is injected as system messages and updated via predictive state updates:
from agent_framework import ChatAgent
from agent_framework.azure import AzureOpenAIChatClient
from agent_framework_ag_ui import AgentFrameworkAgent
# Create your agent
agent = ChatAgent(
name="recipe_agent",
chat_client=AzureOpenAIChatClient(model_id="gpt-4o"),
)
state_schema = {
"recipe": {
"type": "object",
"properties": {
"name": {"type": "string"},
"ingredients": {"type": "array"}
}
}
}
# Configure which tool updates which state fields
predict_state_config = {
"recipe": {"tool": "update_recipe", "tool_argument": "recipe_data"}
}
wrapped_agent = AgentFrameworkAgent(
agent=agent,
state_schema=state_schema,
predict_state_config=predict_state_config,
)
Predictive State Updates
Predictive state updates automatically stream tool arguments as optimistic state updates:
from agent_framework import ChatAgent
from agent_framework.azure import AzureOpenAIChatClient
from agent_framework_ag_ui import AgentFrameworkAgent
# Create your agent
agent = ChatAgent(
name="document_writer",
chat_client=AzureOpenAIChatClient(model_id="gpt-4o"),
)
predict_state_config = {
"current_title": {"tool": "write_document", "tool_argument": "title"},
"current_content": {"tool": "write_document", "tool_argument": "content"},
}
wrapped_agent = AgentFrameworkAgent(
agent=agent,
state_schema={"current_title": {"type": "string"}, "current_content": {"type": "string"}},
predict_state_config=predict_state_config,
require_confirmation=True, # User can approve/reject changes
)
Custom Confirmation Strategies
Provide domain-specific confirmation messages:
from typing import Any
from agent_framework import ChatAgent
from agent_framework.azure import AzureOpenAIChatClient
from agent_framework_ag_ui import AgentFrameworkAgent, ConfirmationStrategy
class CustomConfirmationStrategy(ConfirmationStrategy):
def on_approval_accepted(self, steps: list[dict[str, Any]]) -> str:
return "Your custom approval message!"
def on_approval_rejected(self, steps: list[dict[str, Any]]) -> str:
return "Your custom rejection message!"
def on_state_confirmed(self) -> str:
return "State changes confirmed!"
def on_state_rejected(self) -> str:
return "State changes rejected!"
agent = ChatAgent(
name="custom_agent",
chat_client=AzureOpenAIChatClient(model_id="gpt-4o"),
)
wrapped_agent = AgentFrameworkAgent(
agent=agent,
confirmation_strategy=CustomConfirmationStrategy(),
)
Human in the Loop
Human-in-the-loop is automatically handled when tools are marked for approval:
from agent_framework import ai_function
@ai_function(approval_mode="always_require")
def sensitive_action(param: str) -> str:
"""This action requires user approval."""
return f"Executed with {param}"
# The orchestrator automatically detects approval responses and handles them
Custom Orchestrators
Add custom execution flows by implementing the Orchestrator pattern:
from agent_framework_ag_ui._orchestrators import Orchestrator, ExecutionContext
class MyCustomOrchestrator(Orchestrator):
def can_handle(self, context: ExecutionContext) -> bool:
# Return True if this orchestrator should handle the request
return context.input_data.get("custom_mode") == True
async def run(self, context: ExecutionContext):
# Custom execution logic
yield RunStartedEvent(...)
# ... your custom flow
yield RunFinishedEvent(...)
wrapped_agent = AgentFrameworkAgent(
agent=your_agent,
orchestrators=[MyCustomOrchestrator(), DefaultOrchestrator()],
)
## Documentation
For detailed documentation, see [DESIGN.md](DESIGN.md).
## License
MIT