Files
metona-ollama-desktop/src/renderer/components/tools-modal.ts
T
thzxx e3b44a0357 feat: 移除所有工具结果截断,确保内容完整传给AI
删除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)
2026-07-09 22:31:04 +08:00

88 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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';
}