删除TOOL_MAX_RESULT_SIZE配置表和formatDefaultToolResult截断; read_file移除2000行/100KB截断; read_multiple_files移除10000字符截断; list_directory移除2000条目上限; search_files移除10条匹配和50结果限制; run_command移除512KB输出截断; browser_extract移除15000字符截断; session_read移除50条消息限制; session_list移除20条限制; memory search移除8条限制; web_search移除10条结果限制; SearXNG HTML移除内容截断; 版本号升级至0.14.11; 实现工具三档执行模式(auto/confirm/disabled)
88 lines
3.0 KiB
TypeScript
88 lines
3.0 KiB
TypeScript
/**
|
||
* ToolsModal - 工具面板模态框
|
||
* 展示所有可用工具的详细信息。Tool Calling 始终开启,不可关闭。
|
||
* 支持三档开关(auto/confirm/disabled)的工具统一管理。
|
||
*/
|
||
|
||
import { state, KEYS } from '../state/state.js';
|
||
import { setToolMode, getToolMode, type ToolMode } from '../services/tool-registry.js';
|
||
import { showToast } from './toast.js';
|
||
import { logInfo } from '../services/log-service.js';
|
||
import type { ChatDB } from '../db/chat-db.js';
|
||
|
||
let modalEl: HTMLElement;
|
||
|
||
const MODE_NAMES: Record<ToolMode, string> = {
|
||
auto: '自动执行',
|
||
confirm: '需确认',
|
||
disabled: '已禁用',
|
||
};
|
||
|
||
const BADGE_MAP: Record<ToolMode, { text: string; cls: string }> = {
|
||
auto: { text: '自动', cls: 'auto' },
|
||
confirm: { text: '需确认', cls: 'confirm' },
|
||
disabled: { text: '禁用', cls: 'disabled' },
|
||
};
|
||
|
||
function updateToolBadge(toolName: string, mode: ToolMode): void {
|
||
const badge = modalEl.querySelector(`#badge_${toolName}`) as HTMLElement;
|
||
if (!badge) return;
|
||
const info = BADGE_MAP[mode];
|
||
badge.textContent = info.text;
|
||
badge.className = `tool-card-badge ${info.cls}`;
|
||
}
|
||
|
||
export function initToolsModal(): void {
|
||
modalEl = document.querySelector('#toolsModal')!;
|
||
|
||
// Header 按钮
|
||
document.querySelector('#btnTools')!.addEventListener('click', openToolsModal);
|
||
document.querySelector('#btnCloseTools')!.addEventListener('click', closeToolsModal);
|
||
modalEl.addEventListener('click', (e) => {
|
||
if (e.target === modalEl) closeToolsModal();
|
||
});
|
||
|
||
// 所有带 .tool-mode-select 的下拉框统一绑定 change 事件
|
||
const selects = modalEl.querySelectorAll<HTMLSelectElement>('.tool-mode-select');
|
||
selects.forEach(selectEl => {
|
||
selectEl.addEventListener('change', async () => {
|
||
const toolName = selectEl.dataset.tool;
|
||
if (!toolName) return;
|
||
const mode = selectEl.value as ToolMode;
|
||
const db = state.get<ChatDB | null>(KEYS.DB);
|
||
|
||
// 更新运行时模式
|
||
setToolMode(toolName, mode);
|
||
updateToolBadge(toolName, mode);
|
||
|
||
// 持久化到数据库(所有工具模式合并存储为 JSON)
|
||
const allModes = state.get<Record<string, ToolMode>>('toolModes', {});
|
||
allModes[toolName] = mode;
|
||
state.set('toolModes', allModes);
|
||
if (db) await db.saveSetting('toolModes', allModes);
|
||
|
||
showToast(`${toolName}:${MODE_NAMES[mode]}`, 'info');
|
||
logInfo(`工具模式切换: ${toolName} → ${mode}`);
|
||
});
|
||
});
|
||
}
|
||
|
||
export function openToolsModal(): void {
|
||
// 从 state 读取所有工具模式,同步 UI
|
||
const allModes = state.get<Record<string, ToolMode>>('toolModes', {});
|
||
const selects = modalEl.querySelectorAll<HTMLSelectElement>('.tool-mode-select');
|
||
selects.forEach(selectEl => {
|
||
const toolName = selectEl.dataset.tool;
|
||
if (!toolName) return;
|
||
const mode = allModes[toolName] || getToolMode(toolName);
|
||
selectEl.value = mode;
|
||
updateToolBadge(toolName, mode);
|
||
});
|
||
|
||
modalEl.style.display = '';
|
||
}
|
||
|
||
export function closeToolsModal(): void {
|
||
modalEl.style.display = 'none';
|
||
}
|