mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-14 18:39:54 +08:00
✨ feat(ai-tools): 新增安全边界探针并拆分工具注册
This commit is contained in:
@@ -28,6 +28,8 @@ describe('AIBuiltinToolsCatalog', () => {
|
||||
expect(markup).toContain('inspect_database_bundle');
|
||||
expect(markup).toContain('查看 AI 当前能力');
|
||||
expect(markup).toContain('inspect_ai_runtime');
|
||||
expect(markup).toContain('核对写入安全边界');
|
||||
expect(markup).toContain('inspect_ai_safety');
|
||||
expect(markup).toContain('排查供应商与模型');
|
||||
expect(markup).toContain('inspect_ai_providers');
|
||||
expect(markup).toContain('排查聊天发送状态');
|
||||
|
||||
@@ -42,6 +42,11 @@ const BUILTIN_TOOL_FLOWS = [
|
||||
steps: 'inspect_ai_runtime → inspect_ai_context / inspect_current_connection',
|
||||
description: '适合先确认当前模型、安全级别、上下文级别、Skills 和 MCP 工具,再决定让 AI 走哪条探针链路。',
|
||||
},
|
||||
{
|
||||
title: '核对写入安全边界',
|
||||
steps: 'inspect_ai_safety → inspect_ai_runtime → inspect_current_connection',
|
||||
description: '适合先确认当前是不是只读、DDL/DML 到底允不允许、MCP 写操作是否还需要 allowMutating,再决定后续该走查询、改数据还是改结构。',
|
||||
},
|
||||
{
|
||||
title: '排查供应商与模型',
|
||||
steps: 'inspect_ai_providers → inspect_ai_runtime',
|
||||
|
||||
@@ -224,6 +224,57 @@ describe('aiLocalToolExecutor', () => {
|
||||
expect(result.content).toContain('"builtinToolCount":');
|
||||
});
|
||||
|
||||
it('returns the current ai safety snapshot so the model can inspect write boundaries and readonly guards', async () => {
|
||||
const result = await executeLocalAIToolCall({
|
||||
toolCall: buildToolCall('inspect_ai_safety', {}),
|
||||
connections: [{
|
||||
id: 'jvm-1',
|
||||
name: 'JVM 诊断环境',
|
||||
config: {
|
||||
type: 'jvm',
|
||||
host: '10.0.0.8',
|
||||
port: 0,
|
||||
user: '',
|
||||
jvm: {
|
||||
environment: 'uat',
|
||||
readOnly: true,
|
||||
diagnostic: {
|
||||
transport: 'agent-bridge',
|
||||
allowObserveCommands: true,
|
||||
allowTraceCommands: true,
|
||||
allowMutatingCommands: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}],
|
||||
tabs: [{
|
||||
id: 'diag-tab-1',
|
||||
title: 'JVM 诊断',
|
||||
type: 'jvm-diagnostic',
|
||||
connectionId: 'jvm-1',
|
||||
readOnly: true,
|
||||
}],
|
||||
activeTabId: 'diag-tab-1',
|
||||
mcpTools: [],
|
||||
toolContextMap: new Map(),
|
||||
runtime: {
|
||||
getDatabases: vi.fn(),
|
||||
getTables: vi.fn(),
|
||||
getAIRuntimeState: vi.fn().mockResolvedValue({
|
||||
safetyLevel: 'readwrite',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.content).toContain('"safetyLevel":"readwrite"');
|
||||
expect(result.content).toContain('"allowDML":true');
|
||||
expect(result.content).toContain('"allowDDL":false');
|
||||
expect(result.content).toContain('"readOnly":true');
|
||||
expect(result.content).toContain('"allowMutatingCommands":false');
|
||||
expect(result.content).toContain('allowMutating=true');
|
||||
});
|
||||
|
||||
it('returns the current ai provider snapshot so the model can inspect provider readiness and model selection', async () => {
|
||||
const result = await executeLocalAIToolCall({
|
||||
toolCall: buildToolCall('inspect_ai_providers', {}),
|
||||
|
||||
65
frontend/src/components/ai/aiSafetyInsights.test.ts
Normal file
65
frontend/src/components/ai/aiSafetyInsights.test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { buildAISafetySnapshot } from './aiSafetyInsights';
|
||||
|
||||
describe('buildAISafetySnapshot', () => {
|
||||
it('describes readonly ai safety when no active connection is selected', () => {
|
||||
const snapshot = buildAISafetySnapshot({
|
||||
safetyLevel: 'readonly',
|
||||
connections: [],
|
||||
});
|
||||
|
||||
expect(snapshot.safetyLevel).toBe('readonly');
|
||||
expect(snapshot.permissionMatrix.allowQuery).toBe(true);
|
||||
expect(snapshot.permissionMatrix.allowDML).toBe(false);
|
||||
expect(snapshot.permissionMatrix.allowDDL).toBe(false);
|
||||
expect(snapshot.hasActiveConnection).toBe(false);
|
||||
expect(snapshot.effectiveRestrictions).toContain('只读模式仅允许查询语句。');
|
||||
expect(snapshot.recommendations).toContain('如需执行 INSERT/UPDATE/DELETE,请先把 AI 安全级别切到读写模式。');
|
||||
});
|
||||
|
||||
it('includes jvm connection restrictions and MCP write confirmation hints', () => {
|
||||
const snapshot = buildAISafetySnapshot({
|
||||
safetyLevel: 'readwrite',
|
||||
connections: [
|
||||
{
|
||||
id: 'jvm-1',
|
||||
name: 'JVM 诊断环境',
|
||||
config: {
|
||||
type: 'jvm',
|
||||
host: '10.0.0.8',
|
||||
port: 0,
|
||||
user: '',
|
||||
jvm: {
|
||||
environment: 'uat',
|
||||
readOnly: true,
|
||||
diagnostic: {
|
||||
transport: 'agent-bridge',
|
||||
allowObserveCommands: true,
|
||||
allowTraceCommands: true,
|
||||
allowMutatingCommands: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
tabs: [
|
||||
{
|
||||
id: 'diag-tab-1',
|
||||
title: 'JVM 诊断',
|
||||
type: 'jvm-diagnostic',
|
||||
connectionId: 'jvm-1',
|
||||
readOnly: true,
|
||||
},
|
||||
],
|
||||
activeTabId: 'diag-tab-1',
|
||||
});
|
||||
|
||||
expect(snapshot.permissionMatrix.allowDML).toBe(true);
|
||||
expect(snapshot.permissionMatrix.allowDDL).toBe(false);
|
||||
expect(snapshot.activeConnection?.readOnly).toBe(true);
|
||||
expect(snapshot.jvmGuards?.allowMutatingCommands).toBe(false);
|
||||
expect(snapshot.effectiveRestrictions.join('\n')).toContain('allowMutating=true');
|
||||
expect(snapshot.effectiveRestrictions.join('\n')).toContain('当前 JVM 诊断明确禁止 mutating 命令');
|
||||
});
|
||||
});
|
||||
135
frontend/src/components/ai/aiSafetyInsights.ts
Normal file
135
frontend/src/components/ai/aiSafetyInsights.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
import type { AISafetyLevel, SavedConnection, TabData } from '../../types';
|
||||
|
||||
const SAFETY_LEVEL_LABELS: Record<string, string> = {
|
||||
readonly: '只读',
|
||||
readwrite: '读写',
|
||||
full: '完全开放',
|
||||
};
|
||||
|
||||
const SAFETY_RULE_TEXTS: Record<string, string> = {
|
||||
readonly: '只读模式仅允许查询语句。',
|
||||
readwrite: '读写模式允许查询和 DML,DDL 仍会被阻止。',
|
||||
full: '完全开放模式允许查询、DML 和 DDL;未识别操作仍会被阻止。',
|
||||
};
|
||||
|
||||
const normalizeSafetyLevel = (value: AISafetyLevel | string | undefined): string => {
|
||||
const level = String(value || 'readonly').trim().toLowerCase();
|
||||
if (level === 'readwrite' || level === 'full') {
|
||||
return level;
|
||||
}
|
||||
return 'readonly';
|
||||
};
|
||||
|
||||
const buildPermissionMatrix = (safetyLevel: string) => ({
|
||||
allowQuery: true,
|
||||
allowDML: safetyLevel === 'readwrite' || safetyLevel === 'full',
|
||||
allowDDL: safetyLevel === 'full',
|
||||
requiresConfirmationForAllowedNonQuery: true,
|
||||
requiresMCPAllowMutatingForAllowedNonQuery: true,
|
||||
});
|
||||
|
||||
export const buildAISafetySnapshot = (params: {
|
||||
safetyLevel?: AISafetyLevel | string;
|
||||
activeContext?: { connectionId: string; dbName?: string } | null;
|
||||
tabs?: TabData[];
|
||||
activeTabId?: string | null;
|
||||
connections: SavedConnection[];
|
||||
}) => {
|
||||
const {
|
||||
safetyLevel,
|
||||
activeContext = null,
|
||||
tabs = [],
|
||||
activeTabId = null,
|
||||
connections,
|
||||
} = params;
|
||||
|
||||
const normalizedSafetyLevel = normalizeSafetyLevel(safetyLevel);
|
||||
const activeTab = tabs.find((tab) => tab.id === activeTabId);
|
||||
const connectionId = String(activeContext?.connectionId || activeTab?.connectionId || '').trim();
|
||||
const activeDbName = String(activeContext?.dbName || activeTab?.dbName || '').trim();
|
||||
const connection = connectionId
|
||||
? connections.find((item) => item.id === connectionId)
|
||||
: undefined;
|
||||
const config = connection?.config;
|
||||
const jvm = config?.jvm;
|
||||
const diagnostic = jvm?.diagnostic;
|
||||
const isJVMSession = config?.type === 'jvm';
|
||||
const activeResultReadOnly = activeTab?.readOnly === true;
|
||||
const jvmReadOnly = isJVMSession && jvm?.readOnly !== false;
|
||||
|
||||
const effectiveRestrictions = [
|
||||
SAFETY_RULE_TEXTS[normalizedSafetyLevel] || SAFETY_RULE_TEXTS.readonly,
|
||||
];
|
||||
if (normalizedSafetyLevel === 'readonly') {
|
||||
effectiveRestrictions.push('当前安全级别下,任何 DML/DDL 都会被直接阻止。');
|
||||
} else {
|
||||
effectiveRestrictions.push('任何允许通过的非查询语句都仍然需要人工确认。');
|
||||
effectiveRestrictions.push('如果通过 GoNavi MCP 的 execute_sql 执行非查询语句,还必须显式传 allowMutating=true。');
|
||||
}
|
||||
if (activeResultReadOnly) {
|
||||
effectiveRestrictions.push('当前活动页签结果集是只读的,不能把它当成可直接回写的数据网格。');
|
||||
}
|
||||
if (jvmReadOnly) {
|
||||
effectiveRestrictions.push('当前 JVM 连接本身是只读连接,默认只能按观察/排障思路生成诊断计划。');
|
||||
}
|
||||
if (isJVMSession && diagnostic?.allowMutatingCommands !== true) {
|
||||
effectiveRestrictions.push('当前 JVM 诊断明确禁止 mutating 命令,即使 AI 安全级别允许写入,也不能假设这类命令能执行。');
|
||||
}
|
||||
|
||||
const recommendations: string[] = [];
|
||||
if (normalizedSafetyLevel === 'readonly') {
|
||||
recommendations.push('如需执行 INSERT/UPDATE/DELETE,请先把 AI 安全级别切到读写模式。');
|
||||
recommendations.push('如需执行 CREATE/ALTER/DROP/TRUNCATE 等结构变更,请切到完全开放模式。');
|
||||
} else if (normalizedSafetyLevel === 'readwrite') {
|
||||
recommendations.push('当前已经允许 DML;如果目标是改表结构,仍需要切到完全开放模式。');
|
||||
}
|
||||
if (activeResultReadOnly) {
|
||||
recommendations.push('如果目标是编辑结果网格,请重新打开可编辑的表或查询结果,不要只看当前只读页签。');
|
||||
}
|
||||
if (jvmReadOnly) {
|
||||
recommendations.push('当前 JVM 连接按只读策略回答;需要变更类诊断前先确认连接策略是否应调整。');
|
||||
}
|
||||
if (isJVMSession && diagnostic?.allowMutatingCommands !== true) {
|
||||
recommendations.push('当前 JVM 诊断禁止 mutating 命令;如需执行高风险命令,应先调整诊断权限。');
|
||||
}
|
||||
|
||||
return {
|
||||
safetyLevel: normalizedSafetyLevel,
|
||||
safetyLabel: SAFETY_LEVEL_LABELS[normalizedSafetyLevel] || normalizedSafetyLevel,
|
||||
sqlRuleText: SAFETY_RULE_TEXTS[normalizedSafetyLevel] || SAFETY_RULE_TEXTS.readonly,
|
||||
permissionMatrix: buildPermissionMatrix(normalizedSafetyLevel),
|
||||
hasActiveConnection: Boolean(connection),
|
||||
activeConnection: connection
|
||||
? {
|
||||
connectionId: connection.id,
|
||||
connectionName: connection.name,
|
||||
connectionType: config?.type || '',
|
||||
host: config?.host || '',
|
||||
activeDbName: activeDbName || config?.database || '',
|
||||
readOnly: activeResultReadOnly || jvmReadOnly,
|
||||
}
|
||||
: null,
|
||||
activeTab: activeTab
|
||||
? {
|
||||
id: activeTab.id,
|
||||
title: activeTab.title || '',
|
||||
type: activeTab.type || '',
|
||||
readOnly: activeResultReadOnly,
|
||||
}
|
||||
: null,
|
||||
jvmGuards: isJVMSession
|
||||
? {
|
||||
readOnly: jvmReadOnly,
|
||||
transport: diagnostic?.transport || 'agent-bridge',
|
||||
allowObserveCommands: diagnostic?.allowObserveCommands !== false,
|
||||
allowTraceCommands: diagnostic?.allowTraceCommands === true,
|
||||
allowMutatingCommands: diagnostic?.allowMutatingCommands === true,
|
||||
}
|
||||
: null,
|
||||
effectiveRestrictions,
|
||||
recommendations,
|
||||
message: connection
|
||||
? `当前 AI 安全级别为 ${SAFETY_LEVEL_LABELS[normalizedSafetyLevel] || normalizedSafetyLevel},活动连接为 ${connection.name}`
|
||||
: `当前 AI 安全级别为 ${SAFETY_LEVEL_LABELS[normalizedSafetyLevel] || normalizedSafetyLevel},当前没有活动连接`,
|
||||
};
|
||||
};
|
||||
@@ -21,6 +21,7 @@ import { buildAIGuidanceSnapshot } from './aiPromptInsights';
|
||||
import { buildAIChatReadinessSnapshot } from './aiChatReadiness';
|
||||
import { buildAIProviderSnapshot } from './aiProviderInsights';
|
||||
import { buildAIRuntimeSnapshot } from './aiRuntimeInsights';
|
||||
import { buildAISafetySnapshot } from './aiSafetyInsights';
|
||||
import {
|
||||
buildSavedQueriesSnapshot,
|
||||
buildSqlSnippetsSnapshot,
|
||||
@@ -111,6 +112,21 @@ export async function executeSnapshotInspectionToolCall(
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
case 'inspect_ai_safety': {
|
||||
const runtimeState = typeof runtime?.getAIRuntimeState === 'function'
|
||||
? await runtime.getAIRuntimeState()
|
||||
: undefined;
|
||||
return {
|
||||
content: JSON.stringify(buildAISafetySnapshot({
|
||||
safetyLevel: runtimeState?.safetyLevel,
|
||||
activeContext,
|
||||
tabs,
|
||||
activeTabId,
|
||||
connections,
|
||||
})),
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
case 'inspect_ai_providers': {
|
||||
const runtimeState = typeof runtime?.getAIRuntimeState === 'function'
|
||||
? await runtime.getAIRuntimeState()
|
||||
@@ -254,6 +270,7 @@ export async function executeSnapshotInspectionToolCall(
|
||||
} catch (error: any) {
|
||||
const label = {
|
||||
inspect_ai_runtime: '读取当前 AI 运行状态失败',
|
||||
inspect_ai_safety: '读取当前 AI 安全边界失败',
|
||||
inspect_ai_providers: '读取当前 AI 供应商配置失败',
|
||||
inspect_ai_chat_readiness: '读取 AI 聊天发送前置状态失败',
|
||||
inspect_mcp_setup: '读取 MCP 配置状态失败',
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('buildAISystemContextMessages', () => {
|
||||
connections: [connections[0]],
|
||||
tabs: [],
|
||||
activeTabId: null,
|
||||
availableToolNames: ['inspect_workspace_tabs', 'inspect_ai_runtime', 'inspect_ai_providers', 'inspect_ai_chat_readiness', 'inspect_mcp_setup', 'inspect_ai_guidance', 'inspect_ai_context', 'inspect_current_connection', 'inspect_saved_connections', 'inspect_saved_queries', 'inspect_sql_snippets', 'get_columns'],
|
||||
availableToolNames: ['inspect_workspace_tabs', 'inspect_ai_runtime', 'inspect_ai_safety', 'inspect_ai_providers', 'inspect_ai_chat_readiness', 'inspect_mcp_setup', 'inspect_ai_guidance', 'inspect_ai_context', 'inspect_current_connection', 'inspect_saved_connections', 'inspect_saved_queries', 'inspect_sql_snippets', 'get_columns'],
|
||||
skills,
|
||||
userPromptSettings,
|
||||
});
|
||||
@@ -76,6 +76,7 @@ describe('buildAISystemContextMessages', () => {
|
||||
const joined = messages.map((message) => message.content).join('\n');
|
||||
expect(joined).toContain('inspect_workspace_tabs 盘点当前工作区');
|
||||
expect(joined).toContain('inspect_ai_runtime 读取当前 AI 运行状态');
|
||||
expect(joined).toContain('inspect_ai_safety 读取真实安全边界');
|
||||
expect(joined).toContain('inspect_ai_providers 读取真实供应商配置');
|
||||
expect(joined).toContain('inspect_ai_chat_readiness 读取真实发送前置状态');
|
||||
expect(joined).toContain('inspect_mcp_setup 读取真实 MCP 配置');
|
||||
|
||||
@@ -108,6 +108,19 @@ const appendAIRuntimeInspectionGuidance = (
|
||||
});
|
||||
};
|
||||
|
||||
const appendAISafetyInspectionGuidance = (
|
||||
messages: AISystemContextMessage[],
|
||||
availableToolNames: string[],
|
||||
) => {
|
||||
if (!availableToolNames.includes('inspect_ai_safety')) {
|
||||
return;
|
||||
}
|
||||
messages.push({
|
||||
role: 'system',
|
||||
content: '如果用户提到“为什么现在不能写”“当前是不是只读”“DDL 能不能执行”“allowMutating 要不要传”,优先调用 inspect_ai_safety 读取真实安全边界,不要只凭界面现象或记忆猜测。',
|
||||
});
|
||||
};
|
||||
|
||||
const appendAIProviderInspectionGuidance = (
|
||||
messages: AISystemContextMessage[],
|
||||
availableToolNames: string[],
|
||||
@@ -271,6 +284,7 @@ export function buildAISystemContextMessages({
|
||||
7. 如果命令权限不允许某类操作,就不要输出该类命令;无法满足时直接说明限制。`,
|
||||
});
|
||||
appendAIRuntimeInspectionGuidance(systemMessages, availableToolNames);
|
||||
appendAISafetyInspectionGuidance(systemMessages, availableToolNames);
|
||||
appendCustomPromptGroup(systemMessages, ['jvmDiagnostic'], userPromptSettings);
|
||||
appendSkillPromptGroup(systemMessages, ['jvmDiagnostic'], skills, availableToolNames);
|
||||
return systemMessages;
|
||||
@@ -305,6 +319,7 @@ ${resourcePath ? `当前资源路径:${resourcePath}` : '当前未选中具体
|
||||
6. 不要输出脚本、命令或“已经执行成功”之类的表述。`,
|
||||
});
|
||||
appendAIRuntimeInspectionGuidance(systemMessages, availableToolNames);
|
||||
appendAISafetyInspectionGuidance(systemMessages, availableToolNames);
|
||||
appendCustomPromptGroup(systemMessages, ['jvm'], userPromptSettings);
|
||||
appendSkillPromptGroup(systemMessages, ['jvm'], skills, availableToolNames);
|
||||
return systemMessages;
|
||||
@@ -377,6 +392,7 @@ SELECT * FROM users WHERE status = 1;
|
||||
});
|
||||
}
|
||||
appendAIRuntimeInspectionGuidance(systemMessages, availableToolNames);
|
||||
appendAISafetyInspectionGuidance(systemMessages, availableToolNames);
|
||||
appendAIChatReadinessInspectionGuidance(systemMessages, availableToolNames);
|
||||
appendAIProviderInspectionGuidance(systemMessages, availableToolNames);
|
||||
appendMCPSetupInspectionGuidance(systemMessages, availableToolNames);
|
||||
|
||||
@@ -24,6 +24,7 @@ interface AIToolCallingBlockProps {
|
||||
|
||||
const TOOL_ACTION_LABELS: Record<string, string> = {
|
||||
inspect_ai_runtime: '读取当前 AI 运行状态',
|
||||
inspect_ai_safety: '读取当前 AI 安全边界',
|
||||
inspect_ai_providers: '读取当前 AI 供应商与模型配置',
|
||||
inspect_ai_chat_readiness: '读取当前 AI 聊天发送前置状态',
|
||||
inspect_mcp_setup: '读取当前 MCP 配置状态',
|
||||
|
||||
623
frontend/src/utils/aiBuiltinToolInfo.ts
Normal file
623
frontend/src/utils/aiBuiltinToolInfo.ts
Normal file
@@ -0,0 +1,623 @@
|
||||
export interface AIChatToolDefinition {
|
||||
type: "function";
|
||||
function: {
|
||||
name: string;
|
||||
description: string;
|
||||
parameters: Record<string, any>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AIBuiltinToolInfo {
|
||||
name: string;
|
||||
icon: string;
|
||||
desc: string;
|
||||
detail: string;
|
||||
params: string;
|
||||
tool: AIChatToolDefinition;
|
||||
}
|
||||
|
||||
export const BUILTIN_AI_TOOL_INFO: AIBuiltinToolInfo[] = [
|
||||
{
|
||||
name: "get_connections",
|
||||
icon: "🔗",
|
||||
desc: "获取所有可用的数据库连接",
|
||||
detail:
|
||||
"返回连接 ID、名称、类型 (MySQL/PostgreSQL 等) 和 Host 地址。AI 根据返回信息决定优先探索哪个连接。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_connections",
|
||||
description:
|
||||
"当需要查询、操作数据库但用户没有选择任何连接上下文时,获取当前软件中可用的所有数据库连接信息。返回的数据包含连接ID(id)和名称(name)。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_databases",
|
||||
icon: "🗄️",
|
||||
desc: "获取指定连接下的所有数据库",
|
||||
detail: "传入 connectionId,返回该连接下的数据库/Schema 名称列表。",
|
||||
params: "connectionId: 连接 ID",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_databases",
|
||||
description: "获取指定连接(connectionId)下的所有数据库(Database/Schema)名。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID (从 get_connections 获取)" },
|
||||
},
|
||||
required: ["connectionId"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_tables",
|
||||
icon: "📋",
|
||||
desc: "获取指定数据库下的所有表名",
|
||||
detail:
|
||||
"传入 connectionId 和 dbName,返回表名列表。AI 用它来定位用户提到的目标表。",
|
||||
params: "connectionId, dbName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_tables",
|
||||
description:
|
||||
"当已经确定了目标连接和数据库名后,如果用户询问或隐式提到了表但你不知道确切表名,调用此工具获取该数据库下的所有表名列表(只含表名,帮助你推断目标表)。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
},
|
||||
required: ["connectionId", "dbName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_all_columns",
|
||||
icon: "🧱",
|
||||
desc: "获取指定数据库下所有表的字段摘要",
|
||||
detail:
|
||||
"传入 connectionId 和 dbName,返回跨表字段列表(表名、字段名、类型、注释)。适合用户只知道业务字段、不知道具体在哪张表时快速定位目标表。",
|
||||
params: "connectionId, dbName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_all_columns",
|
||||
description:
|
||||
"获取指定数据库下全部表的字段摘要,返回表名、字段名、类型和注释。适用于按字段反查表、跨表梳理相同字段、做数据地图探索。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
},
|
||||
required: ["connectionId", "dbName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_columns",
|
||||
icon: "🔍",
|
||||
desc: "获取指定表的字段结构",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回每个字段的名称、类型、是否可空、默认值和注释。AI 在生成 SQL 前必须调用此工具确认真实字段名。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_columns",
|
||||
description:
|
||||
"获取指定表的字段列表(字段名、类型、是否可空、默认值、注释等)。在生成 SQL 之前必须先调用此工具确认真实字段名,禁止猜测字段名。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_indexes",
|
||||
icon: "🧭",
|
||||
desc: "获取指定表的索引定义",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回索引名、索引列、唯一性和索引类型。AI 在做慢 SQL 分析、索引优化和执行计划推断时应优先调用。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_indexes",
|
||||
description:
|
||||
"获取指定表的索引定义,包括索引名、字段顺序、唯一性和索引类型。适用于慢 SQL 分析、索引优化建议和确认现有索引覆盖情况。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_foreign_keys",
|
||||
icon: "🧬",
|
||||
desc: "获取指定表的外键关系",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回当前表到其他表的外键映射。AI 在推断表关系、生成联表 SQL 和评审数据一致性时可直接使用。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_foreign_keys",
|
||||
description:
|
||||
"获取指定表的外键关系,包括本表字段、引用表、引用字段和约束名。适用于联表路径分析、ER 关系梳理和约束检查。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_triggers",
|
||||
icon: "⏱️",
|
||||
desc: "获取指定表的触发器定义",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回触发器名、触发时机、事件类型和语句体。AI 在分析隐式写入、副作用和审计逻辑时可直接查看。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_triggers",
|
||||
description:
|
||||
"获取指定表的触发器定义,包括触发时机、事件和触发语句。适用于排查隐式数据变更、审计逻辑和表级副作用。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_table_ddl",
|
||||
icon: "📝",
|
||||
desc: "获取表的建表语句 (DDL)",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回完整的 CREATE TABLE 语句,包含字段定义、索引、约束等信息。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_table_ddl",
|
||||
description: "获取指定表的完整建表语句(CREATE TABLE DDL),包含字段、索引、约束等完整结构信息。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "preview_table_rows",
|
||||
icon: "👀",
|
||||
desc: "抽样预览指定表的前几行数据",
|
||||
detail:
|
||||
"传入 connectionId、dbName、tableName 和可选 limit,返回该表的前几行真实样例数据。适合先看数据形态、空值分布和枚举值,再决定怎么写 SQL。",
|
||||
params: "connectionId, dbName, tableName, limit?",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "preview_table_rows",
|
||||
description:
|
||||
"预览指定表的前几行样例数据。适用于快速理解字段取值形态、空值情况、时间格式和状态枚举,减少模型盲写 SQL。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
limit: { type: "number", description: "可选,预览行数,默认 20,最大 100" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_table_bundle",
|
||||
icon: "🧰",
|
||||
desc: "一次抓取指定表的结构快照",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回字段、索引、外键、触发器和 DDL;还可以附带前几行样例数据。适合在写 SQL、评审表设计或排查副作用前先做完整摸底。",
|
||||
params: "connectionId, dbName, tableName, includeSampleRows?, sampleLimit?",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_table_bundle",
|
||||
description:
|
||||
"一次性获取指定表的结构快照,返回字段、索引、外键、触发器、DDL,以及可选样例数据。适用于做完整表设计摸底、快速理解表关系和降低模型多次往返调用。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
includeSampleRows: { type: "boolean", description: "可选,是否附带前几行样例数据" },
|
||||
sampleLimit: { type: "number", description: "可选,样例行数,默认 10,最大 100" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_database_bundle",
|
||||
icon: "🗂️",
|
||||
desc: "一次抓取指定数据库的结构总览",
|
||||
detail:
|
||||
"传入 connectionId 和 dbName,返回库内表清单、表数量、总字段数,以及按表聚合的字段摘要预览。适合刚接手陌生库时先做全局摸底,再决定深入哪张表。",
|
||||
params: "connectionId, dbName, includeColumns?, tableLimit?, perTableColumnLimit?",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_database_bundle",
|
||||
description:
|
||||
"一次性获取指定数据库的结构总览,返回表名列表、总字段数,以及按表聚合的字段摘要预览。适用于陌生数据库摸底、做数据地图和快速选择下一步要深入分析的表。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
includeColumns: { type: "boolean", description: "可选,是否附带按表聚合的字段摘要,默认 true" },
|
||||
tableLimit: { type: "number", description: "可选,最多返回多少张表,默认 80,最大 200" },
|
||||
perTableColumnLimit: { type: "number", description: "可选,每张表最多返回多少个字段摘要,默认 8,最大 30" },
|
||||
},
|
||||
required: ["connectionId", "dbName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_runtime",
|
||||
icon: "🎛️",
|
||||
desc: "查看当前 AI 自身运行状态",
|
||||
detail:
|
||||
"返回当前启用的模型供应商、模型名、安全级别、上下文级别、启用的 Skills,以及当前已暴露的内置工具和 MCP 工具。适合用户问“你现在能调用什么”“当前用的哪个模型”“为什么不能执行写操作”时,先读真实运行状态再回答。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_runtime",
|
||||
description:
|
||||
"读取当前 AI 运行时快照,包括当前供应商、模型、安全级别、上下文级别、启用的 Skills、当前可用的内置工具与 MCP 工具。适用于用户询问当前 AI 能力边界、当前使用哪个模型、为什么不能执行某些操作时,先读取真实运行状态,避免模型猜测。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_safety",
|
||||
icon: "🛡️",
|
||||
desc: "查看当前 AI 写入安全边界",
|
||||
detail:
|
||||
"返回当前 AI 安全级别对应的 SQL 允许范围、非只读语句是否仍需确认 / allowMutating,以及当前活动连接、页签或 JVM 诊断权限是否还叠加了只读限制。适合用户问“为什么现在不能写”“DDL 能不能执行”“allowMutating 要不要传”时先读真实边界。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_safety",
|
||||
description:
|
||||
"读取当前 AI 安全边界快照,包括当前安全级别允许的 SQL 范围、非查询语句的确认要求、MCP execute_sql 对 allowMutating 的要求,以及当前活动连接、结果页签或 JVM 诊断权限是否额外处于只读限制。适用于用户提到为什么现在不能写、当前是不是只读、DDL 能不能执行、allowMutating 是否必须传时,先读取真实边界再回答。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_providers",
|
||||
icon: "🪪",
|
||||
desc: "查看当前 AI 供应商与模型配置",
|
||||
detail:
|
||||
"返回当前配置了哪些 AI 供应商、哪个正在生效、各自的 baseUrl、已选模型、声明模型列表、密钥是否存在、自定义请求头 key,以及缺少密钥/模型/地址等待检查项。适合用户问“为什么没有模型”“API Key 有没有配”“当前到底配了哪些供应商”时先读真实配置。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_providers",
|
||||
description:
|
||||
"读取当前 AI 供应商配置快照,包括供应商列表、活动供应商、接口地址、已选模型、声明模型列表、是否存在密钥、自定义请求头 key,以及缺少密钥/模型/地址等待检查项。适用于用户提到当前供应商、模型列表为空、API Key 是否配置、为什么 AI 不能正常发起请求时,先读取真实配置再解释。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_chat_readiness",
|
||||
icon: "🚦",
|
||||
desc: "查看当前 AI 聊天是否具备发送条件",
|
||||
detail:
|
||||
"返回当前聊天输入区是否已经具备发送条件,包括有没有活动供应商、当前供应商是否缺密钥或接口地址、是否已选模型、当前连接/表结构上下文是否已挂载,以及下一步建议动作。适合用户问“为什么现在不能发送”“输入框到底缺什么配置”“当前 AI 聊天准备好了没有”时先读真实状态。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_chat_readiness",
|
||||
description:
|
||||
"读取当前 AI 聊天输入区的发送前置状态,包括活动供应商、密钥和接口地址是否完整、是否已选模型、当前连接上下文和已挂载表结构数量,以及建议的下一步动作。适用于用户提到为什么现在不能发送、为什么输入区还没准备好、当前到底缺什么配置时,先读取真实状态再回答。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_mcp_setup",
|
||||
icon: "🪛",
|
||||
desc: "查看当前 MCP 配置与外部接入状态",
|
||||
detail:
|
||||
"返回当前本地配置了哪些 MCP 服务、哪些已启用、每个服务声明了什么启动命令,以及 Claude Code / Codex 这类外部客户端的写入状态与命令检测结果。适合用户问“我现在配了哪些 MCP”“为什么外部客户端还用不了”“MCP 到底写没写进去”时先读真实状态。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_mcp_setup",
|
||||
description:
|
||||
"读取当前本地 MCP 配置快照,包括 MCP 服务列表、启用状态、启动命令、环境变量 key、已发现工具,以及外部客户端的 GoNavi MCP 写入状态与本机 CLI 检测结果。适用于用户提到 MCP 服务配置、Claude/Codex 是否已接入、为什么外部客户端用不了、当前到底启用了哪些 MCP 时,先读取真实配置再回答。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_guidance",
|
||||
icon: "🧠",
|
||||
desc: "查看当前 AI 提示词与 Skills 配置",
|
||||
detail:
|
||||
"返回当前用户自定义的全局/数据库/JVM 提示词,以及当前启用的 Skills、作用域、依赖工具和 skill prompt 内容。适合用户问“你现在到底带了哪些提示词”“为什么你会这样回答”“当前有哪些 Skills 在生效”时先读真实配置。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_guidance",
|
||||
description:
|
||||
"读取当前 AI 的提示与技能配置快照,包括用户自定义提示词、当前启用的 Skills、作用域、依赖工具和各自的 system prompt。适用于用户提到当前提示词、当前 Skill、为什么 AI 当前会这样回答、当前有哪些规则在生效时,先读取真实配置再解释。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_context",
|
||||
icon: "🧷",
|
||||
desc: "查看当前 AI 已关联的表结构上下文",
|
||||
detail:
|
||||
"返回当前对话已经挂载到 AI 上下文里的表清单、所属连接与数据库,以及每张表的 DDL 预览。适合用户说“看看我现在带了哪些表结构”“当前 AI 上下文是什么”时,先读取真实挂载状态再继续分析。",
|
||||
params: "includeDDL?(默认 false), ddlLimit?(默认 4000)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_context",
|
||||
description:
|
||||
"读取当前对话已经关联到 AI 上下文里的表结构快照,包括连接、数据库、表名,以及可选的 DDL 内容。适用于用户提到当前 AI 上下文、当前关联表、当前挂载的表结构时,先读取真实状态,避免模型凭记忆复述。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
includeDDL: { type: "boolean", description: "可选,是否附带每张表的 DDL 内容,默认 false" },
|
||||
ddlLimit: { type: "number", description: "可选,DDL 截断长度,默认 4000,最大 12000" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_current_connection",
|
||||
icon: "🛰️",
|
||||
desc: "查看当前活动连接/数据源摘要",
|
||||
detail:
|
||||
"返回当前活动连接的类型、地址、端口、当前数据库、是否启用 SSH/代理/HTTP 隧道,以及当前活动页签绑定的表信息。适合用户问“我现在连的是哪个库”“这个连接走没走 SSH”“当前数据源是什么类型”时先读取真实连接状态。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_current_connection",
|
||||
description:
|
||||
"读取当前活动连接或当前页签对应数据源的真实摘要,包括连接类型、地址、端口、当前数据库、SSH/代理/HTTP 隧道状态,以及当前页签绑定的表上下文。适用于用户提到当前连接、当前数据源、当前库地址、是否走 SSH、当前连的是哪种数据库时,先读取真实界面上下文,避免模型猜测。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_saved_connections",
|
||||
icon: "🧭",
|
||||
desc: "查看本地已保存连接清单",
|
||||
detail:
|
||||
"可按关键词或数据库类型过滤,返回本地保存的数据源列表、连接类型分布,以及每条连接的地址、当前库、SSH/代理/HTTP 隧道状态。适合用户问“我本地存了哪些连接”“帮我找 mysql / postgres 连接”“哪条连接配置了 SSH”时先读真实本地连接资产。",
|
||||
params: "keyword?, type?, limit?",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_saved_connections",
|
||||
description:
|
||||
"读取本地已保存连接清单,可按关键词和数据库类型过滤,并返回每条连接的类型、地址、当前库、SSH/代理/HTTP 隧道等摘要。适用于用户提到本地保存了哪些连接、要找哪条 mysql/postgres 连接、哪条连接启用了 SSH 或代理时,先读取真实本地连接资产再回答。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
keyword: { type: "string", description: "可选,按连接名、ID、类型、主机、数据库名或 SSH/代理地址做关键词筛选" },
|
||||
type: { type: "string", description: "可选,只看某种数据库类型,例如 mysql、postgres、redis、mongodb" },
|
||||
limit: { type: "number", description: "可选,最多返回多少条连接,默认 20,最大 100" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_active_tab",
|
||||
icon: "📍",
|
||||
desc: "查看当前活动页签上下文",
|
||||
detail:
|
||||
"返回当前活动页签的类型、连接、数据库、表名,以及当前 SQL / 命令页签里的草稿内容(超长会截断)。适合用户说“看我当前这条 SQL”“优化这个编辑器里的语句”时,先让 AI 直接读取当前工作区上下文。",
|
||||
params: "includeContent?(默认 true)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_active_tab",
|
||||
description:
|
||||
"获取当前活动页签的上下文快照,包括页签类型、连接、数据库、表名,以及当前 SQL / 命令页签里的草稿内容。适用于用户提到当前页签、当前 SQL、当前编辑器、这条语句时,先读取真实界面上下文,避免让模型猜测。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
includeContent: { type: "boolean", description: "可选,是否附带页签中的 SQL / 命令草稿内容,默认 true" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_workspace_tabs",
|
||||
icon: "🗃️",
|
||||
desc: "查看当前工作区打开的页签总览",
|
||||
detail:
|
||||
"返回当前工作区里打开的页签列表、哪个是活动页签,以及每个页签对应的连接、数据库、表名等上下文。适合用户说“我现在开了哪些 SQL”“看看我工作区里有哪些页签”“帮我对比这几个查询页签”时,先读取真实工作区布局再继续分析。",
|
||||
params: "limit?(默认 12), includeContent?(默认 false)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_workspace_tabs",
|
||||
description:
|
||||
"获取当前工作区已打开页签的总览,包括活动页签、页签类型、连接、数据库、表名,以及可选的 SQL / 命令草稿内容。适用于用户提到当前工作区、打开了哪些页签、哪几个查询页签、想对比多个编辑器内容时,先读取真实界面状态,避免模型猜测。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
limit: { type: "number", description: "可选,最多返回多少个页签,默认 12,最大 30" },
|
||||
includeContent: { type: "boolean", description: "可选,是否附带页签中的 SQL / 命令草稿内容,默认 false" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_recent_sql_logs",
|
||||
icon: "🧾",
|
||||
desc: "查看最近 SQL 执行日志",
|
||||
detail:
|
||||
"传入可选 limit 和 status,返回最近 SQL 执行记录,包括数据库、耗时、成功/失败、报错、受影响行数和 SQL 文本。适合追查刚执行失败的语句、定位慢查询,并让 AI 基于真实执行历史给出解释或优化建议。",
|
||||
params: "limit?, status?(all|success|error)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_recent_sql_logs",
|
||||
description:
|
||||
"获取最近 SQL 执行日志摘要,可按成功/失败过滤。适用于回看刚执行过的 SQL、排查失败原因、定位慢查询,以及让 AI 基于真实执行历史给出解释和优化建议。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
limit: { type: "number", description: "可选,返回多少条日志,默认 20,最大 100" },
|
||||
status: {
|
||||
type: "string",
|
||||
description: "可选,按执行状态过滤,支持 all、success、error,默认 all",
|
||||
enum: ["all", "success", "error"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_saved_queries",
|
||||
icon: "💾",
|
||||
desc: "查看本地已保存的 SQL 查询",
|
||||
detail:
|
||||
"可按关键词、连接或数据库过滤,返回保存查询的名称、所属连接、数据库和 SQL 预览。适合用户提到“我之前保存过的查询”“帮我找那条历史 SQL”时先从真实本地收藏里检索。",
|
||||
params: "keyword?, connectionId?, dbName?, limit?, includeSql?(默认 true)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_saved_queries",
|
||||
description:
|
||||
"读取本地已保存的 SQL 查询列表,可按关键词、连接和数据库过滤,并返回每条查询的名称、所属连接、数据库与 SQL 预览。适用于用户想找历史查询、复用旧 SQL、核对保存脚本时,先读取真实本地记录。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
keyword: { type: "string", description: "可选,按查询名称、SQL 文本、连接名或数据库名做关键词筛选" },
|
||||
connectionId: { type: "string", description: "可选,只看某个连接下保存的查询" },
|
||||
dbName: { type: "string", description: "可选,只看某个数据库下保存的查询" },
|
||||
limit: { type: "number", description: "可选,最多返回多少条,默认 12,最大 50" },
|
||||
includeSql: { type: "boolean", description: "可选,是否附带 SQL 预览,默认 true" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_sql_snippets",
|
||||
icon: "🧩",
|
||||
desc: "查看 SQL 片段模板",
|
||||
detail:
|
||||
"返回本地 SQL 片段的 prefix、名称、说明和模板预览,可按关键词过滤。适合用户想找现成模板、补全片段、团队约定 SQL 模板时先读取真实片段库。",
|
||||
params: "keyword?, limit?, includeBody?(默认 true)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_sql_snippets",
|
||||
description:
|
||||
"读取本地 SQL 片段模板列表,可按关键词过滤,并返回 prefix、名称、说明和模板预览。适用于用户想找 snippet、复用模板、核对 SQL 片段配置时,先读取真实本地片段库。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
keyword: { type: "string", description: "可选,按 prefix、名称、描述或模板内容做关键词筛选" },
|
||||
limit: { type: "number", description: "可选,最多返回多少条,默认 20,最大 80" },
|
||||
includeBody: { type: "boolean", description: "可选,是否附带模板内容预览,默认 true" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "execute_sql",
|
||||
icon: "▶️",
|
||||
desc: "执行 SQL 查询并返回结果",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 sql,在目标数据库上执行 SQL 并返回结果(最多 50 行)。受安全级别控制,只读模式下仅允许 SELECT/SHOW/DESCRIBE。",
|
||||
params: "connectionId, dbName, sql",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "execute_sql",
|
||||
description:
|
||||
"在指定连接和数据库上执行 SQL 查询并返回结果。受安全级别控制,只读模式下只能执行 SELECT/SHOW/DESCRIBE 等查询操作。结果最多返回 50 行。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
sql: { type: "string", description: "要执行的 SQL 语句" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "sql"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -10,6 +10,13 @@ describe('aiToolRegistry', () => {
|
||||
expect(info?.tool.function.description).toContain('当前供应商');
|
||||
});
|
||||
|
||||
it('registers the ai-safety inspector as a builtin tool', () => {
|
||||
const info = BUILTIN_AI_TOOL_INFO.find((item) => item.name === 'inspect_ai_safety');
|
||||
expect(info).toBeTruthy();
|
||||
expect(info?.desc).toContain('写入安全边界');
|
||||
expect(info?.tool.function.description).toContain('allowMutating');
|
||||
});
|
||||
|
||||
it('registers the mcp-setup inspector as a builtin tool', () => {
|
||||
const info = BUILTIN_AI_TOOL_INFO.find((item) => item.name === 'inspect_mcp_setup');
|
||||
expect(info).toBeTruthy();
|
||||
@@ -79,6 +86,7 @@ describe('aiToolRegistry', () => {
|
||||
}]);
|
||||
|
||||
expect(tools.some((item) => item.function.name === 'inspect_ai_runtime')).toBe(true);
|
||||
expect(tools.some((item) => item.function.name === 'inspect_ai_safety')).toBe(true);
|
||||
expect(tools.some((item) => item.function.name === 'inspect_ai_providers')).toBe(true);
|
||||
expect(tools.some((item) => item.function.name === 'inspect_ai_chat_readiness')).toBe(true);
|
||||
expect(tools.some((item) => item.function.name === 'inspect_mcp_setup')).toBe(true);
|
||||
|
||||
@@ -1,611 +1,15 @@
|
||||
import type { AIMCPToolDescriptor } from "../types";
|
||||
import {
|
||||
BUILTIN_AI_TOOL_INFO,
|
||||
type AIChatToolDefinition,
|
||||
type AIBuiltinToolInfo,
|
||||
} from "./aiBuiltinToolInfo";
|
||||
|
||||
export interface AIChatToolDefinition {
|
||||
type: "function";
|
||||
function: {
|
||||
name: string;
|
||||
description: string;
|
||||
parameters: Record<string, any>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AIBuiltinToolInfo {
|
||||
name: string;
|
||||
icon: string;
|
||||
desc: string;
|
||||
detail: string;
|
||||
params: string;
|
||||
tool: AIChatToolDefinition;
|
||||
}
|
||||
|
||||
export const BUILTIN_AI_TOOL_INFO: AIBuiltinToolInfo[] = [
|
||||
{
|
||||
name: "get_connections",
|
||||
icon: "🔗",
|
||||
desc: "获取所有可用的数据库连接",
|
||||
detail:
|
||||
"返回连接 ID、名称、类型 (MySQL/PostgreSQL 等) 和 Host 地址。AI 根据返回信息决定优先探索哪个连接。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_connections",
|
||||
description:
|
||||
"当需要查询、操作数据库但用户没有选择任何连接上下文时,获取当前软件中可用的所有数据库连接信息。返回的数据包含连接ID(id)和名称(name)。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_databases",
|
||||
icon: "🗄️",
|
||||
desc: "获取指定连接下的所有数据库",
|
||||
detail: "传入 connectionId,返回该连接下的数据库/Schema 名称列表。",
|
||||
params: "connectionId: 连接 ID",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_databases",
|
||||
description: "获取指定连接(connectionId)下的所有数据库(Database/Schema)名。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID (从 get_connections 获取)" },
|
||||
},
|
||||
required: ["connectionId"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_tables",
|
||||
icon: "📋",
|
||||
desc: "获取指定数据库下的所有表名",
|
||||
detail:
|
||||
"传入 connectionId 和 dbName,返回表名列表。AI 用它来定位用户提到的目标表。",
|
||||
params: "connectionId, dbName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_tables",
|
||||
description:
|
||||
"当已经确定了目标连接和数据库名后,如果用户询问或隐式提到了表但你不知道确切表名,调用此工具获取该数据库下的所有表名列表(只含表名,帮助你推断目标表)。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
},
|
||||
required: ["connectionId", "dbName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_all_columns",
|
||||
icon: "🧱",
|
||||
desc: "获取指定数据库下所有表的字段摘要",
|
||||
detail:
|
||||
"传入 connectionId 和 dbName,返回跨表字段列表(表名、字段名、类型、注释)。适合用户只知道业务字段、不知道具体在哪张表时快速定位目标表。",
|
||||
params: "connectionId, dbName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_all_columns",
|
||||
description:
|
||||
"获取指定数据库下全部表的字段摘要,返回表名、字段名、类型和注释。适用于按字段反查表、跨表梳理相同字段、做数据地图探索。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
},
|
||||
required: ["connectionId", "dbName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_columns",
|
||||
icon: "🔍",
|
||||
desc: "获取指定表的字段结构",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回每个字段的名称、类型、是否可空、默认值和注释。AI 在生成 SQL 前必须调用此工具确认真实字段名。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_columns",
|
||||
description:
|
||||
"获取指定表的字段列表(字段名、类型、是否可空、默认值、注释等)。在生成 SQL 之前必须先调用此工具确认真实字段名,禁止猜测字段名。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_indexes",
|
||||
icon: "🧭",
|
||||
desc: "获取指定表的索引定义",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回索引名、索引列、唯一性和索引类型。AI 在做慢 SQL 分析、索引优化和执行计划推断时应优先调用。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_indexes",
|
||||
description:
|
||||
"获取指定表的索引定义,包括索引名、字段顺序、唯一性和索引类型。适用于慢 SQL 分析、索引优化建议和确认现有索引覆盖情况。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_foreign_keys",
|
||||
icon: "🧬",
|
||||
desc: "获取指定表的外键关系",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回当前表到其他表的外键映射。AI 在推断表关系、生成联表 SQL 和评审数据一致性时可直接使用。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_foreign_keys",
|
||||
description:
|
||||
"获取指定表的外键关系,包括本表字段、引用表、引用字段和约束名。适用于联表路径分析、ER 关系梳理和约束检查。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_triggers",
|
||||
icon: "⏱️",
|
||||
desc: "获取指定表的触发器定义",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回触发器名、触发时机、事件类型和语句体。AI 在分析隐式写入、副作用和审计逻辑时可直接查看。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_triggers",
|
||||
description:
|
||||
"获取指定表的触发器定义,包括触发时机、事件和触发语句。适用于排查隐式数据变更、审计逻辑和表级副作用。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_table_ddl",
|
||||
icon: "📝",
|
||||
desc: "获取表的建表语句 (DDL)",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回完整的 CREATE TABLE 语句,包含字段定义、索引、约束等信息。",
|
||||
params: "connectionId, dbName, tableName",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "get_table_ddl",
|
||||
description: "获取指定表的完整建表语句(CREATE TABLE DDL),包含字段、索引、约束等完整结构信息。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "preview_table_rows",
|
||||
icon: "👀",
|
||||
desc: "抽样预览指定表的前几行数据",
|
||||
detail:
|
||||
"传入 connectionId、dbName、tableName 和可选 limit,返回该表的前几行真实样例数据。适合先看数据形态、空值分布和枚举值,再决定怎么写 SQL。",
|
||||
params: "connectionId, dbName, tableName, limit?",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "preview_table_rows",
|
||||
description:
|
||||
"预览指定表的前几行样例数据。适用于快速理解字段取值形态、空值情况、时间格式和状态枚举,减少模型盲写 SQL。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
limit: { type: "number", description: "可选,预览行数,默认 20,最大 100" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_table_bundle",
|
||||
icon: "🧰",
|
||||
desc: "一次抓取指定表的结构快照",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 tableName,返回字段、索引、外键、触发器和 DDL;还可以附带前几行样例数据。适合在写 SQL、评审表设计或排查副作用前先做完整摸底。",
|
||||
params: "connectionId, dbName, tableName, includeSampleRows?, sampleLimit?",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_table_bundle",
|
||||
description:
|
||||
"一次性获取指定表的结构快照,返回字段、索引、外键、触发器、DDL,以及可选样例数据。适用于做完整表设计摸底、快速理解表关系和降低模型多次往返调用。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
tableName: { type: "string", description: "表名" },
|
||||
includeSampleRows: { type: "boolean", description: "可选,是否附带前几行样例数据" },
|
||||
sampleLimit: { type: "number", description: "可选,样例行数,默认 10,最大 100" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "tableName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_database_bundle",
|
||||
icon: "🗂️",
|
||||
desc: "一次抓取指定数据库的结构总览",
|
||||
detail:
|
||||
"传入 connectionId 和 dbName,返回库内表清单、表数量、总字段数,以及按表聚合的字段摘要预览。适合刚接手陌生库时先做全局摸底,再决定深入哪张表。",
|
||||
params: "connectionId, dbName, includeColumns?, tableLimit?, perTableColumnLimit?",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_database_bundle",
|
||||
description:
|
||||
"一次性获取指定数据库的结构总览,返回表名列表、总字段数,以及按表聚合的字段摘要预览。适用于陌生数据库摸底、做数据地图和快速选择下一步要深入分析的表。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
includeColumns: { type: "boolean", description: "可选,是否附带按表聚合的字段摘要,默认 true" },
|
||||
tableLimit: { type: "number", description: "可选,最多返回多少张表,默认 80,最大 200" },
|
||||
perTableColumnLimit: { type: "number", description: "可选,每张表最多返回多少个字段摘要,默认 8,最大 30" },
|
||||
},
|
||||
required: ["connectionId", "dbName"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_runtime",
|
||||
icon: "🎛️",
|
||||
desc: "查看当前 AI 自身运行状态",
|
||||
detail:
|
||||
"返回当前启用的模型供应商、模型名、安全级别、上下文级别、启用的 Skills,以及当前已暴露的内置工具和 MCP 工具。适合用户问“你现在能调用什么”“当前用的哪个模型”“为什么不能执行写操作”时,先读真实运行状态再回答。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_runtime",
|
||||
description:
|
||||
"读取当前 AI 运行时快照,包括当前供应商、模型、安全级别、上下文级别、启用的 Skills、当前可用的内置工具与 MCP 工具。适用于用户询问当前 AI 能力边界、当前使用哪个模型、为什么不能执行某些操作时,先读取真实运行状态,避免模型猜测。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_providers",
|
||||
icon: "🪪",
|
||||
desc: "查看当前 AI 供应商与模型配置",
|
||||
detail:
|
||||
"返回当前配置了哪些 AI 供应商、哪个正在生效、各自的 baseUrl、已选模型、声明模型列表、密钥是否存在、自定义请求头 key,以及缺少密钥/模型/地址等待检查项。适合用户问“为什么没有模型”“API Key 有没有配”“当前到底配了哪些供应商”时先读真实配置。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_providers",
|
||||
description:
|
||||
"读取当前 AI 供应商配置快照,包括供应商列表、活动供应商、接口地址、已选模型、声明模型列表、是否存在密钥、自定义请求头 key,以及缺少密钥/模型/地址等待检查项。适用于用户提到当前供应商、模型列表为空、API Key 是否配置、为什么 AI 不能正常发起请求时,先读取真实配置再解释。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_chat_readiness",
|
||||
icon: "🚦",
|
||||
desc: "查看当前 AI 聊天是否具备发送条件",
|
||||
detail:
|
||||
"返回当前聊天输入区是否已经具备发送条件,包括有没有活动供应商、当前供应商是否缺密钥或接口地址、是否已选模型、当前连接/表结构上下文是否已挂载,以及下一步建议动作。适合用户问“为什么现在不能发送”“输入框到底缺什么配置”“当前 AI 聊天准备好了没有”时先读真实状态。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_chat_readiness",
|
||||
description:
|
||||
"读取当前 AI 聊天输入区的发送前置状态,包括活动供应商、密钥和接口地址是否完整、是否已选模型、当前连接上下文和已挂载表结构数量,以及建议的下一步动作。适用于用户提到为什么现在不能发送、为什么输入区还没准备好、当前到底缺什么配置时,先读取真实状态再回答。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_mcp_setup",
|
||||
icon: "🪛",
|
||||
desc: "查看当前 MCP 配置与外部接入状态",
|
||||
detail:
|
||||
"返回当前本地配置了哪些 MCP 服务、哪些已启用、每个服务声明了什么启动命令,以及 Claude Code / Codex 这类外部客户端的写入状态与命令检测结果。适合用户问“我现在配了哪些 MCP”“为什么外部客户端还用不了”“MCP 到底写没写进去”时先读真实状态。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_mcp_setup",
|
||||
description:
|
||||
"读取当前本地 MCP 配置快照,包括 MCP 服务列表、启用状态、启动命令、环境变量 key、已发现工具,以及外部客户端的 GoNavi MCP 写入状态与本机 CLI 检测结果。适用于用户提到 MCP 服务配置、Claude/Codex 是否已接入、为什么外部客户端用不了、当前到底启用了哪些 MCP 时,先读取真实配置再回答。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_guidance",
|
||||
icon: "🧠",
|
||||
desc: "查看当前 AI 提示词与 Skills 配置",
|
||||
detail:
|
||||
"返回当前用户自定义的全局/数据库/JVM 提示词,以及当前启用的 Skills、作用域、依赖工具和 skill prompt 内容。适合用户问“你现在到底带了哪些提示词”“为什么你会这样回答”“当前有哪些 Skills 在生效”时先读真实配置。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_guidance",
|
||||
description:
|
||||
"读取当前 AI 的提示与技能配置快照,包括用户自定义提示词、当前启用的 Skills、作用域、依赖工具和各自的 system prompt。适用于用户提到当前提示词、当前 Skill、为什么 AI 当前会这样回答、当前有哪些规则在生效时,先读取真实配置再解释。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_ai_context",
|
||||
icon: "🧷",
|
||||
desc: "查看当前 AI 已关联的表结构上下文",
|
||||
detail:
|
||||
"返回当前对话已经挂载到 AI 上下文里的表清单、所属连接与数据库,以及每张表的 DDL 预览。适合用户说“看看我现在带了哪些表结构”“当前 AI 上下文是什么”时,先读取真实挂载状态再继续分析。",
|
||||
params: "includeDDL?(默认 false), ddlLimit?(默认 4000)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_ai_context",
|
||||
description:
|
||||
"读取当前对话已经关联到 AI 上下文里的表结构快照,包括连接、数据库、表名,以及可选的 DDL 内容。适用于用户提到当前 AI 上下文、当前关联表、当前挂载的表结构时,先读取真实状态,避免模型凭记忆复述。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
includeDDL: { type: "boolean", description: "可选,是否附带每张表的 DDL 内容,默认 false" },
|
||||
ddlLimit: { type: "number", description: "可选,DDL 截断长度,默认 4000,最大 12000" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_current_connection",
|
||||
icon: "🛰️",
|
||||
desc: "查看当前活动连接/数据源摘要",
|
||||
detail:
|
||||
"返回当前活动连接的类型、地址、端口、当前数据库、是否启用 SSH/代理/HTTP 隧道,以及当前活动页签绑定的表信息。适合用户问“我现在连的是哪个库”“这个连接走没走 SSH”“当前数据源是什么类型”时先读取真实连接状态。",
|
||||
params: "无参数",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_current_connection",
|
||||
description:
|
||||
"读取当前活动连接或当前页签对应数据源的真实摘要,包括连接类型、地址、端口、当前数据库、SSH/代理/HTTP 隧道状态,以及当前页签绑定的表上下文。适用于用户提到当前连接、当前数据源、当前库地址、是否走 SSH、当前连的是哪种数据库时,先读取真实界面上下文,避免模型猜测。",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_saved_connections",
|
||||
icon: "🧭",
|
||||
desc: "查看本地已保存连接清单",
|
||||
detail:
|
||||
"可按关键词或数据库类型过滤,返回本地保存的数据源列表、连接类型分布,以及每条连接的地址、当前库、SSH/代理/HTTP 隧道状态。适合用户问“我本地存了哪些连接”“帮我找 mysql / postgres 连接”“哪条连接配置了 SSH”时先读真实本地连接资产。",
|
||||
params: "keyword?, type?, limit?",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_saved_connections",
|
||||
description:
|
||||
"读取本地已保存连接清单,可按关键词和数据库类型过滤,并返回每条连接的类型、地址、当前库、SSH/代理/HTTP 隧道等摘要。适用于用户提到本地保存了哪些连接、要找哪条 mysql/postgres 连接、哪条连接启用了 SSH 或代理时,先读取真实本地连接资产再回答。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
keyword: { type: "string", description: "可选,按连接名、ID、类型、主机、数据库名或 SSH/代理地址做关键词筛选" },
|
||||
type: { type: "string", description: "可选,只看某种数据库类型,例如 mysql、postgres、redis、mongodb" },
|
||||
limit: { type: "number", description: "可选,最多返回多少条连接,默认 20,最大 100" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_active_tab",
|
||||
icon: "📍",
|
||||
desc: "查看当前活动页签上下文",
|
||||
detail:
|
||||
"返回当前活动页签的类型、连接、数据库、表名,以及当前 SQL / 命令页签里的草稿内容(超长会截断)。适合用户说“看我当前这条 SQL”“优化这个编辑器里的语句”时,先让 AI 直接读取当前工作区上下文。",
|
||||
params: "includeContent?(默认 true)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_active_tab",
|
||||
description:
|
||||
"获取当前活动页签的上下文快照,包括页签类型、连接、数据库、表名,以及当前 SQL / 命令页签里的草稿内容。适用于用户提到当前页签、当前 SQL、当前编辑器、这条语句时,先读取真实界面上下文,避免让模型猜测。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
includeContent: { type: "boolean", description: "可选,是否附带页签中的 SQL / 命令草稿内容,默认 true" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_workspace_tabs",
|
||||
icon: "🗃️",
|
||||
desc: "查看当前工作区打开的页签总览",
|
||||
detail:
|
||||
"返回当前工作区里打开的页签列表、哪个是活动页签,以及每个页签对应的连接、数据库、表名等上下文。适合用户说“我现在开了哪些 SQL”“看看我工作区里有哪些页签”“帮我对比这几个查询页签”时,先读取真实工作区布局再继续分析。",
|
||||
params: "limit?(默认 12), includeContent?(默认 false)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_workspace_tabs",
|
||||
description:
|
||||
"获取当前工作区已打开页签的总览,包括活动页签、页签类型、连接、数据库、表名,以及可选的 SQL / 命令草稿内容。适用于用户提到当前工作区、打开了哪些页签、哪几个查询页签、想对比多个编辑器内容时,先读取真实界面状态,避免模型猜测。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
limit: { type: "number", description: "可选,最多返回多少个页签,默认 12,最大 30" },
|
||||
includeContent: { type: "boolean", description: "可选,是否附带页签中的 SQL / 命令草稿内容,默认 false" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_recent_sql_logs",
|
||||
icon: "🧾",
|
||||
desc: "查看最近 SQL 执行日志",
|
||||
detail:
|
||||
"传入可选 limit 和 status,返回最近 SQL 执行记录,包括数据库、耗时、成功/失败、报错、受影响行数和 SQL 文本。适合追查刚执行失败的语句、定位慢查询,并让 AI 基于真实执行历史给出解释或优化建议。",
|
||||
params: "limit?, status?(all|success|error)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_recent_sql_logs",
|
||||
description:
|
||||
"获取最近 SQL 执行日志摘要,可按成功/失败过滤。适用于回看刚执行过的 SQL、排查失败原因、定位慢查询,以及让 AI 基于真实执行历史给出解释和优化建议。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
limit: { type: "number", description: "可选,返回多少条日志,默认 20,最大 100" },
|
||||
status: {
|
||||
type: "string",
|
||||
description: "可选,按执行状态过滤,支持 all、success、error,默认 all",
|
||||
enum: ["all", "success", "error"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_saved_queries",
|
||||
icon: "💾",
|
||||
desc: "查看本地已保存的 SQL 查询",
|
||||
detail:
|
||||
"可按关键词、连接或数据库过滤,返回保存查询的名称、所属连接、数据库和 SQL 预览。适合用户提到“我之前保存过的查询”“帮我找那条历史 SQL”时先从真实本地收藏里检索。",
|
||||
params: "keyword?, connectionId?, dbName?, limit?, includeSql?(默认 true)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_saved_queries",
|
||||
description:
|
||||
"读取本地已保存的 SQL 查询列表,可按关键词、连接和数据库过滤,并返回每条查询的名称、所属连接、数据库与 SQL 预览。适用于用户想找历史查询、复用旧 SQL、核对保存脚本时,先读取真实本地记录。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
keyword: { type: "string", description: "可选,按查询名称、SQL 文本、连接名或数据库名做关键词筛选" },
|
||||
connectionId: { type: "string", description: "可选,只看某个连接下保存的查询" },
|
||||
dbName: { type: "string", description: "可选,只看某个数据库下保存的查询" },
|
||||
limit: { type: "number", description: "可选,最多返回多少条,默认 12,最大 50" },
|
||||
includeSql: { type: "boolean", description: "可选,是否附带 SQL 预览,默认 true" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inspect_sql_snippets",
|
||||
icon: "🧩",
|
||||
desc: "查看 SQL 片段模板",
|
||||
detail:
|
||||
"返回本地 SQL 片段的 prefix、名称、说明和模板预览,可按关键词过滤。适合用户想找现成模板、补全片段、团队约定 SQL 模板时先读取真实片段库。",
|
||||
params: "keyword?, limit?, includeBody?(默认 true)",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "inspect_sql_snippets",
|
||||
description:
|
||||
"读取本地 SQL 片段模板列表,可按关键词过滤,并返回 prefix、名称、说明和模板预览。适用于用户想找 snippet、复用模板、核对 SQL 片段配置时,先读取真实本地片段库。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
keyword: { type: "string", description: "可选,按 prefix、名称、描述或模板内容做关键词筛选" },
|
||||
limit: { type: "number", description: "可选,最多返回多少条,默认 20,最大 80" },
|
||||
includeBody: { type: "boolean", description: "可选,是否附带模板内容预览,默认 true" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "execute_sql",
|
||||
icon: "▶️",
|
||||
desc: "执行 SQL 查询并返回结果",
|
||||
detail:
|
||||
"传入 connectionId、dbName 和 sql,在目标数据库上执行 SQL 并返回结果(最多 50 行)。受安全级别控制,只读模式下仅允许 SELECT/SHOW/DESCRIBE。",
|
||||
params: "connectionId, dbName, sql",
|
||||
tool: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "execute_sql",
|
||||
description:
|
||||
"在指定连接和数据库上执行 SQL 查询并返回结果。受安全级别控制,只读模式下只能执行 SELECT/SHOW/DESCRIBE 等查询操作。结果最多返回 50 行。",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
connectionId: { type: "string", description: "连接ID" },
|
||||
dbName: { type: "string", description: "数据库名" },
|
||||
sql: { type: "string", description: "要执行的 SQL 语句" },
|
||||
},
|
||||
required: ["connectionId", "dbName", "sql"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
export {
|
||||
BUILTIN_AI_TOOL_INFO,
|
||||
type AIChatToolDefinition,
|
||||
type AIBuiltinToolInfo,
|
||||
} from "./aiBuiltinToolInfo";
|
||||
|
||||
export const BUILTIN_AI_TOOLS: AIChatToolDefinition[] = BUILTIN_AI_TOOL_INFO.map((item) => item.tool);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user