Files
deepseek-harness/packages/core/tool-skill/src/index.ts
T
Yichen Jiang 83dfc3887e Merge origin/master into skill system branch
Resolve documentation split, tool presentation, and generated catalog changes from master while preserving the skill system integration.
2026-07-05 16:50:29 +08:00

53 lines
1.8 KiB
TypeScript

/**
* Model-facing `skill` tool.
*
* @module @deepseek-ai/dsh-tool-skill
*/
import type { Context } from 'cordis'
import { defineTool } from '@deepseek-ai/dsh-tools'
import { isSkillName, type SkillDefinition } from '@deepseek-ai/dsh-skill'
export const name = 'tool-skill'
export const inject = ['tools', 'skills']
export function apply(ctx: Context): void {
const skillTool = defineTool({
name: 'skill',
description: 'Load the full instructions for one available skill by name. Use this when the current task matches a skill listed in the system prompt.',
parameters: {
name: { type: 'string', required: true, description: 'The exact skill name from the available skills list.' },
},
async execute(args, exec) {
if (!isSkillName(args.name)) {
throw new Error(`invalid skill name "${args.name}"`)
}
const skill = await ctx.skills.get(args.name, { cwd: exec.agent?.session.header.cwd })
if (!skill) {
throw new Error(`unknown skill "${args.name}"`)
}
if (skill.disableModelInvocation === true) {
throw new Error(`skill "${args.name}" is not available for model invocation`)
}
return [{ type: 'text', text: renderSkillContent(skill) }]
},
presentCall(args) {
return { card: 'generic', title: `Load skill ${args.name}`, kind: 'read', rawInput: args.name }
},
})
ctx.tools.register(skillTool)
}
function renderSkillContent(skill: SkillDefinition): string {
return [
`<skill_content name="${skill.name}">`,
`# Skill: ${skill.name}`,
'',
skill.content,
'',
`Base directory for this skill: ${skill.directory}`,
'Resolve relative files mentioned by this skill against the base directory before using them.',
'</skill_content>',
].join('\n')
}