From 423f3aa717b7fcbea7c7dd405d0209add810a89c Mon Sep 17 00:00:00 2001 From: hubian <908234780@qq.com> Date: Mon, 27 Apr 2026 12:51:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=90=8E=E5=8F=B0=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E9=85=8D=E7=BD=AE+=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增对话配置页面: - 配置普通对话使用的LLM、可用工具 - 历史记录数、Temperature、系统提示词 - 支持多配置、设为默认 搜索配置改为工具配置: - 工具类型: search/calculator/image/code/weather/custom - 搜索作为工具之一管理 - 支持添加多种工具 - 工具配置: ID、名称、类型、提供商、API、Key、额外配置 API新增: - /api/admin/chat - 对话配置CRUD - /api/admin/tools - 工具配置CRUD - /api/config 返回 tools 和 chat_config --- backend/app.py | 187 +++++++++++++++++----- www/admin.html | 10 +- www/admin.js | 409 +++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 484 insertions(+), 122 deletions(-) diff --git a/backend/app.py b/backend/app.py index 0b4b103..25ccfb0 100644 --- a/backend/app.py +++ b/backend/app.py @@ -76,14 +76,17 @@ def init_db(): ) ''') - # 搜索配置表 + # 搜索配置表(改为工具配置) cursor.execute(''' - CREATE TABLE IF NOT EXISTS search_configs ( + CREATE TABLE IF NOT EXISTS tool_configs ( id INTEGER PRIMARY KEY AUTOINCREMENT, + tool_id TEXT NOT NULL UNIQUE, name TEXT NOT NULL, + type TEXT NOT NULL, provider TEXT NOT NULL, api_url TEXT NOT NULL, - api_key TEXT NOT NULL, + api_key TEXT, + config_json TEXT, max_results INTEGER DEFAULT 10, is_default INTEGER DEFAULT 0, is_active INTEGER DEFAULT 1, @@ -92,6 +95,24 @@ def init_db(): ) ''') + # 对话配置表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS chat_configs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + config_id TEXT NOT NULL UNIQUE, + name TEXT NOT NULL, + llm_config_id INTEGER, + enable_tools TEXT, + max_history INTEGER DEFAULT 20, + temperature REAL DEFAULT 0.7, + system_prompt TEXT, + is_default INTEGER DEFAULT 0, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (llm_config_id) REFERENCES llm_configs(id) + ) + ''') + # 系统配置表 cursor.execute(''' CREATE TABLE IF NOT EXISTS system_configs ( @@ -133,13 +154,21 @@ def init_db(): '2259e33a1357460abe17919aaf81e73d.K44a8LPQTmFM5PKm', 'glm-4.5-air', 1) ''') - # 初始化默认搜索配置 - cursor.execute('SELECT COUNT(*) FROM search_configs') + # 初始化默认工具配置(搜索工具) + cursor.execute('SELECT COUNT(*) FROM tool_configs') if cursor.fetchone()[0] == 0: cursor.execute(''' - INSERT INTO search_configs (name, provider, api_url, api_key, is_default) - VALUES ('Tavily', 'tavily', 'https://api.tavily.com/search', - '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', 1) + INSERT INTO tool_configs (tool_id, name, type, provider, api_url, api_key, max_results, is_default) + VALUES ('search', '联网搜索', 'search', 'tavily', 'https://api.tavily.com/search', + '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', 10, 1) + ''') + + # 初始化默认对话配置 + cursor.execute('SELECT COUNT(*) FROM chat_configs') + if cursor.fetchone()[0] == 0: + cursor.execute(''' + INSERT INTO chat_configs (config_id, name, llm_config_id, enable_tools, is_default) + VALUES ('default', '默认对话配置', 1, 'search', 1) ''') # 初始化默认智能体 @@ -391,69 +420,140 @@ def delete_agent(agent_id): return jsonify({'success': True}) -# ==================== 搜索配置管理 ==================== +# ==================== 对话配置管理 ==================== -@app.route('/api/admin/search', methods=['GET']) -def get_search_configs(): - """获取搜索配置""" +@app.route('/api/admin/chat', methods=['GET']) +def get_chat_configs(): + """获取对话配置""" conn = get_db() cursor = conn.cursor() - cursor.execute('SELECT * FROM search_configs ORDER BY is_default DESC') + cursor.execute('SELECT * FROM chat_configs ORDER BY is_default DESC') configs = [dict(row) for row in cursor.fetchall()] conn.close() return jsonify(configs) -@app.route('/api/admin/search', methods=['POST']) -def add_search_config(): - """添加搜索配置""" +@app.route('/api/admin/chat', methods=['POST']) +def add_chat_config(): + """添加对话配置""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute(''' - INSERT INTO search_configs (name, provider, api_url, api_key, max_results) - VALUES (?, ?, ?, ?, ?) - ''', (data['name'], data['provider'], data['api_url'], data['api_key'], + INSERT INTO chat_configs (config_id, name, llm_config_id, enable_tools, max_history, temperature, system_prompt) + VALUES (?, ?, ?, ?, ?, ?, ?) + ''', (data['config_id'], data['name'], data.get('llm_config_id'), data.get('enable_tools', ''), + data.get('max_history', 20), data.get('temperature', 0.7), data.get('system_prompt', ''))) + conn.commit() + conn.close() + return jsonify({'success': True}) + + +@app.route('/api/admin/chat/', methods=['PUT']) +def update_chat_config(config_id): + """更新对话配置""" + data = request.json + conn = get_db() + cursor = conn.cursor() + cursor.execute(''' + UPDATE chat_configs SET name=?, llm_config_id=?, enable_tools=?, max_history=?, + temperature=?, system_prompt=?, updated_at=CURRENT_TIMESTAMP WHERE config_id=? + ''', (data['name'], data.get('llm_config_id'), data.get('enable_tools', ''), + data.get('max_history', 20), data.get('temperature', 0.7), + data.get('system_prompt', ''), config_id)) + conn.commit() + conn.close() + return jsonify({'success': True}) + + +@app.route('/api/admin/chat/', methods=['DELETE']) +def delete_chat_config(config_id): + """删除对话配置""" + conn = get_db() + cursor = conn.cursor() + cursor.execute('DELETE FROM chat_configs WHERE config_id=?', (config_id,)) + conn.commit() + conn.close() + return jsonify({'success': True}) + + +@app.route('/api/admin/chat//default', methods=['POST']) +def set_default_chat(config_id): + """设置默认对话配置""" + conn = get_db() + cursor = conn.cursor() + cursor.execute('UPDATE chat_configs SET is_default=0') + cursor.execute('UPDATE chat_configs SET is_default=1 WHERE config_id=?', (config_id,)) + conn.commit() + conn.close() + return jsonify({'success': True}) + + +# ==================== 工具配置管理 ==================== + +@app.route('/api/admin/tools', methods=['GET']) +def get_tool_configs(): + """获取工具配置""" + conn = get_db() + cursor = conn.cursor() + cursor.execute('SELECT * FROM tool_configs ORDER BY is_default DESC, type') + tools = [dict(row) for row in cursor.fetchall()] + conn.close() + return jsonify(tools) + + +@app.route('/api/admin/tools', methods=['POST']) +def add_tool_config(): + """添加工具配置""" + data = request.json + conn = get_db() + cursor = conn.cursor() + cursor.execute(''' + INSERT INTO tool_configs (tool_id, name, type, provider, api_url, api_key, config_json, max_results) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ''', (data['tool_id'], data['name'], data['type'], data['provider'], + data['api_url'], data.get('api_key', ''), data.get('config_json', ''), data.get('max_results', 10))) conn.commit() conn.close() return jsonify({'success': True}) -@app.route('/api/admin/search/', methods=['PUT']) -def update_search_config(id): - """更新搜索配置""" +@app.route('/api/admin/tools/', methods=['PUT']) +def update_tool_config(tool_id): + """更新工具配置""" data = request.json conn = get_db() cursor = conn.cursor() cursor.execute(''' - UPDATE search_configs SET name=?, provider=?, api_url=?, api_key=?, max_results=?, - updated_at=CURRENT_TIMESTAMP WHERE id=? - ''', (data['name'], data['provider'], data['api_url'], data['api_key'], - data.get('max_results', 10), id)) + UPDATE tool_configs SET name=?, type=?, provider=?, api_url=?, api_key=?, + config_json=?, max_results=?, updated_at=CURRENT_TIMESTAMP WHERE tool_id=? + ''', (data['name'], data['type'], data['provider'], data['api_url'], + data.get('api_key', ''), data.get('config_json', ''), + data.get('max_results', 10), tool_id)) conn.commit() conn.close() return jsonify({'success': True}) -@app.route('/api/admin/search/', methods=['DELETE']) -def delete_search_config(id): - """删除搜索配置""" +@app.route('/api/admin/tools/', methods=['DELETE']) +def delete_tool_config(tool_id): + """删除工具配置""" conn = get_db() cursor = conn.cursor() - cursor.execute('DELETE FROM search_configs WHERE id=?', (id,)) + cursor.execute('DELETE FROM tool_configs WHERE tool_id=?', (tool_id,)) conn.commit() conn.close() return jsonify({'success': True}) -@app.route('/api/admin/search//default', methods=['POST']) -def set_default_search(id): - """设置默认搜索""" +@app.route('/api/admin/tools//default', methods=['POST']) +def set_default_tool(tool_id): + """设置默认工具""" conn = get_db() cursor = conn.cursor() - cursor.execute('UPDATE search_configs SET is_default=0') - cursor.execute('UPDATE search_configs SET is_default=1 WHERE id=?', (id,)) + cursor.execute('UPDATE tool_configs SET is_default=0 WHERE type=(SELECT type FROM tool_configs WHERE tool_id=?)', (tool_id,)) + cursor.execute('UPDATE tool_configs SET is_default=1 WHERE tool_id=?', (tool_id,)) conn.commit() conn.close() return jsonify({'success': True}) @@ -564,14 +664,18 @@ def get_frontend_config(): cursor.execute('SELECT * FROM llm_configs WHERE is_default=1 AND is_active=1 LIMIT 1') llm = cursor.fetchone() - # 获取默认搜索配置 - cursor.execute('SELECT * FROM search_configs WHERE is_default=1 AND is_active=1 LIMIT 1') - search = cursor.fetchone() + # 获取默认工具配置(搜索等) + cursor.execute('SELECT * FROM tool_configs WHERE is_default=1 AND is_active=1') + tools = [dict(row) for row in cursor.fetchall()] # 获取所有智能体 - cursor.execute('SELECT agent_id, name, avatar, category, description, system_prompt, heat FROM agents WHERE is_active=1') + cursor.execute('SELECT agent_id, name, avatar, category, description, system_prompt, heat, enable_search FROM agents WHERE is_active=1') agents = [dict(row) for row in cursor.fetchall()] + # 获取默认对话配置 + cursor.execute('SELECT * FROM chat_configs WHERE is_default=1 LIMIT 1') + chat_config = cursor.fetchone() + # 获取系统配置 cursor.execute('SELECT key, value FROM system_configs') system = {row['key']: row['value'] for row in cursor.fetchall()} @@ -580,11 +684,12 @@ def get_frontend_config(): config = { 'llm': dict(llm) if llm else None, - 'search': dict(search) if search else None, + 'tools': tools, 'agents': agents, + 'chat_config': dict(chat_config) if chat_config else None, 'system': { 'appName': system.get('app_name', 'AI助手'), - 'version': system.get('app_version', '3.5.1'), + 'version': system.get('app_version', '3.6.0'), 'enableSearch': system.get('enable_search', 'true') == 'true', 'guestLimits': { 'chatSessions': int(system.get('guest_chat_sessions', '1')), diff --git a/www/admin.html b/www/admin.html index d5f8bf1..2734b65 100644 --- a/www/admin.html +++ b/www/admin.html @@ -440,9 +440,13 @@ 🤖 智能体管理 -