更新会话状态、模型定义、订票工作流
This commit is contained in:
parent
d9622ab6b3
commit
f4a26b74e6
|
|
@ -25,7 +25,7 @@ import reflex as rx
|
||||||
|
|
||||||
from application.states.database import DatabaseState
|
from application.states.database import DatabaseState
|
||||||
from application.states.models import (
|
from application.states.models import (
|
||||||
AgentRunEvent,
|
AgentRunOutputEvent,
|
||||||
Conversation,
|
Conversation,
|
||||||
ConversationHistoryItem,
|
ConversationHistoryItem,
|
||||||
Message,
|
Message,
|
||||||
|
|
@ -461,8 +461,8 @@ class ConversationState(rx.State):
|
||||||
yield # 通知前端更新渲染
|
yield # 通知前端更新渲染
|
||||||
messages.append(message)
|
messages.append(message)
|
||||||
|
|
||||||
# ========== 智能体运行事件 ==========
|
# ========== 智能体运行输出事件 ==========
|
||||||
case AgentRunEvent(content=content):
|
case AgentRunOutputEvent(content=content):
|
||||||
# 构建消息实例
|
# 构建消息实例
|
||||||
message = Message(
|
message = Message(
|
||||||
type=MessageType.TEXT,
|
type=MessageType.TEXT,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ from pydantic_ai import RunUsage
|
||||||
from pydantic_ai._uuid import uuid7
|
from pydantic_ai._uuid import uuid7
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class NoResult(BaseModel):
|
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(
|
content: str = Field(
|
||||||
default="",
|
default="",
|
||||||
description="智能体运行内容",
|
description="智能体运行内容",
|
||||||
)
|
)
|
||||||
|
approvals: list[Approval] = Field(default_factory=list, description="审批列表")
|
||||||
|
|
||||||
|
|
||||||
class MessageType(StrEnum):
|
class MessageType(StrEnum):
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@
|
||||||
预定航班工作流(范式)
|
预定航班工作流(范式)
|
||||||
"""
|
"""
|
||||||
import datetime
|
import datetime
|
||||||
from re import I
|
from typing import Any, AsyncGenerator, cast
|
||||||
from typing import AsyncGenerator, cast, Any
|
|
||||||
from dataclasses import replace
|
|
||||||
from pydantic import BaseModel, Field, field_validator
|
from pydantic import BaseModel, Field, field_validator
|
||||||
from pydantic_ai import (
|
from pydantic_ai import (
|
||||||
Agent,
|
Agent,
|
||||||
|
|
@ -18,7 +17,6 @@ from pydantic_ai import (
|
||||||
RunUsage,
|
RunUsage,
|
||||||
UsageLimits,
|
UsageLimits,
|
||||||
)
|
)
|
||||||
from pydantic_ai.agent.abstract import S
|
|
||||||
from pydantic_ai.messages import (
|
from pydantic_ai.messages import (
|
||||||
AgentStreamEvent,
|
AgentStreamEvent,
|
||||||
FunctionToolResultEvent,
|
FunctionToolResultEvent,
|
||||||
|
|
@ -27,9 +25,13 @@ from pydantic_ai.messages import (
|
||||||
ToolReturnPart,
|
ToolReturnPart,
|
||||||
)
|
)
|
||||||
from pydantic_ai.run import AgentRunResult, AgentRunResultEvent
|
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 (
|
from application.workshop.models import (
|
||||||
DEEPSEEK_V4_FLASH_MODEL,
|
DEEPSEEK_V4_FLASH_MODEL,
|
||||||
DEEPSEEK_V4_FLASH_MODEL_SETTINGS,
|
DEEPSEEK_V4_FLASH_MODEL_SETTINGS,
|
||||||
|
|
@ -204,7 +206,10 @@ async def search_flights(ctx: RunContext[Deps]) -> list[Flight]:
|
||||||
return searched_flights
|
return searched_flights
|
||||||
|
|
||||||
|
|
||||||
@agent.tool(name="预定航班")
|
@agent.tool(
|
||||||
|
name="预定航班",
|
||||||
|
requires_approval=True,
|
||||||
|
)
|
||||||
async def book_flight(ctx: RunContext[Deps]) -> Flight | NoResult:
|
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:
|
if (searched_flights := ctx.deps.searched_flights) is None:
|
||||||
raise ModelRetry("必须先使用 search_flights 查询航班")
|
raise ModelRetry("必须先使用 search_flights 查询航班")
|
||||||
|
|
||||||
if not ctx.tool_call_approved:
|
|
||||||
raise ApprovalRequired(metadata={"content": "您要预定哪班航班?"})
|
|
||||||
|
|
||||||
# 提取到的航班号
|
# 提取到的航班号
|
||||||
extracted_flight_number = (
|
extracted_flight_number = (
|
||||||
await extraction_flight_number_agent.run(
|
await extraction_flight_number_agent.run(
|
||||||
|
|
@ -282,7 +284,7 @@ async def run_stream_events(
|
||||||
) -> AsyncGenerator[
|
) -> AsyncGenerator[
|
||||||
AgentStreamEvent
|
AgentStreamEvent
|
||||||
| AgentRunResultEvent[Flight | NoResult | DeferredToolRequests]
|
| AgentRunResultEvent[Flight | NoResult | DeferredToolRequests]
|
||||||
| AgentRunEvent
|
| AgentRunOutputEvent
|
||||||
| None,
|
| None,
|
||||||
]:
|
]:
|
||||||
"""
|
"""
|
||||||
|
|
@ -330,7 +332,6 @@ async def run_stream_events(
|
||||||
event.part.content = (
|
event.part.content = (
|
||||||
"未提取到航班号,请检查后重试"
|
"未提取到航班号,请检查后重试"
|
||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(content, Flight):
|
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"
|
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
|
yield event
|
||||||
|
|
@ -341,9 +342,20 @@ async def run_stream_events(
|
||||||
match result:
|
match result:
|
||||||
case AgentRunResult(output=output):
|
case AgentRunResult(output=output):
|
||||||
match output:
|
match output:
|
||||||
case Flight():
|
case Flight() | NoResult():
|
||||||
yield AgentRunEvent(content="预定成功")
|
yield event
|
||||||
|
|
||||||
case DeferredToolRequests(approvals=approvals) as t:
|
case DeferredToolRequests(approvals=approvals):
|
||||||
t.metadata = {"1": {"Success": "1"}}
|
yield AgentRunOutputEvent(
|
||||||
yield event
|
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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue