feat(core): improve activate_skill tool and use lowercase XML tags (#16009)

This commit is contained in:
N. Taylor Mullen
2026-01-06 17:10:00 -08:00
committed by GitHub
parent 59a18e710d
commit da85e3f8f2
4 changed files with 30 additions and 18 deletions
@@ -87,14 +87,14 @@ describe('ActivateSkillTool', () => {
expect(mockConfig.getWorkspaceContext().addDirectory).toHaveBeenCalledWith(
'/path/to/test-skill',
);
expect(result.llmContent).toContain('<ACTIVATED_SKILL name="test-skill">');
expect(result.llmContent).toContain('<INSTRUCTIONS>');
expect(result.llmContent).toContain('<activated_skill name="test-skill">');
expect(result.llmContent).toContain('<instructions>');
expect(result.llmContent).toContain('Skill instructions content.');
expect(result.llmContent).toContain('</INSTRUCTIONS>');
expect(result.llmContent).toContain('<AVAILABLE_RESOURCES>');
expect(result.llmContent).toContain('</instructions>');
expect(result.llmContent).toContain('<available_resources>');
expect(result.llmContent).toContain('Mock folder structure');
expect(result.llmContent).toContain('</AVAILABLE_RESOURCES>');
expect(result.llmContent).toContain('</ACTIVATED_SKILL>');
expect(result.llmContent).toContain('</available_resources>');
expect(result.llmContent).toContain('</activated_skill>');
expect(result.returnDisplay).toContain('Skill **test-skill** activated');
expect(result.returnDisplay).toContain('Mock folder structure');
});
+22 -10
View File
@@ -18,6 +18,7 @@ import type {
import { BaseDeclarativeTool, BaseToolInvocation, Kind } from './tools.js';
import type { Config } from '../config/config.js';
import { ACTIVATE_SKILL_TOOL_NAME } from './tool-names.js';
import { ToolErrorType } from './tool-error.js';
/**
* Parameters for the ActivateSkill tool
@@ -51,7 +52,7 @@ class ActivateSkillToolInvocation extends BaseToolInvocation<
if (skill) {
return `"${skillName}": ${skill.description}`;
}
return `"${skillName}" (⚠️ unknown skill)`;
return `"${skillName}" (?) unknown skill`;
}
private async getOrFetchFolderStructure(
@@ -107,9 +108,15 @@ ${folderStructure}`,
if (!skill) {
const skills = skillManager.getSkills();
const availableSkills = skills.map((s) => s.name).join(', ');
const errorMessage = `Skill "${skillName}" not found. Available skills are: ${availableSkills}`;
return {
llmContent: `Error: Skill "${skillName}" not found. Available skills are: ${skills.map((s) => s.name).join(', ')}`,
returnDisplay: `Skill "${skillName}" not found.`,
llmContent: `Error: ${errorMessage}`,
returnDisplay: `Error: ${errorMessage}`,
error: {
message: errorMessage,
type: ToolErrorType.INVALID_TOOL_PARAMS,
},
};
}
@@ -126,15 +133,15 @@ ${folderStructure}`,
);
return {
llmContent: `<ACTIVATED_SKILL name="${skillName}">
<INSTRUCTIONS>
llmContent: `<activated_skill name="${skillName}">
<instructions>
${skill.body}
</INSTRUCTIONS>
</instructions>
<AVAILABLE_RESOURCES>
<available_resources>
${folderStructure}
</AVAILABLE_RESOURCES>
</ACTIVATED_SKILL>`,
</available_resources>
</activated_skill>`,
returnDisplay: `Skill **${skillName}** activated. Resources loaded from \`${path.dirname(skill.location)}\`:\n\n${folderStructure}`,
};
}
@@ -169,10 +176,15 @@ export class ActivateSkillTool extends BaseDeclarativeTool<
});
}
const availableSkillsHint =
skillNames.length > 0
? ` (Available: ${skillNames.map((n) => `'${n}'`).join(', ')})`
: '';
super(
ActivateSkillTool.Name,
'Activate Skill',
"Activates a specialized agent skill by name. Returns the skill's instructions wrapped in `<ACTIVATED_SKILL>` tags. These provide specialized guidance for the current task. Use this when you identify a task that matches a skill's description.",
`Activates a specialized agent skill by name${availableSkillsHint}. Returns the skill's instructions wrapped in \`<activated_skill>\` tags. These provide specialized guidance for the current task. Use this when you identify a task that matches a skill's description. ONLY use names exactly as they appear in the \`<available_skills>\` section.`,
Kind.Other,
zodToJsonSchema(schema),
messageBus,