From f96e2d4222d70849ef8d4992565dc94e64832243 Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Wed, 11 Mar 2026 16:03:15 -0500 Subject: [PATCH] tweak: adjust skill presentation to be a little less token heavy (#17098) --- packages/opencode/src/session/system.ts | 4 ++- packages/opencode/src/skill/skill.ts | 30 ++++++++++++++--------- packages/opencode/src/tool/skill.ts | 2 +- packages/opencode/test/tool/skill.test.ts | 2 +- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/packages/opencode/src/session/system.ts b/packages/opencode/src/session/system.ts index 0f0f6b51b..a4c4684ff 100644 --- a/packages/opencode/src/session/system.ts +++ b/packages/opencode/src/session/system.ts @@ -64,7 +64,9 @@ export namespace SystemPrompt { return [ "Skills provide specialized instructions and workflows for specific tasks.", "Use the skill tool to load a skill when a task matches its description.", - list.length === 0 ? "No skills are currently available." : "\n" + Skill.fmt(list), + // the agents seem to ingest the information about skills a bit better if we present a more verbose + // version of them here and a less verbose version in tool description, rather than vice versa. + Skill.fmt(list, { verbose: true }), ].join("\n") } } diff --git a/packages/opencode/src/skill/skill.ts b/packages/opencode/src/skill/skill.ts index 09cc787c8..fa984b3e1 100644 --- a/packages/opencode/src/skill/skill.ts +++ b/packages/opencode/src/skill/skill.ts @@ -196,17 +196,23 @@ export namespace Skill { return list.filter((skill) => PermissionNext.evaluate("skill", skill.name, agent.permission).action !== "deny") } - export function fmt(list: Info[]) { - return [ - "", - ...list.flatMap((skill) => [ - ` `, - ` ${skill.name}`, - ` ${skill.description}`, - ` ${pathToFileURL(skill.location).href}`, - ` `, - ]), - "", - ].join("\n") + export function fmt(list: Info[], opts: { verbose: boolean }) { + if (list.length === 0) { + return "No skills are currently available." + } + if (opts.verbose) { + return [ + "", + ...list.flatMap((skill) => [ + ` `, + ` ${skill.name}`, + ` ${skill.description}`, + ` ${pathToFileURL(skill.location).href}`, + ` `, + ]), + "", + ].join("\n") + } + return ["## Available Skills", ...list.flatMap((skill) => `- **${skill.name}**: ${skill.description}`)].join("\n") } } diff --git a/packages/opencode/src/tool/skill.ts b/packages/opencode/src/tool/skill.ts index 6d2a48b0e..17016b06f 100644 --- a/packages/opencode/src/tool/skill.ts +++ b/packages/opencode/src/tool/skill.ts @@ -24,7 +24,7 @@ export const SkillTool = Tool.define("skill", async (ctx) => { "The following skills provide specialized sets of instructions for particular tasks", "Invoke this tool to load a skill when a task matches one of the available skills listed below:", "", - Skill.fmt(list), + Skill.fmt(list, { verbose: false }), ].join("\n") const examples = list diff --git a/packages/opencode/test/tool/skill.test.ts b/packages/opencode/test/tool/skill.test.ts index d5057ba9e..c47259f15 100644 --- a/packages/opencode/test/tool/skill.test.ts +++ b/packages/opencode/test/tool/skill.test.ts @@ -45,7 +45,7 @@ description: Skill for tool tests. fn: async () => { const tool = await SkillTool.init() const skillPath = path.join(tmp.path, ".opencode", "skill", "tool-skill", "SKILL.md") - expect(tool.description).toContain(`${pathToFileURL(skillPath).href}`) + expect(tool.description).toContain(`**tool-skill**: Skill for tool tests.`) }, }) } finally {