This commit is contained in:
liubiren 2026-07-28 01:18:38 +08:00
parent 998a0fc572
commit f9b91d45c1
5 changed files with 190 additions and 103 deletions

View File

@ -3,7 +3,7 @@
领域模型 领域模型
""" """
from datetime import datetime from datetime import datetime
from typing import Dict from typing import Dict, List
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from pydantic_ai._uuid import uuid7 from pydantic_ai._uuid import uuid7
@ -57,3 +57,20 @@ class ConversationHistoryItem(BaseModel):
id: str = Field(..., description="会话唯一标识") id: str = Field(..., description="会话唯一标识")
description: str = Field(..., description="会话描述") description: str = Field(..., description="会话描述")
created_at: str = Field(..., description="会话创建时间") created_at: str = Field(..., description="会话创建时间")
class DialogItem(BaseModel):
"""
对话项领域模型
"""
id: str = Field(..., description="对话唯一标识")
user_prompt: str = Field(..., description="用户提示词")
thoughts: List[Thought] = Field(default_factory=list, description="思考列表")
result_output: str = Field(default="", description="结果输出")
is_thinking: bool = Field(
default=False, description="正在思考True 表示正在思考False 表示未正在思考"
)
is_expanded: bool = Field(
default=False, description="思考折叠面板展开状态True 表示展开False 表示折叠"
)

View File

@ -7,33 +7,33 @@ from typing import Dict
from application.domain_models import ( from application.domain_models import (
Conversation, Conversation,
Dialog, DialogItem,
Thought, Thought,
ConversationHistoryItem, ConversationHistoryItem,
) )
from application.states import ConversationState, AuthState from application.states import ConversationState, AuthState
def conversation_history_item( def conversation_history_item_showing(
conversation: ConversationHistoryItem, item: ConversationHistoryItem,
) -> rx.Component: ) -> rx.Component:
""" """
会话历史项 会话历史项展示
:param conversation: 会话历史项 :param conversation: 会话历史项
:return: Component :return: Component
""" """
# 高亮:若为当前会话或显示更多则高亮 # 高亮:若为当前会话或显示更多则高亮
highlight: bool = ( highlight: bool = (item.id == ConversationState.shown_more_conversation_id) | (
conversation.id == ConversationState.shown_more_conversation_id item.id == ConversationState.conversation_id
) | (conversation.id == ConversationState.conversation_id) )
return rx.list.item( return rx.list.item(
rx.vstack( rx.vstack(
rx.hstack( rx.hstack(
# 对话描述 # 对话描述
rx.text( rx.text(
conversation.description, item.description,
flex=1, flex=1,
height="22px", height="22px",
line_height="22px", line_height="22px",
@ -52,7 +52,7 @@ def conversation_history_item(
rx.spacer(), rx.spacer(),
# 创建时间 # 创建时间
rx.text( rx.text(
conversation.created_at, item.created_at,
line_height="20px", line_height="20px",
font_size="var(--prismui-font-size-1)", font_size="var(--prismui-font-size-1)",
color="var(--prismui-color-8)", color="var(--prismui-color-8)",
@ -64,7 +64,7 @@ def conversation_history_item(
margin_bottom="8px", margin_bottom="8px",
), ),
# 点击事件:切换会话 # 点击事件:切换会话
on_click=lambda: ConversationState.switch_conversation(conversation.id), on_click=lambda: ConversationState.switch_conversation(item.id),
width="100%", width="100%",
), ),
# 更多按钮:点击更多按钮显示气泡卡片,可删除会话 # 更多按钮:点击更多按钮显示气泡卡片,可删除会话
@ -97,7 +97,7 @@ def conversation_history_item(
"删除", "删除",
# 点击事件:删除对话 # 点击事件:删除对话
on_click=lambda: ConversationState.delete_conversation( on_click=lambda: ConversationState.delete_conversation(
conversation.id item.id
), ),
display="flex", display="flex",
align_items="center", align_items="center",
@ -130,7 +130,7 @@ def conversation_history_item(
overflow="visible", overflow="visible",
), ),
on_open_change=lambda is_shown: ConversationState.set_shown_more_conversation_id( on_open_change=lambda is_shown: ConversationState.set_shown_more_conversation_id(
conversation.id, is_shown item.id, is_shown
), ),
open_delay=0, open_delay=0,
), ),
@ -138,7 +138,7 @@ def conversation_history_item(
top="27px", top="27px",
right="16px", right="16px",
transform="translateY(-50%)", transform="translateY(-50%)",
z_index=99, z_index="99",
min_width="14px", min_width="14px",
cursor="pointer", cursor="pointer",
opacity=rx.cond(highlight, "1", "0"), opacity=rx.cond(highlight, "1", "0"),
@ -172,11 +172,11 @@ def conversation_history_item(
) )
def conversation_history( def conversation_history_items_showing(
is_conversation_history_shown: bool, is_conversation_history_shown: bool,
) -> rx.Component: ) -> rx.Component:
""" """
会话历史 会话历史列表展示
:param is_conversation_history_shown: 会话历史展示状态 :param is_conversation_history_shown: 会话历史展示状态
:return: Component :return: Component
""" """
@ -193,11 +193,10 @@ def conversation_history(
align_items="center", align_items="center",
justify_content="space-between", justify_content="space-between",
), ),
# 会话历史列表
rx.auto_scroll( rx.auto_scroll(
rx.foreach( rx.foreach(
ConversationState.conversation_history_items, ConversationState.conversation_history_items,
conversation_history_item, conversation_history_item_showing,
), ),
flex="1", flex="1",
align_items="stretch", align_items="stretch",
@ -227,9 +226,9 @@ def conversation_history(
) )
def greeting() -> rx.Component: def greeting_showing() -> rx.Component:
""" """
欢迎 欢迎展示
:return: Component :return: Component
""" """
return rx.vstack( return rx.vstack(
@ -332,20 +331,19 @@ def greeting() -> rx.Component:
) )
def thought(thought): def thought_showing(item: Thought):
""" """
思考卡片 思考展示
:param item: 思考实例
:param thought: 思考实例
:return: Component :return: Component
""" """
return rx.vstack( return rx.vstack(
rx.match( rx.match(
thought[1].type, item.type,
( (
"thinking", "thinking",
rx.text( rx.text(
thought[1].content, item.content,
line_height="22px", line_height="22px",
font_size="var(--prismui-font-size-2)", font_size="var(--prismui-font-size-2)",
color="var(--prismui-color-3)", color="var(--prismui-color-3)",
@ -358,16 +356,16 @@ def thought(thought):
) )
def dialog(dialog: Dialog) -> rx.Component: def dialog_item_showing(item: DialogItem) -> rx.Component:
""" """
对话 对话项展示
:param dialog: 对话实例 :param item: 对话项实例
:return: Component :return: Component
""" """
# 推理状态 # 推理状态
is_thinking = dialog.is_thinking is_thinking = item.is_thinking
# 思考折叠面板展开状态 # 思考折叠面板展开状态
is_expanded = dialog.is_expanded is_expanded = item.is_expanded
return rx.vstack( return rx.vstack(
rx.hstack( rx.hstack(
@ -375,13 +373,12 @@ def dialog(dialog: Dialog) -> rx.Component:
rx.vstack( rx.vstack(
# 用户提示词 # 用户提示词
rx.text( rx.text(
dialog.user_prompt, item.user_prompt,
max_width="600px", max_width="600px",
padding="12px 16px", padding="12px 16px",
background_color="var(--prismui-background-color-3)", background_color="var(--prismui-background-color-3)",
border_radius="var(--prismui-border-radius-3)", border_radius="var(--prismui-border-radius-3)",
line_height="1.5", line_height="1.5",
color="var(--prismui-color-text)",
word_wrap="break-word", word_wrap="break-word",
word_break="break-all", word_break="break-all",
white_space="pre-line", white_space="pre-line",
@ -442,14 +439,14 @@ def dialog(dialog: Dialog) -> rx.Component:
), ),
cursor="pointer", cursor="pointer",
# 点击事件,展开/折叠思考折叠面板 # 点击事件,展开/折叠思考折叠面板
on_click=lambda: ConversationState.toggle_collapse(dialog.id), on_click=lambda: ConversationState.toggle_collapse(item.id),
), ),
rx.box( rx.box(
rx.box( rx.box(
rx.auto_scroll( rx.auto_scroll(
rx.foreach( rx.foreach(
dialog.thoughts, item.thoughts,
thought, thought_showing,
), ),
width="100%", width="100%",
margin_top="8px", margin_top="8px",
@ -470,20 +467,41 @@ def dialog(dialog: Dialog) -> rx.Component:
), ),
# 结果输出 # 结果输出
rx.markdown( rx.markdown(
dialog.result_output, item.result_output,
component_map={ component_map={
"p": lambda text: rx.text( "p": lambda text: rx.text(
text, text,
margin_bottom="8px", margin="6px 0",
line_height="1.5", line_height="1.5",
word_wrap="break-word", word_wrap="break-word",
word_break="break-all", word_break="break-all",
white_space="pre-line", white_space="pre-line",
), ),
"h1": lambda text: rx.text(
text,
margin="12px 0 6px",
line_height="1.5",
font_size="20px",
font_weight="var(--prismui-font-weight-3)",
word_wrap="break-word",
word_break="break-all",
white_space="pre-line",
),
"h2": lambda text: rx.text( "h2": lambda text: rx.text(
text, text,
margin_bottom="8px", margin="10px 0 6px",
line_height="1.5", line_height="1.5",
font_size="18px",
font_weight="var(--prismui-font-weight-3)",
word_wrap="break-word",
word_break="break-all",
white_space="pre-line",
),
"h3": lambda text: rx.text(
text,
margin="8px 0 6px",
line_height="1.5",
font_size="16px",
font_weight="var(--prismui-font-weight-3)", font_weight="var(--prismui-font-weight-3)",
word_wrap="break-word", word_wrap="break-word",
word_break="break-all", word_break="break-all",
@ -495,54 +513,71 @@ def dialog(dialog: Dialog) -> rx.Component:
font_weight="var(--prismui-font-weight-3)", font_weight="var(--prismui-font-weight-3)",
), ),
"ul": lambda children: rx.vstack( "ul": lambda children: rx.vstack(
children, margin_bottom="8px", gap="4px" children,
align_items="flex-start",
margin="6px 0",
style={"padding": "0 !important"},
), ),
"li": lambda text: rx.text( "ol": lambda children: rx.vstack(
text, children,
display="list-item", align_items="flex-start",
list_style_type="disc", margin="6px 0",
list_style_position="outside", style={"padding": "0 !important"},
margin="0 0 4px 16px", ),
line_height="1.5", "li": lambda text: rx.hstack(
font_size="var(--prismui-font-size-1)", rx.icon(
color="var(--prismui-color-1)", "dot",
word_wrap="break-word", flex_shrink="0",
word_break="break-all", width="21px",
white_space="pre-line", height="21px",
style={}, color="var(--prismui-color-5)",
),
rx.text(
text,
line_height="1.5",
word_wrap="break-word",
word_break="break-all",
white_space="pre-line",
),
align_items="flex-start",
margin_bottom="6px",
),
"hr": lambda _: rx.divider(
height="1px",
margin="12px 0",
background_color="var(--prismui-background-color-6)",
), ),
"hr": lambda _: rx.divider(margin="8px 0"),
}, },
width="100%", width="100%",
margin_top="8px",
), ),
padding="0 16px", padding="0 16px",
width="100%", width="100%",
key=dialog.id, key=item.id,
) )
def dialogs_showing() -> rx.Component: def dialog_items_showing() -> rx.Component:
""" """
对话列表展示 对话列表展示
:return: Component :return: Component
""" """
# 当前会话的对话列表 # 当前会话的对话列表
dialogs = ConversationState.dialogs dialog_items = ConversationState.dialog_items
# 若对话列表为空则显示欢迎,否则显示对话列表 # 若对话列表为空则显示欢迎,否则显示对话列表
return rx.cond( return rx.cond(
dialogs.length() == 0, dialog_items.length() == 0,
# 欢迎 # 欢迎展示
greeting(), greeting_showing(),
rx.vstack( rx.vstack(
rx.auto_scroll( rx.auto_scroll(
rx.foreach( rx.foreach(
dialogs, dialog_items,
dialog, dialog_item_showing,
), ),
width="100%", width="100%",
padding="0 12px", padding="0 12px",
padding_bottom="180px",
), ),
flex="1", flex="1",
width="100%", width="100%",
@ -556,7 +591,7 @@ def dialogs_showing() -> rx.Component:
) )
def create_conversation() -> rx.Component: def conversation_creating() -> rx.Component:
""" """
创建会话 创建会话
:return: Component :return: Component
@ -629,13 +664,15 @@ def create_conversation() -> rx.Component:
on_open_change=ConversationState.toggle_conversation_creating, on_open_change=ConversationState.toggle_conversation_creating,
), ),
display="flex", display="flex",
width="100%",
max_width="1200px",
height="39px",
padding="0 12px",
justify_content="flex-end", justify_content="flex-end",
align_items="center", align_items="center",
gap="4px", gap="4px",
padding="0 12px",
margin_bottom="8px",
width="100%",
max_width="1200px",
height="39px",
background="transparent",
) )
@ -645,6 +682,8 @@ def user_prompt_sending() -> rx.Component:
:return: Component :return: Component
""" """
return rx.vstack( return rx.vstack(
# 创建对话
conversation_creating(),
rx.vstack( rx.vstack(
rx.text_area( rx.text_area(
# 值绑定用户提示词 # 值绑定用户提示词
@ -654,7 +693,8 @@ def user_prompt_sending() -> rx.Component:
placeholder="请输入您的问题按Enter换行", placeholder="请输入您的问题按Enter换行",
vertical_align="middle", vertical_align="middle",
width="100%", width="100%",
height="64px", min_height="64px",
max_height="224px",
padding="4px 0", padding="4px 0",
background_color="var(--prismui-background-color-1)", background_color="var(--prismui-background-color-1)",
border="none !important", border="none !important",
@ -665,6 +705,10 @@ def user_prompt_sending() -> rx.Component:
"border": "none !important", "border": "none !important",
"outline": "none !important", "outline": "none !important",
"box-shadow": "none !important", "box-shadow": "none !important",
"field-sizing": "content !important",
"min-height": "64px",
"max-height": "224px",
"overflow-y": "auto",
}, },
}, },
), ),
@ -731,6 +775,10 @@ def user_prompt_sending() -> rx.Component:
font_size="var(--prismui-font-size-1)", font_size="var(--prismui-font-size-1)",
color="var(--prismui-color-10)", color="var(--prismui-color-10)",
), ),
position="absolute",
bottom="0",
left="0",
z_index="99",
display="flex", display="flex",
flex_direction="column", flex_direction="column",
width="100%", width="100%",
@ -756,12 +804,14 @@ def conversation_history_collapse_button(
height="16px", height="16px",
color="var(--prismui-color-3)", color="var(--prismui-color-3)",
), ),
# 点击事件:切换会话历史折叠面板展开状态
on_click=ConversationState.toggle_conversation_history_shown,
position="absolute", position="absolute",
top="calc(50% - 20px)", top="calc(50% - 20px)",
left=rx.cond( left=rx.cond(
is_conversation_history_shown, "calc(clamp(240px, 25%, 380px) - 8px)", "0" is_conversation_history_shown, "calc(clamp(240px, 25%, 380px) - 8px)", "0"
), ),
z_index=99, z_index="99",
width="16px", width="16px",
height="40px", height="40px",
background_color="var(--prismui-background-color-1)", background_color="var(--prismui-background-color-1)",
@ -773,8 +823,6 @@ def conversation_history_collapse_button(
box_shadow="var(--prismui-box-shadow-4)", box_shadow="var(--prismui-box-shadow-4)",
transition="all 0.3s ease-in-out", transition="all 0.3s ease-in-out",
cursor="pointer", cursor="pointer",
# 点击事件:切换会话历史折叠面板展开状态
on_click=ConversationState.toggle_conversation_history_shown,
) )
@ -787,29 +835,26 @@ def conversation() -> rx.Component:
return rx.box( return rx.box(
rx.hstack( rx.hstack(
# 会话历史 # 会话历史列表展示
conversation_history(is_conversation_history_shown), conversation_history_items_showing(is_conversation_history_shown),
rx.box( rx.box(
rx.vstack( rx.vstack(
# 对话列表展示 # 对话列表展示
dialogs_showing(), dialog_items_showing(),
# 创建对话
create_conversation(),
# 用户提示词发送
user_prompt_sending(),
display="flex",
flex_flow="column",
width="100%", width="100%",
height="100%", height="100%",
gap="8px", gap="8px",
align_items="center", align_items="center",
), ),
# 用户提示词发送
user_prompt_sending(),
position="relative", position="relative",
display="flex", display="flex",
flex="1", flex="1",
width="0", width="0",
height="100%", height="100%",
background="linear-gradient(180deg, #fffffff2, #f8fafff2 99%)", padding_bottom="120px",
background="var(--prismui-background-2)",
), ),
position="relative", position="relative",
display="flex", display="flex",
@ -821,11 +866,11 @@ def conversation() -> rx.Component:
), ),
# 会话历史折叠面板按钮 # 会话历史折叠面板按钮
conversation_history_collapse_button(is_conversation_history_shown), conversation_history_collapse_button(is_conversation_history_shown),
# 挂载事件:恢复会话状态
on_mount=AuthState.resume_conversation_state,
position="relative", position="relative",
width="100%", width="100%",
height="100%", height="100%",
border_radius="var(--prismui-border-radius-4)", border_radius="var(--prismui-border-radius-4)",
overflow="hidden", overflow="hidden",
# 挂载事件:恢复当前用户会话状态
on_mount=AuthState.resume_conversation_state,
) )

View File

@ -190,9 +190,9 @@ class AuthState(rx.State):
@rx.event @rx.event
async def resume_conversation_state(self): async def resume_conversation_state(self):
""" """
恢复当前用户会话状态 恢复会话状态
""" """
# 恢复当前用户会话状态 # 恢复会话状态
conversation_state = await self.get_state(ConversationState) conversation_state = await self.get_state(ConversationState)
await conversation_state.resume(user_id=self.user_id) await conversation_state.resume(user_id=self.user_id)

View File

@ -26,7 +26,7 @@ import reflex as rx
from application.states.database import DatabaseState from application.states.database import DatabaseState
from application.domain_models import ( from application.domain_models import (
Conversation, Conversation,
Dialog, DialogItem,
Thought, Thought,
ConversationHistoryItem, ConversationHistoryItem,
) )
@ -252,16 +252,29 @@ class ConversationState(rx.State):
return conversation.is_running return conversation.is_running
@rx.var @rx.var
def dialogs(self) -> List[Dialog]: def dialog_items(self) -> List[DialogItem]:
""" """
当前会话的对话列表 当前会话的对话列表
:return: 当前会话的对话列表 :return: 当前会话的对话列表
""" """
# 当前会话 # 当前会话
conversation = self.conversations.get(self.conversation_id) conversation = self.conversations.get(self.conversation_id)
if not conversation: if not conversation:
return [] return []
return list(conversation.dialogs.values())
items: List[DialogItem] = []
for dialog in conversation.dialogs.values():
items.append(
DialogItem(
id=dialog.id,
user_prompt=dialog.user_prompt,
thoughts=list(dialog.thoughts.values()),
result_output=dialog.result_output,
is_thinking=dialog.is_thinking,
is_expanded=dialog.is_expanded,
)
)
return items
@rx.event @rx.event
async def handle_user_prompt(self) -> AsyncGenerator[None]: async def handle_user_prompt(self) -> AsyncGenerator[None]:
@ -278,27 +291,26 @@ class ConversationState(rx.State):
# 当前会话 # 当前会话
conversation = self.conversations[self.conversation_id] conversation = self.conversations[self.conversation_id]
# 将当前会话的运行状态设置为正在运行 # 将运行状态设置为正在运行
conversation.is_running = True conversation.is_running = True
yield # 通知前端渲染 yield
# 获取数据库状态
database_state = await self.get_state(DatabaseState) database_state = await self.get_state(DatabaseState)
# 获取消息历史
message_history = await database_state.get_message_history(
conversation_id=self.conversation_id
)
# 创建对话记录再添加对话实例 # 创建对话记录再添加对话实例
conversation.dialogs.update( conversation.dialogs.update(
await database_state.create_dialog_record( await database_state.create_dialog_record(
conversation_id=self.conversation_id, user_prompt=user_prompt conversation_id=self.conversation_id, user_prompt=user_prompt
) )
) )
# 将最后一个会话作为当前会 # 将最后一个对话作为当前对
dialog = next(reversed(conversation.dialogs.values())) dialog = next(reversed(conversation.dialogs.values()))
# 获取消息历史
message_history = await database_state.get_message_history(
conversation_id=self.conversation_id
)
# 初始化工具调用唯一标识和片段索引映射字典 # 初始化工具调用唯一标识和片段索引映射字典
tool_call_ids: Dict[str, int] = {} tool_call_ids: Dict[str, int] = {}
async with agent.run_stream_events( async with agent.run_stream_events(
@ -324,6 +336,7 @@ class ConversationState(rx.State):
dialog.thoughts[index] = Thought( dialog.thoughts[index] = Thought(
type="thinking", content=content type="thinking", content=content
) )
yield
# 工具检索分片开始事件 # 工具检索分片开始事件
case ToolSearchCallPart(tool_call_id=tool_call_id): case ToolSearchCallPart(tool_call_id=tool_call_id):
@ -334,6 +347,7 @@ class ConversationState(rx.State):
type="tool_search", type="tool_search",
content="正在生成检索关键词", content="正在生成检索关键词",
) )
yield
# 能力加载分片开始事件 # 能力加载分片开始事件
case LoadCapabilityCallPart(tool_call_id=tool_call_id): case LoadCapabilityCallPart(tool_call_id=tool_call_id):
@ -343,6 +357,7 @@ class ConversationState(rx.State):
type="capability_load", type="capability_load",
content="正在生成加载参数", content="正在生成加载参数",
) )
yield
# 工具调用分片开始事件 # 工具调用分片开始事件
case ToolCallPart(tool_call_id=tool_call_id): case ToolCallPart(tool_call_id=tool_call_id):
@ -352,10 +367,12 @@ class ConversationState(rx.State):
type="tool_call", type="tool_call",
content="正在生成调用参数", content="正在生成调用参数",
) )
yield
# 文本分片开始事件 # 文本分片开始事件
case TextPart(content=content): case TextPart(content=content):
dialog.result_output = content dialog.result_output = content
yield
# ========== 增量事件 ========== # ========== 增量事件 ==========
case PartDeltaEvent(index=index, delta=delta): case PartDeltaEvent(index=index, delta=delta):
@ -365,12 +382,14 @@ class ConversationState(rx.State):
content_delta=content_delta, content_delta=content_delta,
): ):
dialog.thoughts[index].content += content_delta or "" dialog.thoughts[index].content += content_delta or ""
yield
# 文本分片增量事件 # 文本分片增量事件
case TextPartDelta( case TextPartDelta(
content_delta=content_delta, content_delta=content_delta,
): ):
dialog.result_output += content_delta dialog.result_output += content_delta
yield
# ========== 结束事件 ========== # ========== 结束事件 ==========
case PartEndEvent( case PartEndEvent(
@ -385,6 +404,7 @@ class ConversationState(rx.State):
if next_part_kind == "text": if next_part_kind == "text":
dialog.is_thinking = False dialog.is_thinking = False
dialog.is_expanded = False dialog.is_expanded = False
yield
# ========== 函数工具调用事件 ========== # ========== 函数工具调用事件 ==========
case FunctionToolCallEvent(tool_call_id=tool_call_id, part=part): case FunctionToolCallEvent(tool_call_id=tool_call_id, part=part):
@ -394,18 +414,21 @@ class ConversationState(rx.State):
# 工具检索 # 工具检索
case "tool_search": case "tool_search":
dialog.thoughts[index].content = "正在检索" dialog.thoughts[index].content = "正在检索"
yield
# 能力加载 # 能力加载
case "capability_load": case "capability_load":
dialog.thoughts[index].content = ( dialog.thoughts[index].content = (
f"正在加载能力 {part.tool_name}" f"正在加载能力 {part.tool_name}"
) )
yield
# 工具调用 # 工具调用
case "tool_call": case "tool_call":
dialog.thoughts[index].content = ( dialog.thoughts[index].content = (
f"正在调用工具 {part.tool_name}" f"正在调用工具 {part.tool_name}"
) )
yield
# ========== 函数工具结果事件 ========== # ========== 函数工具结果事件 ==========
case FunctionToolResultEvent( case FunctionToolResultEvent(
@ -419,14 +442,17 @@ class ConversationState(rx.State):
dialog.thoughts[index].content = ( dialog.thoughts[index].content = (
content if isinstance(content, str) else "" content if isinstance(content, str) else ""
) # 暂仅考虑文本内容 ) # 暂仅考虑文本内容
yield
# 能力加载 # 能力加载
case "capability_load": case "capability_load":
dialog.thoughts[index].content = "已加载" dialog.thoughts[index].content = "已加载"
yield
# 工具调用 # 工具调用
case "tool_call": case "tool_call":
dialog.thoughts[index].content = f"已调用" dialog.thoughts[index].content = f"已调用"
yield
# ========== 智能体运行结果事件 ========== # ========== 智能体运行结果事件 ==========
case AgentRunResultEvent(result=result): case AgentRunResultEvent(result=result):
@ -444,8 +470,7 @@ class ConversationState(rx.State):
) )
# 将当前会话的运行状态设置为运行完成 # 将当前会话的运行状态设置为运行完成
conversation.is_running = False conversation.is_running = False
yield
yield
@rx.event @rx.event
def toggle_collapse(self, dialog_id: str) -> None: def toggle_collapse(self, dialog_id: str) -> None:

Binary file not shown.