更新会话状态、模型定义、订票工作流

This commit is contained in:
liubiren 2026-09-08 20:54:04 +08:00
parent d9622ab6b3
commit f4a26b74e6
3 changed files with 54 additions and 23 deletions

View File

@ -25,7 +25,7 @@ import reflex as rx
from application.states.database import DatabaseState
from application.states.models import (
AgentRunEvent,
AgentRunOutputEvent,
Conversation,
ConversationHistoryItem,
Message,
@ -461,8 +461,8 @@ class ConversationState(rx.State):
yield # 通知前端更新渲染
messages.append(message)
# ========== 智能体运行事件 ==========
case AgentRunEvent(content=content):
# ========== 智能体运行输出事件 ==========
case AgentRunOutputEvent(content=content):
# 构建消息实例
message = Message(
type=MessageType.TEXT,

View File

@ -11,7 +11,6 @@ from pydantic_ai import RunUsage
from pydantic_ai._uuid import uuid7
class NoResult(BaseModel):
"""
无结果类
@ -19,15 +18,35 @@ class NoResult(BaseModel):
...
class AgentRunEvent(BaseModel):
class InteractionType(StrEnum):
"""
智能体运行事件类
交互类型枚举
"""
INPUT = "input"
class Approval(BaseModel):
"""
审批类
"""
tool_call_id: str = Field(..., description="工具调用唯一标识")
tool_name: str = Field(..., description="工具名称")
interaction_type: InteractionType = Field(..., description="交互类型")
class AgentRunOutputEvent(BaseModel):
"""
智能体运行输出事件类
"""
content: str = Field(
default="",
description="智能体运行内容",
)
approvals: list[Approval] = Field(default_factory=list, description="审批列表")
class MessageType(StrEnum):

View File

@ -3,9 +3,8 @@
预定航班工作流范式
"""
import datetime
from re import I
from typing import AsyncGenerator, cast, Any
from dataclasses import replace
from typing import Any, AsyncGenerator, cast
from pydantic import BaseModel, Field, field_validator
from pydantic_ai import (
Agent,
@ -18,7 +17,6 @@ from pydantic_ai import (
RunUsage,
UsageLimits,
)
from pydantic_ai.agent.abstract import S
from pydantic_ai.messages import (
AgentStreamEvent,
FunctionToolResultEvent,
@ -27,9 +25,13 @@ from pydantic_ai.messages import (
ToolReturnPart,
)
from pydantic_ai.run import AgentRunResult, AgentRunResultEvent
from reflex.event import T
from application.states.models import AgentRunEvent, NoResult
from application.states.models import (
AgentRunOutputEvent,
NoResult,
InteractionType,
Approval,
)
from application.workshop.models import (
DEEPSEEK_V4_FLASH_MODEL,
DEEPSEEK_V4_FLASH_MODEL_SETTINGS,
@ -204,7 +206,10 @@ async def search_flights(ctx: RunContext[Deps]) -> list[Flight]:
return searched_flights
@agent.tool(name="预定航班")
@agent.tool(
name="预定航班",
requires_approval=True,
)
async def book_flight(ctx: RunContext[Deps]) -> Flight | NoResult:
"""
预定航班
@ -212,9 +217,6 @@ async def book_flight(ctx: RunContext[Deps]) -> Flight | NoResult:
if (searched_flights := ctx.deps.searched_flights) is None:
raise ModelRetry("必须先使用 search_flights 查询航班")
if not ctx.tool_call_approved:
raise ApprovalRequired(metadata={"content": "您要预定哪班航班?"})
# 提取到的航班号
extracted_flight_number = (
await extraction_flight_number_agent.run(
@ -282,7 +284,7 @@ async def run_stream_events(
) -> AsyncGenerator[
AgentStreamEvent
| AgentRunResultEvent[Flight | NoResult | DeferredToolRequests]
| AgentRunEvent
| AgentRunOutputEvent
| None,
]:
"""
@ -330,7 +332,6 @@ async def run_stream_events(
event.part.content = (
"未提取到航班号,请检查后重试"
)
if isinstance(content, Flight):
event.part.content = f"已预定航班:\n{content.number} {content.airfare}$ 于 {content.date.strftime('%Y-%m-%d')}{content.origin_airport_code}{content.destination_airport_code}\n"
yield event
@ -341,9 +342,20 @@ async def run_stream_events(
match result:
case AgentRunResult(output=output):
match output:
case Flight():
yield AgentRunEvent(content="预定成功")
case Flight() | NoResult():
yield event
case DeferredToolRequests(approvals=approvals) as t:
t.metadata = {"1": {"Success": "1"}}
yield event
case DeferredToolRequests(approvals=approvals):
yield AgentRunOutputEvent(
content="请输入航班号",
approvals=[
Approval(
tool_call_id=approval.tool_call_id,
tool_name=approval.tool_name,
interaction_type=InteractionType.INPUT,
)
for approval in approvals
if approval.tool_name == "预定航班"
],
)
yield event