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 {