260603更新

This commit is contained in:
liubiren 2026-06-03 00:36:07 +08:00
parent 5129459d47
commit 48e08eebb8
3 changed files with 46 additions and 45 deletions

Binary file not shown.

View File

View File

@ -6,31 +6,32 @@
# 列举导入模块
from pathlib import Path
from sys import path
from typing import List, Optional, cast
from typing import List, Optional, Union, cast
from typing import TypeVar
from uuid import uuid4
from mistralai.client.models import Op
from pydantic_ai import Agent as BaseAgent, AgentRunResult
from pydantic_ai.builtin_tools import AbstractBuiltinTool
from pydantic_ai.capabilities import AgentCapability
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.native_tools import AbstractNativeTool
from pydantic_ai.output import OutputSpec
from pydantic_ai.providers.openai import OpenAIProvider
from pydantic_ai.settings import ModelSettings
from pydantic_core.core_schema import is_subclass_schema
from starlette.applications import Starlette
from starlette.routing import Mount, Route
from typing_extensions import is_protocol
from memory import Memory
path.append(Path(__file__).resolve().parent.as_posix())
from memory import Memory
AgentDepsT = TypeVar("AgentDepsT")
OutputDataT = TypeVar("OutputDataT")
class Agent:
"""
智能体支持
1实例智能体
2异步运行
1 实例智能体
2 异步运行
"""
def __init__(
@ -108,23 +109,25 @@ class Agent:
def create_web_application(
self,
builtin_tools: Optional[List[AbstractBuiltinTool]] = None,
native_tools: Optional[List[AbstractNativeTool]] = None,
html_source: Optional[Union[str, Path]] = None,
) -> Starlette:
"""
创建 Starlette 应用为智能体提供交互式对话界面
:param builtin_tools: 前端可选工具列表
:param native_tools: 前端可选工具列表
:return: Starlette 实例
"""
from starlette.requests import Request
from starlette.responses import JSONResponse, HTMLResponse, Response
def api(
self,
builtin_tools: Optional[List[AbstractBuiltinTool]] = None,
agent: BaseAgent[AgentDepsT, OutputDataT],
native_tools: Optional[List[AbstractNativeTool]] = None,
) -> Starlette:
"""
创建 API 应用
:param builtin_tools: 前端可选工具列表
创建处理请求应用
:param agnet: 智能体
:param native_tools: 前端可选原生工具列表
:return: Starlette 实例
"""
from pydantic_ai.models import Model
@ -136,26 +139,25 @@ class Agent:
validate_request_options,
)
from pydantic_ai.ui.vercel_ai import VercelAIAdapter
from typing import TypeVar
from pydantic_ai.capabilities import NativeTool
agent_model = cast(Model, self.agent.model)
async def options(request: Request) -> Response:
"""处理跨域预检请求"""
return Response()
# 前端可选工具列表
frontend_builtin_tools = [
agent_model = cast(Model, agent.model)
# 前端可选原生工具列表
frontend_native_tools = [
t
for t in (builtin_tools or [])
for t in (native_tools or [])
if t.unique_id
not in {
t.unique_id
for t in self.agent._cap_builtin_tools
if isinstance(t, AbstractBuiltinTool)
for t in agent._cap_native_tools
if isinstance(t, AbstractNativeTool)
}
]
async def options_chat(request: Request) -> Response:
"""处理跨域预检请求"""
return Response()
async def configurations(request: Request) -> Response:
"""处理前端模型与工具配置请求"""
configurations = ConfigureFrontend(
@ -165,14 +167,14 @@ class Agent:
name=agent_model.label,
builtin_tools=[
t.unique_id
for t in frontend_builtin_tools
if type(t) in agent_model.supported_builtin_tools()
for t in frontend_native_tools
if type(t) in agent_model.profile.supported_native_tools
],
)
], # 前端仅可选择智能体配置的模型
], # 前端仅可选择智能体配置的模型
builtin_tools=[
BuiltinToolInfo(id=t.unique_id, name=t.label)
for t in frontend_builtin_tools
for t in frontend_native_tools
],
)
return JSONResponse(content=configurations.model_dump(by_alias=True))
@ -184,14 +186,14 @@ class Agent:
TypeVar("AgentDepsT"), TypeVar("OutputDataT")
].from_request(request=request, agent=self.agent)
# 解析请求中额外数据,包括前端选择的模型标识、工具标识和其它配置等
# 解析请求中额外数据,包括前端选择的模型标识、原生工具标识和其它配置等
extra_data = ChatRequestExtra.model_validate(
adapter.run_input.__pydantic_extra__
)
if error := validate_request_options(
extra_data=extra_data,
model_ids={agent_model.model_id}, # 前端仅可选择智能体配置的模型
builtin_tool_ids={t.unique_id for t in frontend_builtin_tools},
model_ids={agent_model.model_id}, # 前端仅可选择智能体配置的模型
builtin_tool_ids={t.unique_id for t in frontend_native_tools},
):
return JSONResponse(content={"error": error}, status_code=400)
@ -200,9 +202,9 @@ class Agent:
].dispatch_request(
request=request,
agent=self.agent,
builtin_tools=[
t
for t in frontend_builtin_tools
capabilities=[
NativeTool(t)
for t in frontend_native_tools
if t.unique_id in extra_data.builtin_tools
],
)
@ -214,15 +216,17 @@ class Agent:
return Starlette(
routes=[
Route("/chat", options, methods=["OPTIONS"]),
Route("/configure", configurations, methods=["GET"]),
Route("/chat", options_chat, methods=["OPTIONS"]),
Route("/chat", chat, methods=["POST"]),
Route("/health", health, methods=["GET"]),
]
)
async def ui(request: Request) -> Response:
"""Serve the chat UI from filesystem cache or CDN."""
async def index(request: Request) -> Response:
"""S处理聊天界面请求"""
from pydantic_ai.ui._web.app import _get_ui_html
content = await _get_ui_html(html_source)
return HTMLResponse(
@ -236,14 +240,11 @@ class Agent:
routes=[
Mount(
"/api",
app=api(self, builtin_tools=builtin_tools),
app=api(agent=self.agent, native_tools=native_tools),
)
]
)
app.router.add_route("/", ui, methods=["GET"])
app.router.add_route("/{id}", ui, methods=["GET"])
exit()
application.router.add_route("/", index, methods=["GET"])
application.router.add_route("/{id}", index, methods=["GET"])
return application