diff --git a/docs/latest/changelog/roadmap.md b/docs/latest/changelog/roadmap.md index d3d52e11..df4782d2 100644 --- a/docs/latest/changelog/roadmap.md +++ b/docs/latest/changelog/roadmap.md @@ -11,10 +11,14 @@ - 文档解析部分的 markdown 中的图片替换为内部可访问的链接 (2/4) - chat_model 的 call 需要异步 - 优化chunk逻辑,移除 QA 分割,集成到普通分块中 +- 考虑修改附件的处理逻辑,考虑使用文件系统,将附件解析后放到文件系统中,智能体按需读取,用户可以使用 @ 来引用附件,例如 @file:reports.md 相较于现在的处理逻辑感觉会更加自然一点。在此之前可能还要考虑文件系统的后端支持问题 +- skills 如何实现还需要继续调研 ### Bugs - 部分异常状态下,智能体的模型名称出现重叠[#279](https://github.com/xerrors/Yuxi-Know/issues/279) +- 部分 local 的 mcp server 无法正常加载,但是建议在项目外部启动 mcp 服务器,然后通过 sse 的方式使用。 - DeepSeek 官方接口适配会出现问题 +- 部分推理后端与 langchain 的适配有问题: - 目前的知识库的图片存在公开访问风险 - 工具传递给模型的时候,使用英文,但部分模型不支持中文函数名(如gpt-4o-mini) - 首页加载的问题 diff --git a/src/agents/chatbot/tools.py b/src/agents/chatbot/tools.py index 0a7114cb..c19d7707 100644 --- a/src/agents/chatbot/tools.py +++ b/src/agents/chatbot/tools.py @@ -12,8 +12,8 @@ from src.utils import logger @tool -async def text_to_img_qwen(text: str) -> str: - """(用来测试文件存储)使用模型生成图片, 会返回图片的URL""" +async def text_to_img_demo(text: str) -> str: + """【测试用】使用模型生成图片, 会返回图片的URL""" url = "https://api.siliconflow.cn/v1/images/generations" @@ -27,13 +27,13 @@ async def text_to_img_qwen(text: str) -> str: response = requests.post(url, json=payload, headers=headers) response_json = response.json() except Exception as e: - logger.error(f"Failed to generate image with Kolors: {e}") + logger.error(f"Failed to generate image with: {e}") raise ValueError(f"Image generation failed: {e}") try: image_url = response_json["images"][0]["url"] except (KeyError, IndexError, TypeError) as e: - logger.error(f"Failed to parse image URL from Kolors response: {e}, {response_json=}") + logger.error(f"Failed to parse image URL from response: {e}, {response_json=}") raise ValueError(f"Image URL extraction failed: {e}") # 2. Upload to MinIO (Simplified) @@ -51,6 +51,6 @@ async def text_to_img_qwen(text: str) -> str: def get_tools() -> list[Any]: """获取所有可运行的工具(给大模型使用)""" tools = get_buildin_tools() - tools.append(text_to_img_qwen) + tools.append(text_to_img_demo) tools.extend(get_mysql_tools()) return tools diff --git a/web/src/assets/css/base.dark.css b/web/src/assets/css/base.dark.css index 406cd904..9c2daee7 100644 --- a/web/src/assets/css/base.dark.css +++ b/web/src/assets/css/base.dark.css @@ -107,12 +107,12 @@ --color-text-tertiary: rgba(255, 255, 255, 0.45); /* Shadow System - 深色模式阴影系统 */ - --shadow-0: rgba(0, 0, 0, 0.1); - --shadow-1: rgba(0, 0, 0, 0.2); - --shadow-2: rgba(0, 0, 0, 0.3); - --shadow-3: rgba(0, 0, 0, 0.4); - --shadow-4: rgba(0, 0, 0, 0.5); - --shadow-5: rgba(0, 0, 0, 0.6); + --shadow-0: rgba(255, 255, 255, 0.02); + --shadow-1: rgba(255, 255, 255, 0.05); + --shadow-2: rgba(255, 255, 255, 0.08); + --shadow-3: rgba(255, 255, 255, 0.12); + --shadow-4: rgba(255, 255, 255, 0.16); + --shadow-5: rgba(255, 255, 255, 0.20); --color-trans-light: rgba(0, 0, 0, 0.85); diff --git a/web/src/components/AgentConfigSidebar.vue b/web/src/components/AgentConfigSidebar.vue index 1b01a2d4..fabd44a4 100644 --- a/web/src/components/AgentConfigSidebar.vue +++ b/web/src/components/AgentConfigSidebar.vue @@ -684,7 +684,8 @@ const resetConfig = async () => { background-color: var(--gray-25); padding: 12px; border-radius: 8px; - box-shadow: 0px 1px 1px var(--shadow-2); + border: 1px solid var(--gray-100); + // box-shadow: 0px 0px 2px var(--shadow-3); :deep(label.form_item_model) { font-weight: 600; diff --git a/web/src/components/AgentMessageComponent.vue b/web/src/components/AgentMessageComponent.vue index ace57a95..332e7a35 100644 --- a/web/src/components/AgentMessageComponent.vue +++ b/web/src/components/AgentMessageComponent.vue @@ -4,6 +4,10 @@
@@ -63,14 +63,13 @@ import { ref, computed, reactive, onMounted } from 'vue' import { useClipboard } from '@vueuse/core' import { message } from 'ant-design-vue' import { - CopyOutlined, - BulbOutlined, - ReloadOutlined, - LikeOutlined, - LikeFilled, - DislikeOutlined, - DislikeFilled, -} from '@ant-design/icons-vue' + ThumbsUp, + ThumbsDown, + Bot, + Copy, + Check, + RotateCcw, +} from 'lucide-vue-next' import { agentApi } from '@/apis' const emit = defineEmits(['retry', 'openRefs']); @@ -110,12 +109,19 @@ const showKey = (key) => { return props.showRefs.includes(key) } +// 复制状态 +const isCopied = ref(false) + // 定义 copy 方法 const copyText = async (text) => { if (isSupported) { try { await copy(text) message.success('文本已复制到剪贴板') + isCopied.value = true + setTimeout(() => { + isCopied.value = false + }, 2000) } catch (error) { console.error('复制失败:', error) message.error('复制失败,请手动复制') @@ -255,11 +261,16 @@ const cancelDislike = () => { .item { background: var(--gray-50); color: var(--gray-700); - padding: 2px 8px; + padding: 6px 8px; border-radius: 8px; font-size: 13px; user-select: none; transition: all 0.2s ease; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 4px; + line-height: 1; &.btn { cursor: pointer; @@ -272,8 +283,6 @@ const cancelDislike = () => { // Disabled state - when feedback has been submitted &.disabled { - cursor: not-allowed; - opacity: 0.7; &:hover { background: var(--gray-50);