fix(skill): unify command listing format and trim verbose description
This commit is contained in:
parent
e70539fe5f
commit
17d3184e7a
@ -2,13 +2,8 @@ export const TOOL_NAME = "skill" as const
|
|||||||
|
|
||||||
export const TOOL_DESCRIPTION_NO_SKILLS = "Load a skill or execute a slash command to get detailed instructions for a specific task. No skills are currently available."
|
export const TOOL_DESCRIPTION_NO_SKILLS = "Load a skill or execute a slash command to get detailed instructions for a specific task. No skills are currently available."
|
||||||
|
|
||||||
export const TOOL_DESCRIPTION_PREFIX = `Load a skill or execute a slash command to get detailed instructions for a specific task.
|
export const TOOL_DESCRIPTION_PREFIX = `Load a skill or execute a command to get detailed instructions for a specific task.
|
||||||
|
|
||||||
Skills and commands provide specialized knowledge and step-by-step guidance.
|
Skills and commands provide specialized knowledge and step-by-step guidance.
|
||||||
Use this when a task matches an available skill's or command's description.
|
Use this when a task matches an available skill's or command's description.
|
||||||
|
|
||||||
**How to use:**
|
|
||||||
- Call with a skill name: name='code-review'
|
|
||||||
- Call with a command name (without leading slash): name='publish'
|
|
||||||
- The tool will return detailed instructions with your context applied.
|
|
||||||
`
|
`
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import * as fs from "node:fs"
|
|||||||
import { createSkillTool } from "./tools"
|
import { createSkillTool } from "./tools"
|
||||||
import { SkillMcpManager } from "../../features/skill-mcp-manager"
|
import { SkillMcpManager } from "../../features/skill-mcp-manager"
|
||||||
import type { LoadedSkill } from "../../features/opencode-skill-loader/types"
|
import type { LoadedSkill } from "../../features/opencode-skill-loader/types"
|
||||||
|
import type { CommandInfo } from "../slashcommand/types"
|
||||||
import type { Tool as McpTool } from "@modelcontextprotocol/sdk/types.js"
|
import type { Tool as McpTool } from "@modelcontextprotocol/sdk/types.js"
|
||||||
|
|
||||||
const originalReadFileSync = fs.readFileSync.bind(fs)
|
const originalReadFileSync = fs.readFileSync.bind(fs)
|
||||||
@ -105,6 +106,61 @@ describe("skill tool - synchronous description", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("skill tool - command listing format", () => {
|
||||||
|
it("uses XML format for commands in description", () => {
|
||||||
|
// given
|
||||||
|
const commands: CommandInfo[] = [
|
||||||
|
{
|
||||||
|
name: "publish",
|
||||||
|
path: "/test/commands/publish",
|
||||||
|
metadata: { name: "publish", description: "Publish to npm", argumentHint: "<patch|minor|major>" },
|
||||||
|
scope: "opencode-project",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "commit",
|
||||||
|
path: "/test/commands/commit",
|
||||||
|
metadata: { name: "commit", description: "Commits changes" },
|
||||||
|
scope: "builtin",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// when
|
||||||
|
const tool = createSkillTool({ skills: [], commands })
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(tool.description).toContain("<available_commands>")
|
||||||
|
expect(tool.description).toContain("</available_commands>")
|
||||||
|
expect(tool.description).toContain("<command>")
|
||||||
|
expect(tool.description).toContain("<name>/publish <patch|minor|major></name>")
|
||||||
|
expect(tool.description).toContain("<description>Publish to npm</description>")
|
||||||
|
expect(tool.description).toContain("<scope>opencode-project</scope>")
|
||||||
|
expect(tool.description).toContain("<name>/commit</name>")
|
||||||
|
expect(tool.description).toContain("<scope>builtin</scope>")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("uses XML format for both skills and commands together", () => {
|
||||||
|
// given
|
||||||
|
const loadedSkills = [createMockSkill("test-skill")]
|
||||||
|
const commands: CommandInfo[] = [
|
||||||
|
{
|
||||||
|
name: "deploy",
|
||||||
|
path: "/test/commands/deploy",
|
||||||
|
metadata: { name: "deploy", description: "Deploy app" },
|
||||||
|
scope: "user",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// when
|
||||||
|
const tool = createSkillTool({ skills: loadedSkills, commands })
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(tool.description).toContain("<available_skills>")
|
||||||
|
expect(tool.description).toContain("<available_commands>")
|
||||||
|
expect(tool.description).toContain("<command>")
|
||||||
|
expect(tool.description).toContain("<name>/deploy</name>")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("skill tool - agent restriction", () => {
|
describe("skill tool - agent restriction", () => {
|
||||||
it("allows skill without agent restriction to any agent", async () => {
|
it("allows skill without agent restriction to any agent", async () => {
|
||||||
// given
|
// given
|
||||||
|
|||||||
@ -48,11 +48,18 @@ function formatCombinedDescription(skills: SkillInfo[], commands: CommandInfo[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (commands.length > 0) {
|
if (commands.length > 0) {
|
||||||
const commandLines = commands.map(cmd => {
|
const commandsXml = commands.map(cmd => {
|
||||||
const hint = cmd.metadata.argumentHint ? ` ${cmd.metadata.argumentHint}` : ""
|
const hint = cmd.metadata.argumentHint ? ` ${cmd.metadata.argumentHint}` : ""
|
||||||
return ` - /${cmd.name}${hint}: ${cmd.metadata.description || "(no description)"} (${cmd.scope})`
|
const parts = [
|
||||||
|
" <command>",
|
||||||
|
` <name>/${cmd.name}${hint}</name>`,
|
||||||
|
` <description>${cmd.metadata.description || "(no description)"}</description>`,
|
||||||
|
` <scope>${cmd.scope}</scope>`,
|
||||||
|
" </command>",
|
||||||
|
]
|
||||||
|
return parts.join("\n")
|
||||||
}).join("\n")
|
}).join("\n")
|
||||||
lines.push(`\n<available_commands>\n${commandLines}\n</available_commands>`)
|
lines.push(`\n<available_commands>\n${commandsXml}\n</available_commands>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return TOOL_DESCRIPTION_PREFIX + lines.join("")
|
return TOOL_DESCRIPTION_PREFIX + lines.join("")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user