This commit is contained in:
liubiren 2026-07-08 20:20:18 +08:00
parent 4c630c1f79
commit 13e3c58edf
11 changed files with 417 additions and 284 deletions

View File

@ -12,13 +12,23 @@ app = rx.App(
"margin": "0", "margin": "0",
"padding": "0", "padding": "0",
"box_sizing": "border-box", "box_sizing": "border-box",
"background-color": "transparent",
"font-family": "HuaweiFont,Helvetica,Arial,PingFangSC-Regular,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Microsoft JhengHei",
"gap": "0",
}, },
# 覆盖伪元素 ::before 和 ::after # 覆盖伪元素 ::before 和 ::after
"*::before, *::after": { "*::before, *::after": {
"box_sizing": "border-box", "box_sizing": "border-box",
}, },
"--devui-base-bg": "#ffffff",
"--mc-global-bg": "linear-gradient(to bottom, #D0C9FF 0%, #E6D6F0 8%, #F1DBEA 12%, #C8DCFB 40%, #ABC6F6 60%, #87AEFE 90%)", "--mc-global-bg": "linear-gradient(to bottom, #D0C9FF 0%, #E6D6F0 8%, #F1DBEA 12%, #C8DCFB 40%, #ABC6F6 60%, #87AEFE 90%)",
"--devui-base-bg-dark": "#252b3a", "--devui-border-radius-feedback": "4px",
"--devui-border-radius-card": "8px",
"--devui-font-size-sm": "11px",
"--devui-font-size": "12px",
"--devui-font-size-lg": "14px",
"--devui-text": "#252b3a",
"--devui-text-weak": "#575d6c",
} # 自定义主题颜色 } # 自定义主题颜色
) # 此处变量名需使用 app ,具体原因目前尚不清楚 ) # 此处变量名需使用 app ,具体原因目前尚不清楚
# 注册首页路由 # 注册首页路由

View File

@ -0,0 +1,22 @@
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" fill="none">
<defs>
<linearGradient id="paint_linear_0" x1="20.4101181" x2="13.4623451" y1="22.4444809" y2="9.22279358" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(195.886,115.909,255)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(120.545,222.545,255)" offset="0.91785866" stop-opacity="1" />
</linearGradient>
<linearGradient id="paint_linear_1" x1="21.1874924" x2="19.1952991" y1="7.64146042" y2="4.28173828" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(195.886,115.909,255)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(120.545,222.545,255)" offset="0.91785866" stop-opacity="1" />
</linearGradient>
<linearGradient id="paint_linear_2" x1="16.3122597" x2="5.95285082" y1="20.5696716" y2="3.09911919" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(195.886,115.909,255)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(120.545,222.545,255)" offset="0.91785866" stop-opacity="1" />
</linearGradient>
</defs>
<rect id="对话" width="24" height="24" x="0" y="0" />
<g id="组合 2745">
<path id="矢量 652" d="M11.1465 19.6708C12.2203 20.4478 13.5424 20.9059 14.9688 20.9059C15.8547 20.9059 16.699 20.7296 17.469 20.4101C18.2668 20.0796 20.9063 20.3121 20.9063 20.3121C20.9063 20.3121 20.6743 17.6733 21.006 16.8749C21.3237 16.1048 21.5 15.26 21.5 14.3746C21.5 12.2814 20.5166 10.4178 18.9835 9.22279C19.0763 9.73827 19.125 10.27 19.125 10.8121C19.125 15.4177 15.6298 19.207 11.1465 19.6708Z" fill="url(#paint_linear_0)" fill-rule="evenodd" />
<path id="路径 33备份" d="M20.0156 4.28174L19.6034 5.34381L18.5313 5.77253L19.6034 6.18613L20.0156 7.25049L20.4007 6.18613L21.5 5.77253L20.4007 5.34381L20.0156 4.28174Z" fill="url(#paint_linear_1)" fill-rule="evenodd" />
<path id="减去顶层" d="M17.9373 10.8179C17.9373 6.55492 14.4815 3.09912 10.2186 3.09912C5.95562 3.09912 2.49981 6.55492 2.49981 10.8179C2.49981 11.8645 2.70811 12.8624 3.0855 13.7725C3.47671 14.7159 3.20152 17.8349 3.20152 17.8349C3.20152 17.8349 6.32055 17.5597 7.26394 17.9509C8.17404 18.3283 9.17198 18.5366 10.2186 18.5366C14.4815 18.5366 17.9373 15.0808 17.9373 10.8179ZM8.80933 8.78985C9.43966 8.78985 9.95063 9.30087 9.95063 9.93115C9.95063 10.5614 9.43966 11.0725 8.80933 11.0725C8.179 11.0725 7.66803 10.5614 7.66803 9.93115C7.66803 9.30087 8.179 8.78985 8.80933 8.78985ZM13.5267 8.78985C14.1571 8.78985 14.668 9.30087 14.668 9.93115C14.668 10.5614 14.1571 11.0725 13.5267 11.0725C12.8964 11.0725 12.3854 10.5614 12.3854 9.93115C12.3854 9.30087 12.8964 8.78985 13.5267 8.78985Z" fill="url(#paint_linear_2)" fill-rule="evenodd" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -4,107 +4,149 @@
""" """
import reflex as rx import reflex as rx
from typing import Tuple
from application.models import Run, Reasoning, Conversation from application.models import Run, Reasoning, Conversation
from application.state.conversation import ConversationState from application.state.conversation import ConversationState
from application.state.create_conversation_modal import CreateConversationModalState from application.state.create_conversation_modal import CreateConversationModalState
def render_delete_conversation_component( def render_conversation_history_item(
conversation_id: str, conversation_id: str, conversation: Conversation
): ) -> rx.Component:
""" """
渲染删除对话组件 渲染对话历史的对话卡片
:param conversation_id: 对话唯一标识 :param conversation_id: 对话唯一标识
:return: 删除对话组件 :param conversation: 对话实例
:return: Component
"""
def render_more_button(
conversation_id: str,
) -> rx.Component:
"""
渲染更多按钮
:param conversation_id: 对话唯一标识
:return: Component
""" """
return rx.popover.root( return rx.popover.root(
# 触发事件:点击更多按钮
rx.popover.trigger( rx.popover.trigger(
rx.button( rx.button(
rx.icon("ellipsis", size=16), rx.icon("ellipsis", size=14, color="var(--devui-text-weak)"),
variant="ghost", cursor="pointer", # 鼠标光标显示为手指
padding="4px",
height="auto",
) )
), ),
# 渲染气泡卡片
rx.popover.content( rx.popover.content(
rx.box(
width="14px",
height="14px",
position="absolute",
top="-7px",
left="50%",
transform="translateX(-50%) rotate(45deg)",
background_color="var(--devui-base-bg, #ffffff)",
box_shadow="-2px -2px 4px rgba(0,0,0,0.05)",
),
rx.popover.close( rx.popover.close(
rx.button( rx.box(
"删除", "删除",
color_scheme="red", width="100%", # 宽度
variant="ghost", height="24px", # 高度
width="100%", padding="4px", # 内边距
justify_content="center", line_height="16px", # 行高
font_size="12px", # 字体大小
color="#252b3a",
display="flex", # 弹性布局
flex_wrap="wrap", # 换行
align_items="center", # 子元素垂直居中
background_color="var(--devui-base-bg)", # 背景颜色
white_space="nowrap", # 不换行
border_radius="var(--devui-border-radius-feedback)", # 圆角
# 点击事件:删除对话
on_click=lambda: ConversationState.delete_conversation( on_click=lambda: ConversationState.delete_conversation(
conversation_id conversation_id
), ),
)
), ),
padding="4px",
), ),
open_delay=0, padding="8px", # 内边距
arrow_size=10, # 三角大小
side="bottom", # 气泡在按钮下方,三角朝上
side_offset=8, # 气泡和按钮之间间距
align="center", # 水平居中对齐触发按钮中线
style={
"position": "relative", # 关键:给三角提供定位基准
"background_color": "var(--devui-base-bg, #ffffff) !important",
"border_radius": "var(--devui-border-radius-feedback, 8px) !important",
"box_shadow": "0 2px 12px rgba(0,0,0,0.1)",
},
),
) )
# 指定对话的激活状态
is_actived = conversation_id == ConversationState.conversation_id
def render_conversation_item_component( return rx.box(
conversation_id: str, conversation: Conversation
):
"""
渲染对话项组件
"""
# 对话描述
description = conversation.description
# 若当前对话唯一标识非指定对话唯一标识则正常渲染,否则高亮渲染
return rx.cond(
ConversationState.conversation_id != conversation_id,
# 正常渲染
rx.button(
rx.hstack( rx.hstack(
# 渲染对话描述
rx.text( rx.text(
description, conversation.description,
flex=1, flex=1,
height="22px",
line_height="22px",
font_size="var(--devui-font-size)",
padding_right="4px",
overflow="hidden", overflow="hidden",
text_overflow="ellipsis", text_overflow="ellipsis",
white_space="nowrap", white_space="nowrap",
text_align="left",
), ),
render_delete_conversation_component(conversation_id), # 渲染更多按钮
align_items="center", rx.box(
width="100%", render_more_button(conversation_id=conversation_id),
spacing="2", min_width="14px",
cursor="pointer", # 鼠标光标显示为手指
style={
"opacity": rx.cond(
is_actived, "1", "0"
), # 若已激活则不透明,否则透明
"pointer_events": rx.cond(
is_actived, "auto", "none"
), # 若已激活则可点击,否则不可点击
"transition": "opacity 0.18s ease",
},
), ),
width="100%", display="flex", # 弹性布局
justify_content="flex-start", align_items="center", # 子元素垂直居中
padding_x="12px", width="100%", # 宽度
padding_y="10px", margin_bottom="8px", # 底部外边距
variant="surface", ),
color_scheme="blue", line_height="1.5", # 行高
color="var(--devui-text-weak)", # 字体颜色
cursor="pointer", # 鼠标悬停显示手指
margin_bottom="8px", # 底部外边距
width="100%", # 宽度
padding="16px", # 内边距
border_radius="8px", # 圆角
style={
"background": rx.cond(
is_actived,
"linear-gradient(to right, #f3efff, #f3efff33, #e2f1fd33, #e2f1fd)",
"var(--devui-base-bg)",
),
"box_shadow": rx.cond(is_actived, "2px 2px 8px #e9e9e9", "none"),
# 鼠标悬停时渲染背景颜色和阴影
"&:hover": {
"background": "linear-gradient(to right, #f3efff, #f3efff33, #e2f1fd33, #e2f1fd)",
"box_shadow": "2px 2px 8px #e9e9e9",
},
# 鼠标悬停时强制显示右侧三点按钮,覆盖默认隐藏
"&:hover > div > div:last-child": {
"opacity": "1 !important",
"pointer_events": "auto !important",
},
},
# 点击事件:将指定对话唯一标识设置为当前对话唯一标识
on_click=lambda: ConversationState.switch_conversation(conversation_id), on_click=lambda: ConversationState.switch_conversation(conversation_id),
),
# 高亮渲染
rx.button(
rx.hstack(
rx.text(
description,
flex=1,
overflow="hidden",
text_overflow="ellipsis",
white_space="nowrap",
text_align="left",
),
render_delete_conversation_component(conversation_id),
align_items="center",
width="100%",
spacing="2",
),
width="100%",
justify_content="flex-start",
padding_x="12px",
padding_y="10px",
variant="soft",
color_scheme="blue",
),
) )
@ -277,14 +319,11 @@ def render_conversation_component() -> rx.Component:
) )
def render_input_component() -> rx.Component: def render_create_conversation_component() -> rx.Component:
""" """
渲染输入和其它组件 渲染创建对话组件
""" """
return rx.center( return rx.hstack(
rx.vstack(
# 渲染创建对话组件
rx.hstack(
rx.spacer(), # 占位符 rx.spacer(), # 占位符
rx.dialog.root( rx.dialog.root(
# 触发事件:点击创建对话图标,支持鼠标悬停提示 # 触发事件:点击创建对话图标,支持鼠标悬停提示
@ -314,7 +353,14 @@ def render_input_component() -> rx.Component:
on_open_change=CreateConversationModalState.toggle, on_open_change=CreateConversationModalState.toggle,
), ),
width="100%", width="100%",
), )
def render_input_component() -> rx.Component:
"""
渲染输入组件
"""
return rx.vstack(
# 渲染自定义输入组件 # 渲染自定义输入组件
rx.form( rx.form(
rx.box( rx.box(
@ -370,15 +416,4 @@ def render_input_component() -> rx.Component:
width="100%", width="100%",
padding_x="16px", padding_x="16px",
align="stretch", align="stretch",
),
position="sticky",
bottom="0",
left="0",
padding_y="16px",
backdrop_filter="auto",
backdrop_blur="lg",
border_top=f"1px solid {rx.color('mauve', 3)}",
background_color=rx.color("mauve", 2),
align="stretch",
width="100%",
) )

View File

@ -9,8 +9,8 @@ from application.state.frame import FrameState
# 初始化侧边栏图标导航按钮字典 # 初始化侧边栏图标导航按钮字典
sidebar_icon_nav_buttons = { sidebar_icon_nav_buttons = {
"conversation": {"src": "/assets/conversation.svg", "text": "对话"}, "conversation": {"src": "/conversation.svg", "text": "对话"},
"knowledge_base": {"src": "/assets/knowledge_base.svg", "text": "知识库"}, "knowledge_base": {"src": "/knowledge_base.svg", "text": "知识库"},
} }
@ -21,7 +21,7 @@ def render_brand_logo(width: str = "34px", height: str = "34px") -> rx.Component
:param height: 高度默认为 34px :param height: 高度默认为 34px
""" """
return rx.image( return rx.image(
src="/assets/logo.png", src="/logo.png",
width=width, width=width,
height=height, height=height,
object_fit="contain", # 等比缩放 object_fit="contain", # 等比缩放
@ -35,55 +35,45 @@ def render_sidebar_icon_nav_button(
渲染侧边栏图标导航按钮 渲染侧边栏图标导航按钮
:param sidebar_icon_nav_button: 侧边栏图标导航按钮 :param sidebar_icon_nav_button: 侧边栏图标导航按钮
""" """
# 侧边栏图标导航按钮图标 # 指定侧边栏图标导航按钮的激活状态
src = sidebar_icon_nav_buttons[sidebar_icon_nav_button]["src"] is_actived = sidebar_icon_nav_button == FrameState.sidebar_icon_nav_button
# 侧边栏图标导航按钮标签
text = sidebar_icon_nav_buttons[sidebar_icon_nav_button]["text"]
# 若选中侧边栏图标导航按钮图标非指定图标导航按钮图标则正常渲染,否则高亮渲染 return rx.box(
return rx.cond( # 渲染图标盒子
FrameState.sidebar_icon_nav_button != sidebar_icon_nav_button,
# 正常渲染
rx.button(
rx.vstack(
rx.icon(icon, size=18),
rx.text(text, font_size="10px"),
spacing="2",
align_items="center",
),
width="100%",
justify_content="center",
variant="surface",
color_scheme="blue",
on_click=lambda: FrameState.switch_active_sidebar_tab(
sidebar_icon_nav_button
),
padding_y="10px",
),
# 高亮渲染
rx.button(
rx.vstack(
rx.box( rx.box(
# 渲染图标
rx.image( rx.image(
src=src, src=sidebar_icon_nav_buttons[sidebar_icon_nav_button]["src"],
width="24px", width="24px",
height="24px", height="24px",
object_fit="contain", # 等比缩放 object_fit="contain", # 等比缩放
), ),
background_color="#e4f7ff", display="flex", # 弹性布局
border_radius="4px", justify_content="center", # 水平居中对齐
align_items="center", # 垂直居中对齐
width="36px", # 宽度
height="36px", # 高度
border_radius="var(--devui-border-radius-card)", # 圆角
# 若已激活则渲染图标盒子背景颜色和阴影,否则不渲染
style={
"background-color": rx.cond(
is_actived, "var(--devui-base-bg)", "transparent"
), ),
rx.text(text, size="8"), "box-shadow": rx.cond(is_actived, "0 4px 12px #0000001a", "none"),
spacing="2", },
align_items="center",
), ),
width="100%", # 渲染标签
justify_content="center", rx.text(
variant="soft", sidebar_icon_nav_buttons[sidebar_icon_nav_button]["text"],
color_scheme="blue", color="var(--devui-text)",
padding_y="10px", font_size="var(--devui-font-size-sm)",
line_height="20px",
), ),
display="flex", # 弹性布局
flex_direction="column", # 垂直方向布局
align_items="center", # 垂直居中对齐
gap="4px",
font_size="var(--devui-font-size-sm)", # 字体大小
cursor="pointer", # 鼠标指针
) )
@ -100,7 +90,7 @@ def render_sidebar() -> rx.Component:
render_brand_logo(), render_brand_logo(),
# 渲染品牌名称 # 渲染品牌名称
rx.text( rx.text(
"MateAgent", "MateAI",
line_height="20px", # 行高 line_height="20px", # 行高
font_size="11px", font_size="11px",
font_weight="700", font_weight="700",
@ -108,8 +98,8 @@ def render_sidebar() -> rx.Component:
), ),
display="flex", # 弹性布局 display="flex", # 弹性布局
flex_direction="column", # 垂直方向布局 flex_direction="column", # 垂直方向布局
justify_content="center", # 水平居中对齐 justify_content="center", # 子元素垂直居中分布
align_items="center", # 水平居中对齐 align_items="center", # 子元素水平居中
gap="4px", gap="4px",
), ),
# 渲染分隔线 # 渲染分隔线
@ -123,14 +113,14 @@ def render_sidebar() -> rx.Component:
margin_top="12px", # 上外边距 margin_top="12px", # 上外边距
display="flex", # 弹性布局 display="flex", # 弹性布局
flex_direction="column", # 垂直方向布局 flex_direction="column", # 垂直方向布局
align_items="center", # 水平居中对齐 align_items="center", # 子元素水平居中
width="100%", # 宽度为父容器宽度 width="100%", # 宽度为父容器宽度
), ),
display="flex", # 弹性布局 display="flex", # 弹性布局
flex_direction="column", # 垂直方向布局 flex_direction="column", # 垂直方向布局
justify_content="space-between", # 间距分布 justify_content="space-between", # 子元素垂直两端分布
align_items="center", # 水平居中对齐 align_items="center", # 子元素水平居中
width="60px", # 宽度 width="60px", # 宽度
height="100%", # 高度为父容器高度 height="100%", # 高度
box_sizing="border-box", # 盒模型 box_sizing="border-box", # 盒模型
) )

View File

@ -6,8 +6,9 @@ import reflex as rx
from application.components.conversation import ( from application.components.conversation import (
render_conversation_component, render_conversation_component,
render_conversation_item_component, render_conversation_history_item,
render_input_component, render_input_component,
render_create_conversation_component,
) )
from application.state.conversation import ConversationState from application.state.conversation import ConversationState
from application.state.conversation_history_collapse import ( from application.state.conversation_history_collapse import (
@ -17,49 +18,61 @@ from application.state.conversation_history_collapse import (
def render_conversation_page() -> rx.Component: def render_conversation_page() -> rx.Component:
""" """
渲染对话页面左侧为对话历史折叠面板右侧为对话和输入等组件 渲染对话页面左侧为对话历史折叠面板右侧为对话历史运行历史创建和输入等组件
""" """
# 对话历史折叠面板打开状态 # 对话历史折叠面板打开状态
is_open = ConversationHistoryCollapseState.is_open is_open = ConversationHistoryCollapseState.is_open
return rx.hstack( return rx.hstack(
# 渲染对话历史组件(聊天容器左侧部分),若对话历史列表 # 渲染左侧
rx.hstack( rx.hstack(
# 若对话历史折叠面板关闭则不渲染,否则渲染 # 若对话历史折叠面板打开则渲染,否则不渲染
rx.cond( rx.cond(
is_open, is_open,
rx.fragment(), # 渲染标题、搜索栏和对话历史列表
# 渲染对话历史组件
rx.box(
rx.vstack( rx.vstack(
# 标题 # 标题
rx.hstack(
rx.text( rx.text(
"对话历史", font_size="16px", weight="bold", width="100%" "对话历史",
font_size="var(--devui-font-size-lg)", # 字体大小
font_weight="700", # 字体粗细
margin_bottom="8px", # 底部外边距
white_space="nowrap", # 不换行
), ),
# 分割线 display="flex", # 弹性布局
rx.divider(), align_items="center", # 子元素垂直居中
# 遍历渲染对话字典 justify_content="space-between", # 子元素两端对齐
rx.foreach(
ConversationState.get_conversations,
lambda i, _: render_conversation_item_component(i[0], i[1]),
), ),
# 渲染搜索栏(暂未实现)
# 渲染对话历史列表
rx.vstack( rx.vstack(
rx.icon("box", size=64, color=rx.color("mauve", 8)), rx.foreach(
rx.text("无数据", size="3", color=rx.color("mauve", 10)), ConversationState.get_conversation_history,
align_items="center", lambda item, _: render_conversation_history_item(
justify_content="center", item[0], item[1]
flex="1",
margin_top="60px",
), ),
align_items="stretch",
width="100%",
spacing="2",
padding="2em",
), ),
width="20em", flex="1", # 占满父元素高度
height="100vh", margin_top="8px", # 顶部外边距
background_color=rx.color("mauve", 1), width="100%", # 宽度
overflow="auto", # 允许溢出时显示垂直滚动条
align_items="stretch", # 子元素水平拉伸
), ),
backdrop_filter="blur(50px)", # 背景模糊
background_color="#f9f9f9cc", # 背景颜色
display="flex", # 弹性布局
flex_direction="column", # 垂直方向布局
gap="12px", # 子元素间距
min_width="240px", # 最小宽度
max_width="380px", # 最大宽度
width="25%", # 宽度
height="100%", # 高度
padding="12px", # 内边距
color="var(--devui-text)",
transition="all 0.3s ease-in-out", # 过渡动画
),
rx.fragment(),
), ),
rx.button( rx.button(
rx.cond( rx.cond(
@ -79,16 +92,35 @@ def render_conversation_page() -> rx.Component:
height="100vh", height="100vh",
spacing="0", spacing="0",
), ),
# 渲染对话、输入和其它组件(聊天容器右侧部分) # 渲染右侧布局占位层
rx.box(
# 渲染内容排版层
rx.vstack( rx.vstack(
# 渲染对话
render_conversation_component(), render_conversation_component(),
# 渲染创建对话
render_create_conversation_component(),
# 渲染输入
render_input_component(), render_input_component(),
flex=1, width="100%", # 宽度
height="100vh", height="100%", # 高度
spacing="0", display="flex", # 弹性布局
flex_flow="column", # 垂直方向布局
align_items="center", # 子元素水平居中
gap="8px", # 子元素间距
), ),
width="100vw", background_color="linear-gradient(180deg, #fffffff2, #f8fafff2 99%)", # 背景颜色
height="100vh", position="relative", # 相对定位
spacing="0", display="flex", # 弹性布局
align_items="stretch", flex="1", # 分配父容器宽度
width="0", # 宽度
height="100%", # 高度
),
position="relative", # 相对定位
flex="1", # 分配父容器宽度
display="flex", # 弹性布局
overflow="hidden", # 隐藏溢出内容
height="100%", # 高度
min_height="0", # 最小高度
border_radius="12px", # 圆角
) )

View File

@ -26,8 +26,8 @@ def render_index_page() -> rx.Component:
# 渲染知识库页面 # 渲染知识库页面
("knowledge_base", render_knowledge_base_page()), ("knowledge_base", render_knowledge_base_page()),
), ),
width="100%", width="100%", # 宽度
height="100vh", # 垂直高度为可视窗口高度 height="100vh", # 高度
padding="8px 8px 8px 0", # 内边距 padding="8px 8px 8px 0", # 内边距
overflow="auto", # 垂直方向拉伸至父元素高度 overflow="auto", # 垂直方向拉伸至父元素高度
box_sizing="border-box", # 盒模型 box_sizing="border-box", # 盒模型

View File

@ -71,10 +71,10 @@ class ConversationState(rx.State):
conversation_id: str = next(reversed(conversations.keys())) conversation_id: str = next(reversed(conversations.keys()))
@rx.var @rx.var
def get_conversations(self) -> Dict[str, Conversation]: def get_conversation_history(self) -> Dict[str, Conversation]:
""" """
获取对话字典用于前端按照创建倒序渲染对话历史 获取对话历史用于前端渲染对话历史
:return: 对话字典倒序 :return: 对话历史
""" """
return dict(reversed(self.conversations.items())) return dict(reversed(self.conversations.items()))

View File

@ -11,7 +11,7 @@ class ConversationHistoryCollapseState(rx.State):
""" """
# 对话历史折叠面板打开状态True表示打开False表示关闭 # 对话历史折叠面板打开状态True表示打开False表示关闭
is_open: bool = True is_open: bool = False
@rx.event @rx.event
def toggle(self) -> None: def toggle(self) -> None:

View File

@ -0,0 +1,22 @@
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" fill="none">
<defs>
<linearGradient id="paint_linear_0" x1="20.4101181" x2="13.4623451" y1="22.4444809" y2="9.22279358" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(195.886,115.909,255)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(120.545,222.545,255)" offset="0.91785866" stop-opacity="1" />
</linearGradient>
<linearGradient id="paint_linear_1" x1="21.1874924" x2="19.1952991" y1="7.64146042" y2="4.28173828" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(195.886,115.909,255)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(120.545,222.545,255)" offset="0.91785866" stop-opacity="1" />
</linearGradient>
<linearGradient id="paint_linear_2" x1="16.3122597" x2="5.95285082" y1="20.5696716" y2="3.09911919" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(195.886,115.909,255)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(120.545,222.545,255)" offset="0.91785866" stop-opacity="1" />
</linearGradient>
</defs>
<rect id="对话" width="24" height="24" x="0" y="0" />
<g id="组合 2745">
<path id="矢量 652" d="M11.1465 19.6708C12.2203 20.4478 13.5424 20.9059 14.9688 20.9059C15.8547 20.9059 16.699 20.7296 17.469 20.4101C18.2668 20.0796 20.9063 20.3121 20.9063 20.3121C20.9063 20.3121 20.6743 17.6733 21.006 16.8749C21.3237 16.1048 21.5 15.26 21.5 14.3746C21.5 12.2814 20.5166 10.4178 18.9835 9.22279C19.0763 9.73827 19.125 10.27 19.125 10.8121C19.125 15.4177 15.6298 19.207 11.1465 19.6708Z" fill="url(#paint_linear_0)" fill-rule="evenodd" />
<path id="路径 33备份" d="M20.0156 4.28174L19.6034 5.34381L18.5313 5.77253L19.6034 6.18613L20.0156 7.25049L20.4007 6.18613L21.5 5.77253L20.4007 5.34381L20.0156 4.28174Z" fill="url(#paint_linear_1)" fill-rule="evenodd" />
<path id="减去顶层" d="M17.9373 10.8179C17.9373 6.55492 14.4815 3.09912 10.2186 3.09912C5.95562 3.09912 2.49981 6.55492 2.49981 10.8179C2.49981 11.8645 2.70811 12.8624 3.0855 13.7725C3.47671 14.7159 3.20152 17.8349 3.20152 17.8349C3.20152 17.8349 6.32055 17.5597 7.26394 17.9509C8.17404 18.3283 9.17198 18.5366 10.2186 18.5366C14.4815 18.5366 17.9373 15.0808 17.9373 10.8179ZM8.80933 8.78985C9.43966 8.78985 9.95063 9.30087 9.95063 9.93115C9.95063 10.5614 9.43966 11.0725 8.80933 11.0725C8.179 11.0725 7.66803 10.5614 7.66803 9.93115C7.66803 9.30087 8.179 8.78985 8.80933 8.78985ZM13.5267 8.78985C14.1571 8.78985 14.668 9.30087 14.668 9.93115C14.668 10.5614 14.1571 11.0725 13.5267 11.0725C12.8964 11.0725 12.3854 10.5614 12.3854 9.93115C12.3854 9.30087 12.8964 8.78985 13.5267 8.78985Z" fill="url(#paint_linear_2)" fill-rule="evenodd" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,22 @@
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" fill="none">
<defs>
<linearGradient id="paint_linear_0" x1="20.4101181" x2="13.4623451" y1="22.4444809" y2="9.22279358" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(195.886,115.909,255)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(120.545,222.545,255)" offset="0.91785866" stop-opacity="1" />
</linearGradient>
<linearGradient id="paint_linear_1" x1="21.1874924" x2="19.1952991" y1="7.64146042" y2="4.28173828" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(195.886,115.909,255)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(120.545,222.545,255)" offset="0.91785866" stop-opacity="1" />
</linearGradient>
<linearGradient id="paint_linear_2" x1="16.3122597" x2="5.95285082" y1="20.5696716" y2="3.09911919" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(195.886,115.909,255)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(120.545,222.545,255)" offset="0.91785866" stop-opacity="1" />
</linearGradient>
</defs>
<rect id="对话" width="24" height="24" x="0" y="0" />
<g id="组合 2745">
<path id="矢量 652" d="M11.1465 19.6708C12.2203 20.4478 13.5424 20.9059 14.9688 20.9059C15.8547 20.9059 16.699 20.7296 17.469 20.4101C18.2668 20.0796 20.9063 20.3121 20.9063 20.3121C20.9063 20.3121 20.6743 17.6733 21.006 16.8749C21.3237 16.1048 21.5 15.26 21.5 14.3746C21.5 12.2814 20.5166 10.4178 18.9835 9.22279C19.0763 9.73827 19.125 10.27 19.125 10.8121C19.125 15.4177 15.6298 19.207 11.1465 19.6708Z" fill="url(#paint_linear_0)" fill-rule="evenodd" />
<path id="路径 33备份" d="M20.0156 4.28174L19.6034 5.34381L18.5313 5.77253L19.6034 6.18613L20.0156 7.25049L20.4007 6.18613L21.5 5.77253L20.4007 5.34381L20.0156 4.28174Z" fill="url(#paint_linear_1)" fill-rule="evenodd" />
<path id="减去顶层" d="M17.9373 10.8179C17.9373 6.55492 14.4815 3.09912 10.2186 3.09912C5.95562 3.09912 2.49981 6.55492 2.49981 10.8179C2.49981 11.8645 2.70811 12.8624 3.0855 13.7725C3.47671 14.7159 3.20152 17.8349 3.20152 17.8349C3.20152 17.8349 6.32055 17.5597 7.26394 17.9509C8.17404 18.3283 9.17198 18.5366 10.2186 18.5366C14.4815 18.5366 17.9373 15.0808 17.9373 10.8179ZM8.80933 8.78985C9.43966 8.78985 9.95063 9.30087 9.95063 9.93115C9.95063 10.5614 9.43966 11.0725 8.80933 11.0725C8.179 11.0725 7.66803 10.5614 7.66803 9.93115C7.66803 9.30087 8.179 8.78985 8.80933 8.78985ZM13.5267 8.78985C14.1571 8.78985 14.668 9.30087 14.668 9.93115C14.668 10.5614 14.1571 11.0725 13.5267 11.0725C12.8964 11.0725 12.3854 10.5614 12.3854 9.93115C12.3854 9.30087 12.8964 8.78985 13.5267 8.78985Z" fill="url(#paint_linear_2)" fill-rule="evenodd" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
智能体/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB