forked from trpc-group/trpc-agent-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path_agui_runner.py
More file actions
138 lines (112 loc) · 4.38 KB
/
Copy path_agui_runner.py
File metadata and controls
138 lines (112 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
#
# Copyright (C) 2026 Tencent. All rights reserved.
#
# tRPC-Agent-Python is licensed under Apache-2.0.
"""Runner manager: owns the AG-UI manager for the FastAPI server.
"""
from contextlib import asynccontextmanager
from typing import Any
from ag_ui.core import RunAgentInput
from fastapi import FastAPI
from pydantic import BaseModel
from trpc_agent_sdk.agents import BaseAgent
from trpc_agent_sdk.log import logger
from trpc_agent_sdk.server.ag_ui import AgUiAgent
from trpc_agent_sdk.server.ag_ui import AgUiManager
from trpc_agent_sdk.server.ag_ui import AgUiService
from trpc_agent_sdk.server.ag_ui import AgUiUserFeedBack
def get_agui_user_id(input: RunAgentInput):
"""Extract user_id from input if available."""
return "user_123"
async def user_feedback_handler(feedback: AgUiUserFeedBack):
"""Handle user feedback in Human-In-The-Loop scenarios."""
logger.info(f"User Feedback Received:")
logger.info(f" Tool: {feedback.tool_name}")
logger.info(f" Message: {feedback.tool_message}")
class HealthResponse(BaseModel):
"""Response body for GET /health."""
status: str = "ok"
app_name: str
version: str = "1.0.0"
class AguiRunner:
"""AG-UI runner: owns the AG-UI manager for the FastAPI server."""
def __init__(
self,
app_name: str,
) -> None:
self._app_name = app_name
self._agui_manager = AgUiManager()
self._app = self._create_app()
@property
def app(self) -> FastAPI:
"""Get the FastAPI app for the AG-UI runner."""
return self._app
def register_service(self, service_name: str, service: AgUiService) -> None:
"""Register an AG-UI service.
Args:
service_name: The name of the service.
service: The AG-UI service to register.
"""
self._agui_manager.register_service(service_name, service)
def run(self, host: str, port: int, **kwargs: Any) -> None:
"""Run the AG-UI runner.
Args:
host: The host to run the AG-UI runner on.
port: The port to run the AG-UI runner on.
kwargs: Additional keyword arguments to pass to the uvicorn server.
"""
self._app.get("/health", response_model=HealthResponse, tags=["meta"])(self.health)
self._agui_manager.set_app(self._app)
self._agui_manager.run(host, port, **kwargs)
@asynccontextmanager
async def _lifespan(self, app: FastAPI): # noqa: ARG001
"""Startup / shutdown hook: close the runner on exit."""
logger.info("TRPC AG-UI Server starting up.")
yield
logger.info("TRPC AG-UI Server shutting down.")
await self._agui_manager.close()
def _create_app(self) -> FastAPI:
app = FastAPI(
title="TRPC AG-UI Server",
description="HTTP API for TRPC AG-UI Server",
version="1.0.0",
lifespan=self._lifespan,
)
return app
async def health(self) -> HealthResponse:
"""Liveness check - always returns 200 while the server is up."""
return HealthResponse(app_name=self._app_name)
def _create_agui_agent(name: str, root_agent: BaseAgent, **kwargs) -> AgUiAgent:
"""Create AgUiAgent in tRPC framework worker process.
Args:
name: Name of the agent
root_agent: Root agent instance
Returns:
AgUiAgent instance
"""
agui_agent = AgUiAgent(
trpc_agent=root_agent,
app_name=name,
**kwargs,
# user_feedback_handler=user_feedback_handler,
# app_name_extractor=get_agui_user_id,
# user_id_extractor=xxx,
)
return agui_agent
def create_agui_runner(app_name: str, service_name: str, uri: str, **kwargs: Any) -> AguiRunner:
"""Create AgUiService and add agent to it.
Args:
app_name: Name of the app
service_name: Name of the service
uri: URI of the agent
kwargs: Additional keyword arguments to pass to the AgUiAgent constructor
Returns:
AguiRunner instance
"""
ag_ui_runner: AguiRunner = AguiRunner(app_name)
agui_service = AgUiService(service_name, app=ag_ui_runner.app)
agui_agent = _create_agui_agent(app_name, **kwargs)
agui_service.add_agent(uri, agui_agent)
ag_ui_runner.register_service(service_name, agui_service)
return ag_ui_runner