From 9f4e246465435cd6f7e4e00568e53f33fddd20da Mon Sep 17 00:00:00 2001 From: hy Date: Tue, 25 Aug 2026 19:49:40 +0800 Subject: [PATCH] feat: streamline runtime skill management by consolidating skill definitions and enhancing catalog structure --- src/main/services/ai/human/constants.ts | 3 - src/main/services/ai/human/schema.ts | 2 +- src/main/services/ai/human/skills.ts | 147 ++++++++++++++- .../workbench/messageLogProjection.ts | 9 +- src/shared/runtimeCapabilities.ts | 176 +++--------------- 5 files changed, 169 insertions(+), 168 deletions(-) diff --git a/src/main/services/ai/human/constants.ts b/src/main/services/ai/human/constants.ts index 773b710d..8057f824 100644 --- a/src/main/services/ai/human/constants.ts +++ b/src/main/services/ai/human/constants.ts @@ -1,8 +1,5 @@ export { AI_TOOL_FAMILY_IDS, - BUILTIN_RUNTIME_SKILL_IDS, - EXTERNAL_RUNTIME_SKILL_IDS, - LEARNABLE_RUNTIME_SKILL_IDS, RUNTIME_SKILL_IDS } from '../../../../shared/runtimeCapabilities' diff --git a/src/main/services/ai/human/schema.ts b/src/main/services/ai/human/schema.ts index 2c047a40..95976651 100644 --- a/src/main/services/ai/human/schema.ts +++ b/src/main/services/ai/human/schema.ts @@ -3,7 +3,6 @@ import { aiArtifactRefSchema } from '../schema' import { jsonObjectSchema, jsonValueSchema, toolResourceContextSchema } from './toolSchemas' import { AI_TOOL_FAMILY_IDS, - BUILTIN_RUNTIME_SKILL_IDS, HUMAN_ROUND_EXECUTION_KINDS, HUMAN_SKILL_SOURCES, HUMAN_STAGES, @@ -12,6 +11,7 @@ import { HUMAN_STEP_RESULT_STATUSES, RUNTIME_SKILL_IDS } from './constants' +import { BUILTIN_RUNTIME_SKILL_IDS } from './skills' export const runtimeSkillIdSchema = z.enum(RUNTIME_SKILL_IDS) export const toolFamilyIdSchema = z.enum(AI_TOOL_FAMILY_IDS) diff --git a/src/main/services/ai/human/skills.ts b/src/main/services/ai/human/skills.ts index 5413dd21..a53f0c9b 100644 --- a/src/main/services/ai/human/skills.ts +++ b/src/main/services/ai/human/skills.ts @@ -1,15 +1,144 @@ +import { HUMAN_SKILL_SOURCES, RUNTIME_SKILL_IDS } from './constants' import { - BUILTIN_RUNTIME_SKILL_IDS, - EXTERNAL_RUNTIME_SKILL_IDS, - LEARNABLE_RUNTIME_SKILL_IDS, - RUNTIME_SKILL_IDS -} from './constants' -import { - RUNTIME_SKILL_CATALOG, - listRuntimeToolNamesForSkill + RUNTIME_TOOL_CATALOG, + RUNTIME_TOOL_NAMES, + type RuntimeToolFamilyId, + type RuntimeToolName } from '../../../../shared/runtimeCapabilities' import type { RuntimeSkillId, SkillDefinition } from './types' +type RuntimeSkillSource = (typeof HUMAN_SKILL_SOURCES)[number] + +type RuntimeSkillCatalogEntry = { + familyId: RuntimeToolFamilyId + source: RuntimeSkillSource + countsTowardToolBudget: boolean + title: string + description: string +} + +export const RUNTIME_SKILL_CATALOG = { + terminal: { + familyId: 'terminal', + source: 'builtin', + countsTowardToolBudget: false, + title: 'terminal', + description: + '在用户工作区根目录执行和读取命令,并返回终端状态、增量输出、退出状态和用户工作区域文件产物。' + }, + 'text-file': { + familyId: 'text-file', + source: 'builtin', + countsTowardToolBudget: false, + title: 'text-file', + description: '读取和写入 Markdown、TXT、代码等 UTF-8 普通文本文件。' + }, + 'kb-retrieval': { + familyId: 'kb', + source: 'builtin', + countsTowardToolBudget: false, + title: 'kb-retrieval', + description: + '查询用户工作区域知识库的已索引文档或检索相关内容片段,并返回命中证据、来源文档与内容块信息。' + }, + 'web-browsing': { + familyId: 'web', + source: 'builtin', + countsTowardToolBudget: false, + title: 'web-browsing', + description: + '按关键词搜索并读取公开网页正文,或直接读取指定网页,或操作内置浏览器,并返回网页正文、链接或浏览器动作结果。' + }, + 'docx-read': { + familyId: 'docx', + source: 'external', + countsTowardToolBudget: true, + title: 'docx-read', + description: '读取 .docx、.doc 的结构、节点、检索结果和视觉内容。' + }, + 'docx-write': { + familyId: 'docx', + source: 'external', + countsTowardToolBudget: true, + title: 'docx-write', + description: '读取稳定 nodeId,并局部修改 DOCX 内容、格式、表格、媒体、批注和修订。' + }, + 'pdf-read': { + familyId: 'pdf', + source: 'external', + countsTowardToolBudget: true, + title: 'pdf-read', + description: '读取 PDF 文档信息、页级文本、检索结果和页面视觉内容。' + }, + 'ppt-read': { + familyId: 'ppt', + source: 'external', + countsTowardToolBudget: true, + title: 'ppt-read', + description: '读取 PPTX 的页面结构、内容、搜索结果和页面视觉内容。' + }, + 'ppt-write': { + familyId: 'ppt', + source: 'external', + countsTowardToolBudget: true, + title: 'ppt-write', + description: '使用受限 HTML 创建或编辑 PPTX 页面和元素。' + }, + 'excel-read': { + familyId: 'excel', + source: 'external', + countsTowardToolBudget: true, + title: 'excel-read', + description: '读取 Excel 工作簿、工作表、单元格范围、公式和值。' + }, + 'excel-write': { + familyId: 'excel', + source: 'external', + countsTowardToolBudget: true, + title: 'excel-write', + description: '创建或编辑 Excel 工作簿中的工作表、单元格、公式、格式和结构。' + }, + 'image-recognition': { + familyId: 'image-recognition', + source: 'external', + countsTowardToolBudget: true, + title: '图像识别', + description: '读取图片并按 instruction 分析图片内容,并返回模型生成的文本结果。' + }, + 'image-generation': { + familyId: 'image-generation', + source: 'external', + countsTowardToolBudget: true, + title: '图片生成', + description: '通过 SVG 绘制生成 PNG、JPEG 或 WebP 图片,并保存为用户工作区域文件。' + }, + 'agent-control': { + familyId: 'agent-control', + source: 'builtin', + countsTowardToolBudget: false, + title: 'agent-control', + description: '管理任务推进过程:学习需要的技能、维护并更新执行计划。' + } +} as const satisfies Record + +export const BUILTIN_RUNTIME_SKILL_IDS = RUNTIME_SKILL_IDS.filter( + (skillId) => RUNTIME_SKILL_CATALOG[skillId].source === 'builtin' +) + +export const EXTERNAL_RUNTIME_SKILL_IDS = RUNTIME_SKILL_IDS.filter( + (skillId) => RUNTIME_SKILL_CATALOG[skillId].source === 'external' +) + +export const LEARNABLE_RUNTIME_SKILL_IDS = EXTERNAL_RUNTIME_SKILL_IDS + +export function listRuntimeToolNamesForSkill(skillId: RuntimeSkillId): RuntimeToolName[] { + const includedSkillIds: RuntimeSkillId[] = + skillId === 'docx-write' ? ['docx-read', 'docx-write'] : [skillId] + return RUNTIME_TOOL_NAMES.filter((toolName) => + includedSkillIds.includes(RUNTIME_TOOL_CATALOG[toolName].skillId) + ) +} + export const SKILL_DEFINITIONS = Object.fromEntries( RUNTIME_SKILL_IDS.map((skillId) => { const definition = RUNTIME_SKILL_CATALOG[skillId] @@ -87,4 +216,4 @@ export const findEffectiveSkillIdByToolName = (input: { return getEffectiveLearnedSkillIds(input.learnedSkillIds).find((skillId) => getSkillDefinition(skillId).toolNames.includes(target) ) -} +} \ No newline at end of file diff --git a/src/renderer/src/components/workbench/messageLogProjection.ts b/src/renderer/src/components/workbench/messageLogProjection.ts index e94b3df9..85c2c2b3 100644 --- a/src/renderer/src/components/workbench/messageLogProjection.ts +++ b/src/renderer/src/components/workbench/messageLogProjection.ts @@ -1,10 +1,9 @@ import type { AssistantProcessDisplay, ChatMessageLogEntry, - IpcJsonObject, - RuntimeSkillId + IpcJsonObject } from '../../../../shared/types' -import { RUNTIME_SKILL_CATALOG } from '../../../../shared/runtimeCapabilities' +import { isRuntimeSkillId } from '../../../../shared/runtimeCapabilities' import { normalizeThoughtText } from '../../../../shared/thoughtText' import { createDisplayProcessGroup, createDisplayProcessItem } from './utils' import type { @@ -15,10 +14,6 @@ import type { const CONTROL_TOOL_NAMES = new Set(['learn_skill', 'update_plan']) -const isRuntimeSkillId = (value: unknown): value is RuntimeSkillId => - typeof value === 'string' && - Object.prototype.hasOwnProperty.call(RUNTIME_SKILL_CATALOG, value) - export const projectProcessGroups = (input: { runId: string entries: ChatMessageLogEntry[] diff --git a/src/shared/runtimeCapabilities.ts b/src/shared/runtimeCapabilities.ts index 9bf47502..974131bb 100644 --- a/src/shared/runtimeCapabilities.ts +++ b/src/shared/runtimeCapabilities.ts @@ -13,140 +13,10 @@ export const AI_TOOL_FAMILY_IDS = [ ] as const export type RuntimeToolFamilyId = (typeof AI_TOOL_FAMILY_IDS)[number] -export type RuntimeSkillSource = 'builtin' | 'external' - -type RuntimeSkillCatalogEntry = { - familyId: RuntimeToolFamilyId - source: RuntimeSkillSource - countsTowardToolBudget: boolean - title: string - displayName: string - description: string -} - -export const RUNTIME_SKILL_CATALOG = { - terminal: { - familyId: 'terminal', - source: 'builtin', - countsTowardToolBudget: false, - title: 'terminal', - displayName: '命令执行器', - description: - '在用户工作区根目录执行和读取命令,并返回终端状态、增量输出、退出状态和用户工作区域文件产物。' - }, - 'text-file': { - familyId: 'text-file', - source: 'builtin', - countsTowardToolBudget: false, - title: 'text-file', - displayName: '文件编辑器', - description: '读取和写入 Markdown、TXT、代码等 UTF-8 普通文本文件。' - }, - 'kb-retrieval': { - familyId: 'kb', - source: 'builtin', - countsTowardToolBudget: false, - title: 'kb-retrieval', - displayName: '资料查阅器', - description: - '查询用户工作区域知识库的已索引文档或检索相关内容片段,并返回命中证据、来源文档与内容块信息。' - }, - 'web-browsing': { - familyId: 'web', - source: 'builtin', - countsTowardToolBudget: false, - title: 'web-browsing', - displayName: '网页浏览器', - description: - '按关键词搜索并读取公开网页正文,或直接读取指定网页,或操作内置浏览器,并返回网页正文、链接或浏览器动作结果。' - }, - 'docx-read': { - familyId: 'docx', - source: 'external', - countsTowardToolBudget: true, - title: 'docx-read', - displayName: 'docx 阅读器', - description: '读取 .docx、.doc 的结构、节点、检索结果和视觉内容。' - }, - 'docx-write': { - familyId: 'docx', - source: 'external', - countsTowardToolBudget: true, - title: 'docx-write', - displayName: 'docx 写作器', - description: '读取稳定 nodeId,并局部修改 DOCX 内容、格式、表格、媒体、批注和修订。' - }, - 'pdf-read': { - familyId: 'pdf', - source: 'external', - countsTowardToolBudget: true, - title: 'pdf-read', - displayName: 'PDF 阅读器', - description: '读取 PDF 文档信息、页级文本、检索结果和页面视觉内容。' - }, - 'ppt-read': { - familyId: 'ppt', - source: 'external', - countsTowardToolBudget: true, - title: 'ppt-read', - displayName: 'PPT 阅读器', - description: '读取 PPTX 的页面结构、内容、搜索结果和页面视觉内容。' - }, - 'ppt-write': { - familyId: 'ppt', - source: 'external', - countsTowardToolBudget: true, - title: 'ppt-write', - displayName: 'PPT 编辑器', - description: '使用受限 HTML 创建或编辑 PPTX 页面和元素。' - }, - 'excel-read': { - familyId: 'excel', - source: 'external', - countsTowardToolBudget: true, - title: 'excel-read', - displayName: 'Excel 阅读器', - description: '读取 Excel 工作簿、工作表、单元格范围、公式和值。' - }, - 'excel-write': { - familyId: 'excel', - source: 'external', - countsTowardToolBudget: true, - title: 'excel-write', - displayName: 'Excel 编辑器', - description: '创建或编辑 Excel 工作簿中的工作表、单元格、公式、格式和结构。' - }, - 'image-recognition': { - familyId: 'image-recognition', - source: 'external', - countsTowardToolBudget: true, - title: '图像识别', - displayName: '图像识别', - description: '读取图片并按 instruction 分析图片内容,并返回模型生成的文本结果。' - }, - 'image-generation': { - familyId: 'image-generation', - source: 'external', - countsTowardToolBudget: true, - title: '图片生成', - displayName: '图片生成', - description: '通过 SVG 绘制生成 PNG、JPEG 或 WebP 图片,并保存为用户工作区域文件。' - }, - 'agent-control': { - familyId: 'agent-control', - source: 'builtin', - countsTowardToolBudget: false, - title: 'agent-control', - displayName: '任务控制', - description: '管理任务推进过程:学习需要的技能、维护并更新执行计划。' - } -} as const satisfies Record - -export type RuntimeSkillId = keyof typeof RUNTIME_SKILL_CATALOG type RuntimeToolCatalogEntry = { familyId: RuntimeToolFamilyId - skillId: RuntimeSkillId + skillId: string } export const RUNTIME_TOOL_CATALOG = { @@ -188,23 +58,33 @@ export const RUNTIME_TOOL_CATALOG = { export type RuntimeToolName = keyof typeof RUNTIME_TOOL_CATALOG -export const RUNTIME_SKILL_IDS = Object.keys(RUNTIME_SKILL_CATALOG) as RuntimeSkillId[] -export const BUILTIN_RUNTIME_SKILL_IDS = RUNTIME_SKILL_IDS.filter( - (skillId) => RUNTIME_SKILL_CATALOG[skillId].source === 'builtin' -) -export const EXTERNAL_RUNTIME_SKILL_IDS = RUNTIME_SKILL_IDS.filter( - (skillId) => RUNTIME_SKILL_CATALOG[skillId].source === 'external' -) -export const LEARNABLE_RUNTIME_SKILL_IDS = EXTERNAL_RUNTIME_SKILL_IDS +export type RuntimeSkillId = (typeof RUNTIME_TOOL_CATALOG)[RuntimeToolName]['skillId'] + export const RUNTIME_TOOL_NAMES = Object.keys(RUNTIME_TOOL_CATALOG) as RuntimeToolName[] -export const getRuntimeSkillDisplayName = (skillId: string): string | undefined => - RUNTIME_SKILL_CATALOG[skillId as RuntimeSkillId]?.displayName +export const RUNTIME_SKILL_IDS = [ + ...new Set(RUNTIME_TOOL_NAMES.map((toolName) => RUNTIME_TOOL_CATALOG[toolName].skillId)) +] as RuntimeSkillId[] -export const listRuntimeToolNamesForSkill = (skillId: RuntimeSkillId): RuntimeToolName[] => { - const includedSkillIds: RuntimeSkillId[] = - skillId === 'docx-write' ? ['docx-read', 'docx-write'] : [skillId] - return RUNTIME_TOOL_NAMES.filter((toolName) => - includedSkillIds.includes(RUNTIME_TOOL_CATALOG[toolName].skillId) - ) -} +export const RUNTIME_SKILL_DISPLAY_NAMES = { + terminal: '命令执行器', + 'text-file': '文件编辑器', + 'kb-retrieval': '资料查阅器', + 'web-browsing': '网页浏览器', + 'docx-read': 'docx 阅读器', + 'docx-write': 'docx 写作器', + 'pdf-read': 'PDF 阅读器', + 'ppt-read': 'PPT 阅读器', + 'ppt-write': 'PPT 编辑器', + 'excel-read': 'Excel 阅读器', + 'excel-write': 'Excel 编辑器', + 'image-recognition': '图像识别', + 'image-generation': '图片生成', + 'agent-control': '任务控制' +} as const satisfies Record + +export const isRuntimeSkillId = (value: unknown): value is RuntimeSkillId => + typeof value === 'string' && RUNTIME_SKILL_IDS.includes(value as RuntimeSkillId) + +export const getRuntimeSkillDisplayName = (skillId: string): string | undefined => + RUNTIME_SKILL_DISPLAY_NAMES[skillId as RuntimeSkillId] \ No newline at end of file