This commit is contained in:
parent
8c8fda3da6
commit
55aa7e30e9
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from application.pages.conversation import conversation
|
||||
from application.pages.knowledge_base import knowledge_base
|
||||
from application.pages.conversation import conversation_page
|
||||
from application.pages.knowledge_base import knowledge_base_page
|
||||
|
||||
|
||||
__all__ = ["conversation", "knowledge_base"]
|
||||
__all__ = ["conversation_page", "knowledge_base_page"]
|
||||
|
|
|
|||
|
|
@ -9,32 +9,32 @@ from application.states.models import (
|
|||
Conversation,
|
||||
Dialog,
|
||||
Thought,
|
||||
ConversationHistoryItem,
|
||||
)
|
||||
from application.states import ConversationState, AuthState
|
||||
|
||||
|
||||
def conversation_history_item(
|
||||
item: Tuple[str, Conversation],
|
||||
item: ConversationHistoryItem,
|
||||
) -> rx.Component:
|
||||
"""
|
||||
会话历史项
|
||||
:param item: 会话历史项
|
||||
:return: Component
|
||||
"""
|
||||
conversation = item[1]
|
||||
|
||||
# 高亮:若为当前会话或显示更多则高亮
|
||||
highlight: bool = (
|
||||
conversation.id
|
||||
== ConversationState.is_conversation_history_item_more_button_shown
|
||||
) | (conversation.id == ConversationState.conversation_id)
|
||||
# 高亮
|
||||
is_highlight = item.id in (
|
||||
ConversationState.is_conversation_history_item_popover_shown,
|
||||
ConversationState.actived_conversation_id,
|
||||
)
|
||||
|
||||
return rx.list.item(
|
||||
rx.vstack(
|
||||
rx.hstack(
|
||||
# 对话描述
|
||||
rx.text(
|
||||
conversation.description,
|
||||
item.description,
|
||||
flex=1,
|
||||
height="22px",
|
||||
line_height="22px",
|
||||
|
|
@ -53,7 +53,7 @@ def conversation_history_item(
|
|||
rx.spacer(),
|
||||
# 创建时间
|
||||
rx.text(
|
||||
conversation.created_at,
|
||||
item.created_at,
|
||||
line_height="20px",
|
||||
font_size="var(--prismui-font-size-1)",
|
||||
color="var(--prismui-color-8)",
|
||||
|
|
@ -64,8 +64,8 @@ def conversation_history_item(
|
|||
height="20px",
|
||||
margin_bottom="8px",
|
||||
),
|
||||
# 点击事件:切换会话
|
||||
on_click=lambda: ConversationState.switch_conversation(conversation.id),
|
||||
# 点击事件:设置激活会话
|
||||
on_click=lambda: ConversationState.set_actived_conversation(item.id),
|
||||
width="100%",
|
||||
),
|
||||
# 更多按钮:点击更多按钮显示气泡卡片,可删除会话
|
||||
|
|
@ -98,7 +98,7 @@ def conversation_history_item(
|
|||
"删除",
|
||||
# 点击事件:删除对话
|
||||
on_click=lambda: ConversationState.delete_conversation(
|
||||
conversation.id
|
||||
item.id
|
||||
),
|
||||
display="flex",
|
||||
align_items="center",
|
||||
|
|
@ -130,8 +130,9 @@ def conversation_history_item(
|
|||
box_shadow="var(--prismui-box-shadow-6)",
|
||||
overflow="visible",
|
||||
),
|
||||
on_open_change=lambda is_shown: ConversationState.set_shown_more_conversation_id(
|
||||
conversation.id, is_shown
|
||||
# 悬停气泡显示 / 隐藏变化事件:设置会话历史项悬停气泡显示 / 隐藏
|
||||
on_open_change=lambda is_shown: ConversationState.set_conversation_history_item_popover_shown(
|
||||
item.id, is_shown
|
||||
),
|
||||
open_delay=0,
|
||||
),
|
||||
|
|
@ -227,9 +228,9 @@ def conversation_history(
|
|||
)
|
||||
|
||||
|
||||
def greeting_showing() -> rx.Component:
|
||||
def guidance() -> rx.Component:
|
||||
"""
|
||||
欢迎展示
|
||||
引导
|
||||
:return: Component
|
||||
"""
|
||||
return rx.vstack(
|
||||
|
|
@ -360,9 +361,9 @@ def thought_showing(item: Tuple[int, Thought]):
|
|||
)
|
||||
|
||||
|
||||
def dialog_showing(item: Tuple[str, Dialog]) -> rx.Component:
|
||||
def message_history_item(item: Tuple[str, Dialog]) -> rx.Component:
|
||||
"""
|
||||
对话展示
|
||||
消息历史项
|
||||
:param item: 对话实例
|
||||
:return: Component
|
||||
"""
|
||||
|
|
@ -612,42 +613,42 @@ def dialog_showing(item: Tuple[str, Dialog]) -> rx.Component:
|
|||
)
|
||||
|
||||
|
||||
def dialog_items_showing() -> rx.Component:
|
||||
def message_history() -> rx.Component:
|
||||
"""
|
||||
对话项列表展示
|
||||
消息历史
|
||||
:return: Component
|
||||
"""
|
||||
|
||||
# 当前会话的对话列表
|
||||
dialogs = ConversationState.dialogs
|
||||
# 若对话列表为空则显示欢迎,否则显示对话列表
|
||||
return rx.cond(
|
||||
dialogs.length() == 0,
|
||||
# 欢迎展示
|
||||
greeting_showing(),
|
||||
rx.vstack(
|
||||
rx.auto_scroll(
|
||||
rx.foreach(
|
||||
dialogs,
|
||||
dialog_showing,
|
||||
),
|
||||
width="100%",
|
||||
padding="0 12px",
|
||||
padding_bottom="180px",
|
||||
style={
|
||||
"&::-webkit-scrollbar": {
|
||||
"display": "none",
|
||||
# 消息历史
|
||||
message_history = ConversationState.message_history
|
||||
return rx.box(
|
||||
# 若消息历史为空则显示引导,否则渲染消息历史项
|
||||
rx.cond(
|
||||
message_history.length() == 0,
|
||||
guidance(),
|
||||
rx.vstack(
|
||||
rx.auto_scroll(
|
||||
rx.foreach(
|
||||
message_history,
|
||||
message_history_item,
|
||||
),
|
||||
width="100%",
|
||||
padding="0 12px",
|
||||
padding_bottom="180px",
|
||||
style={
|
||||
"&::-webkit-scrollbar": {
|
||||
"display": "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
flex="1",
|
||||
width="100%",
|
||||
max_width="1200px",
|
||||
margin_x="auto",
|
||||
padding_top="20px",
|
||||
justify_content="flex-start",
|
||||
overflow_x="hidden",
|
||||
overflow_y="auto",
|
||||
),
|
||||
flex="1",
|
||||
width="100%",
|
||||
max_width="1200px",
|
||||
margin_x="auto",
|
||||
padding_top="20px",
|
||||
justify_content="flex-start",
|
||||
overflow_x="hidden",
|
||||
overflow_y="auto",
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -723,7 +724,7 @@ def user_prompt_sending() -> rx.Component:
|
|||
conversation_creating(),
|
||||
rx.vstack(
|
||||
rx.text_area(
|
||||
# 值绑定用户提示词
|
||||
# 值绑定:用户提示词
|
||||
value=ConversationState.user_prompt,
|
||||
# 输入事件:设置用户提示词
|
||||
on_change=ConversationState.set_user_prompt,
|
||||
|
|
@ -867,7 +868,7 @@ def conversation_history_collapse_button(
|
|||
|
||||
def conversation_page() -> rx.Component:
|
||||
"""
|
||||
会话页面:布局参考 MetaChat,从左到右分别为会话历史和工作区。其中,工作区从上到下分别为对话历史和用户提示词输入框。
|
||||
会话页面:布局参考 MetaChat,从左到右分别为会话历史和工作区。其中,工作区从上到下分别为消息历史和用户提示词输入框。
|
||||
"""
|
||||
# 会话历史展示状态
|
||||
is_shown = ConversationState.is_conversation_history_shown
|
||||
|
|
@ -880,7 +881,7 @@ def conversation_page() -> rx.Component:
|
|||
rx.box(
|
||||
# 对话历史
|
||||
rx.vstack(
|
||||
dialog_history(),
|
||||
message_history(),
|
||||
width="100%",
|
||||
height="100%",
|
||||
gap="8px",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"""
|
||||
import reflex as rx
|
||||
|
||||
from application.pages import conversation, knowledge_base
|
||||
from application.pages import conversation_page, knowledge_base_page
|
||||
from application.states import AuthState
|
||||
|
||||
|
||||
|
|
@ -434,13 +434,13 @@ def index() -> rx.Component:
|
|||
rx.hstack(
|
||||
# 侧边栏
|
||||
sidebar(),
|
||||
# 根据侧边栏状态中激活的导航按钮相应页面(本项目采用卡片布局)
|
||||
# 根据侧边栏状态中激活的导航按钮相应页面
|
||||
rx.match(
|
||||
AuthState.activated_nav_button,
|
||||
# 知识库页面
|
||||
("knowledge_base", knowledge_base()),
|
||||
("knowledge_base", knowledge_base_page()),
|
||||
# 会话页面
|
||||
conversation(),
|
||||
conversation_page(),
|
||||
),
|
||||
width="100%",
|
||||
height="100vh",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
import reflex as rx
|
||||
|
||||
|
||||
def knowledge_base() -> rx.Component:
|
||||
def knowledge_base_page() -> rx.Component:
|
||||
"""
|
||||
知识库页面
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ class ConversationState(rx.State):
|
|||
|
||||
# 显示会话历史,True 表示显示,False 表示隐藏
|
||||
is_conversation_history_shown: bool = False
|
||||
# 会话历史项显示悬停气泡,True 表示显示,False 表示隐藏
|
||||
is_conversation_history_item_popover_shown: bool = False
|
||||
# 会话历史项显示悬停气泡
|
||||
is_conversation_history_item_popover_shown: str = ""
|
||||
|
||||
# 当前数据库状态(私有变量)
|
||||
# 私有变量:reflex 约定以 _ 开头的变量为私有变量,后端不序列化,前端不可使用
|
||||
|
|
@ -121,6 +121,7 @@ class ConversationState(rx.State):
|
|||
"""
|
||||
return [
|
||||
ConversationHistoryItem(
|
||||
id=conversation.id,
|
||||
description=conversation.description,
|
||||
created_at=format_conversation_created_at(conversation.created_at),
|
||||
)
|
||||
|
|
@ -128,12 +129,16 @@ class ConversationState(rx.State):
|
|||
]
|
||||
|
||||
@rx.event
|
||||
def set_conversation_history_item_popover_shown(self, is_shown: bool) -> None:
|
||||
def set_conversation_history_item_popover_shown(
|
||||
self, conversation_id: str, is_shown: bool
|
||||
) -> None:
|
||||
"""
|
||||
设置会话历史项悬停气泡显示 / 隐藏
|
||||
:return: None
|
||||
"""
|
||||
self.is_conversation_history_item_popover_shown = is_shown
|
||||
self.is_conversation_history_item_popover_shown = (
|
||||
conversation_id if is_shown else ""
|
||||
)
|
||||
|
||||
@rx.event
|
||||
async def delete_conversation(self, conversation_id: str) -> None:
|
||||
|
|
@ -166,6 +171,18 @@ class ConversationState(rx.State):
|
|||
"""
|
||||
self.actived_conversation_id = conversation_id
|
||||
|
||||
@rx.var
|
||||
def message_history(self) -> list[Message]:
|
||||
"""
|
||||
获取当前会话的消息历史
|
||||
:return: 当前会话的消息历史
|
||||
"""
|
||||
# 当前会话
|
||||
conversation = self.conversations.get(self.actived_conversation_id)
|
||||
if not conversation:
|
||||
return []
|
||||
return list(conversation.messages.values())
|
||||
|
||||
@rx.event
|
||||
async def create_conversation(self) -> None:
|
||||
"""
|
||||
|
|
@ -181,6 +198,18 @@ class ConversationState(rx.State):
|
|||
# 将最后一个会话的唯一标识作为激活会话唯一标识
|
||||
self.actived_conversation_id = next(reversed(self.conversations.keys()))
|
||||
|
||||
@rx.var
|
||||
def user_prompt(self) -> str:
|
||||
"""
|
||||
用户提示词
|
||||
:return: 用户提示词
|
||||
"""
|
||||
# 当前会话
|
||||
conversation = self.conversations.get(self.actived_conversation_id)
|
||||
if not conversation:
|
||||
return ""
|
||||
return conversation.user_prompt
|
||||
|
||||
@rx.event
|
||||
def set_user_prompt(self, user_prompt: str) -> None:
|
||||
"""
|
||||
|
|
@ -276,7 +305,7 @@ class ConversationState(rx.State):
|
|||
from application.workshop.unstructured_dialogue import (
|
||||
run_stream_events,
|
||||
)
|
||||
|
||||
# 运行并流式输出事件
|
||||
stream_events = run_stream_events(
|
||||
user_prompt=user_prompt,
|
||||
message_history=message_history,
|
||||
|
|
@ -415,11 +444,6 @@ class ConversationState(rx.State):
|
|||
case "tool_call":
|
||||
dialog.thoughts[index].content = f"已调用 {content}"
|
||||
|
||||
case TaskNodeResultEvent(task=task, content=content):
|
||||
# 更新任务
|
||||
conversation.task = task
|
||||
dialog.result_output += content
|
||||
|
||||
# ========== 智能体运行结果事件 ==========
|
||||
case AgentRunResultEvent(result=result):
|
||||
# 创建对话记录
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ class MessageType(StrEnum):
|
|||
THINKING = "thinking"
|
||||
TOOL_CALL = "tool_call"
|
||||
RESULT_OUTPUT = "result_output"
|
||||
|
||||
|
||||
|
||||
class Message(BaseModel):
|
||||
|
|
@ -73,12 +72,6 @@ class WorkType(StrEnum):
|
|||
BOOK_FLIGHT = "预定航班"
|
||||
|
||||
|
||||
class TaskStatus(StrEnum):
|
||||
"""
|
||||
任务状态枚举
|
||||
"""
|
||||
|
||||
NONE = "none"
|
||||
|
||||
|
||||
class Deps(BaseModel):
|
||||
|
|
@ -126,6 +119,7 @@ class ConversationHistoryItem(BaseModel):
|
|||
会话历史项类
|
||||
"""
|
||||
|
||||
id: str = Field(..., description="会话唯一标识")
|
||||
description: str = Field(..., description="会话描述")
|
||||
created_at: str = Field(..., description="会话创建日期时间")
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from application.states.models import (
|
|||
usage_to_dict,
|
||||
usage_to_object,
|
||||
)
|
||||
from application.tasks.models import DEEPSEEK_V4_FLASH_MODEL, MODEL_SETTINGS
|
||||
from application.workshop.models import DEEPSEEK_V4_FLASH_MODEL, MODEL_SETTINGS
|
||||
|
||||
|
||||
class Deps(BaseModel):
|
||||
|
|
@ -67,7 +67,7 @@ flight_details_extraction_agent = Agent(
|
|||
)
|
||||
|
||||
|
||||
@flight_search_agent.tool(name="提取所有航班详情")
|
||||
@flight_search_agent.tool
|
||||
async def extract_flight_details(ctx: RunContext[Deps]) -> list[FlightDetail]:
|
||||
"""
|
||||
工具:提取所有航班详情
|
||||
|
|
@ -168,15 +168,16 @@ flight_info = """
|
|||
|
||||
|
||||
def init_task() -> Task:
|
||||
return Task(
|
||||
type=TaskType.BOOK_FLIGHT,
|
||||
node="flight_search",
|
||||
return WorkFlow(
|
||||
type=WorkType.BOOK_FLIGHT,
|
||||
tools={"extract_flight_details": {"": ""}},
|
||||
deps=Deps(
|
||||
flight_info=flight_info,
|
||||
date=datetime.date(2025, 1, 10),
|
||||
origin="SFO",
|
||||
destination="ANC",
|
||||
),
|
||||
usage_limits={},
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue