diff --git a/src/agents/chatbot/graph.py b/src/agents/chatbot/graph.py
index 9d4ab4cd..902a4eea 100644
--- a/src/agents/chatbot/graph.py
+++ b/src/agents/chatbot/graph.py
@@ -51,9 +51,11 @@ class ChatbotAgent(BaseAgent):
system_prompt = f"{conf.system_prompt} Now is {get_cur_time_with_utc()}"
model = load_chat_model(conf.model)
- model_with_tools = model.bind_tools(self._get_tools(conf.tools))
- res = model_with_tools.invoke(
+ if tools := self._get_tools(conf.tools):
+ model = model.bind_tools(tools)
+
+ res = model.invoke(
[{"role": "system", "content": system_prompt}, *state["messages"]]
)
return {"messages": [res]}
diff --git a/src/agents/tools_factory.py b/src/agents/tools_factory.py
index b93960d5..69c4461c 100644
--- a/src/agents/tools_factory.py
+++ b/src/agents/tools_factory.py
@@ -81,7 +81,7 @@ def get_all_tools():
# 获取所有知识库
for db_Id, retrieve_info in knowledge_base.get_retrievers().items():
- name = f"retrieve_{retrieve_info['name']}"
+ name = f"retrieve_{db_Id}" # Deepseek does not support non-alphanumeric characters in tool names
description = (
f"使用 {retrieve_info['name']} 知识库进行检索。\n"
f"下面是这个知识库的描述:\n{retrieve_info['description']}"
diff --git a/web/src/views/AgentView.vue b/web/src/views/AgentView.vue
index d8db097d..fa290037 100644
--- a/web/src/views/AgentView.vue
+++ b/web/src/views/AgentView.vue
@@ -62,6 +62,18 @@
{{ selectedAgent.description }}
{{ selectedAgent }}
+
+
+
+
+
@@ -78,7 +90,7 @@
-
注意,部分模型对于 Tool Calling 的支持不稳定,建议采用{{ value.options }}
+
-
-
-
+
+
+
+
已选择 {{ getSelectedCount(key) }} 项
+
+ 清空
+
+
+
+
+
+
@@ -163,7 +190,9 @@ import {
LinkOutlined,
StarOutlined,
MenuOutlined,
- StarFilled
+ StarFilled,
+ CheckCircleOutlined,
+ PlusCircleOutlined
} from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import AgentChatComponent from '@/components/AgentChatComponent.vue';
@@ -215,6 +244,42 @@ const setAsDefaultAgent = async () => {
}
};
+// 多选组件相关方法
+const ensureArray = (key) => {
+ if (!agentConfig.value[key] || !Array.isArray(agentConfig.value[key])) {
+ agentConfig.value[key] = [];
+ }
+};
+
+const isOptionSelected = (key, option) => {
+ ensureArray(key);
+ return agentConfig.value[key].includes(option);
+};
+
+const getSelectedCount = (key) => {
+ ensureArray(key);
+ return agentConfig.value[key].length;
+};
+
+const toggleOption = (key, option) => {
+ ensureArray(key);
+
+ const currentOptions = [...agentConfig.value[key]];
+ const index = currentOptions.indexOf(option);
+
+ if (index > -1) {
+ currentOptions.splice(index, 1);
+ } else {
+ currentOptions.push(option);
+ }
+
+ agentConfig.value[key] = currentOptions;
+};
+
+const clearSelection = (key) => {
+ agentConfig.value[key] = [];
+};
+
// 获取默认智能体ID
const fetchDefaultAgent = async () => {
try {
@@ -278,6 +343,9 @@ const loadAgentConfig = async () => {
// 根据类型设置默认值
if (typeof item.default === 'boolean') {
agentConfig.value[key] = item.default;
+ } else if (item.type === 'list') {
+ // 对于 list 类型,确保初始化为数组
+ agentConfig.value[key] = Array.isArray(item.default) ? item.default : [];
} else {
agentConfig.value[key] = item.default || '';
}
@@ -290,7 +358,13 @@ const loadAgentConfig = async () => {
// 合并服务器配置
Object.keys(response.config).forEach(key => {
if (key in agentConfig.value) {
- agentConfig.value[key] = response.config[key];
+ const item = items[key];
+ // 对于 list 类型,确保是数组
+ if (item && item.type === 'list') {
+ agentConfig.value[key] = Array.isArray(response.config[key]) ? response.config[key] : [];
+ } else {
+ agentConfig.value[key] = response.config[key];
+ }
}
});
console.log(`从服务器加载 ${selectedAgentId.value} 配置成功, ${JSON.stringify(agentConfig.value)}`);
@@ -568,7 +642,6 @@ const toggleSidebar = () => {
// 添加requirements相关样式
.info-section {
margin-top: 16px;
- border-top: 1px solid var(--main-light-3);
padding-top: 12px;
h3 {
@@ -693,6 +766,92 @@ const toggleSidebar = () => {
font-size: 14px;
}
}
+
+// 多选卡片样式
+.multi-select-cards {
+ .multi-select-label {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+ font-size: 12px;
+ color: var(--gray-600);
+ height: 24px;
+ }
+
+ .options-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
+ gap: 8px;
+ }
+
+ .option-card {
+ border: 1px solid var(--gray-300);
+ border-radius: 8px;
+ padding: 8px 12px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ background: white;
+ user-select: none;
+
+ &:hover {
+ border-color: var(--main-color);
+ }
+
+ &.selected {
+ border-color: var(--main-color);
+ background: var(--main-10);
+
+ .option-indicator {
+ color: var(--main-color);
+ }
+
+ .option-text {
+ color: var(--main-color);
+ font-weight: 500;
+ }
+ }
+
+ &.unselected {
+ .option-indicator {
+ color: var(--gray-400);
+ }
+
+ .option-text {
+ color: var(--gray-700);
+ }
+ }
+
+ .option-content {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .option-text {
+ flex: 1;
+ font-size: 14px;
+ line-height: 1.4;
+ word-break: break-word;
+ }
+
+ .option-indicator {
+ flex-shrink: 0;
+ font-size: 16px;
+ transition: color 0.2s ease;
+ }
+ }
+}
+
+// 响应式适配
+@media (max-width: 768px) {
+ .multi-select-cards {
+ .options-grid {
+ grid-template-columns: 1fr;
+ }
+ }
+}