fix(agent): surface installed skill ids in prompt
This commit is contained in:
parent
50407918b9
commit
6fd4819280
2 changed files with 64 additions and 4 deletions
|
|
@ -222,11 +222,26 @@ describe("buildSkillsSection", () => {
|
|||
const result = buildSkillsSection("## commit\nDo commits.", "full");
|
||||
const text = result.join("\n");
|
||||
expect(text).toContain("capability gap");
|
||||
expect(text).toContain("meta-skill-installer");
|
||||
expect(text).toContain("explicit user confirmation");
|
||||
expect(text).toContain("clawhub install");
|
||||
});
|
||||
|
||||
it("surfaces installed skill IDs and prioritizes meta skill guidance when present", () => {
|
||||
const prompt = [
|
||||
"## 🔧 Meta Skill Installer (meta-skill-installer)",
|
||||
"Detect missing capabilities.",
|
||||
"",
|
||||
"## 📄 PDF (pdf)",
|
||||
"Handle PDFs.",
|
||||
].join("\n");
|
||||
const result = buildSkillsSection(prompt, "full");
|
||||
const text = result.join("\n");
|
||||
expect(text).toContain("Installed skill IDs:");
|
||||
expect(text).toContain("`meta-skill-installer`");
|
||||
expect(text).toContain("is installed");
|
||||
expect(text).toContain("ClawHub search");
|
||||
});
|
||||
|
||||
it("returns empty in minimal mode", () => {
|
||||
expect(buildSkillsSection("skills", "minimal")).toEqual([]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -391,22 +391,67 @@ export function buildSkillsSection(
|
|||
const trimmed = skillsPrompt?.trim();
|
||||
if (!trimmed) return [];
|
||||
|
||||
const skillIds = extractSkillIdsFromSkillsPrompt(trimmed);
|
||||
const hasMetaSkillInstaller = skillIds.includes("meta-skill-installer");
|
||||
const { text: budgeted } = truncateWithBudget(trimmed, DEFAULT_SKILLS_MAX_CHARS);
|
||||
|
||||
return [
|
||||
const lines: string[] = [
|
||||
"## Skills (mandatory)",
|
||||
"Before replying: scan the available skills below.",
|
||||
];
|
||||
|
||||
if (skillIds.length > 0) {
|
||||
lines.push(
|
||||
`Installed skill IDs: ${skillIds.map((id) => `\`${id}\``).join(", ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
lines.push(
|
||||
"- If exactly one skill clearly applies: follow its instructions.",
|
||||
"- If multiple could apply: choose the most specific one.",
|
||||
"- If none clearly apply but an **inactive skill** matches the user's intent: suggest activating it.",
|
||||
"- If the request needs a capability you currently lack: do not stop at refusal. Treat it as a capability gap and propose a recovery path.",
|
||||
"- If `meta-skill-installer` is available and no installed skill matches: proactively offer to search ClawHub for candidates and run security review before install.",
|
||||
);
|
||||
|
||||
if (hasMetaSkillInstaller) {
|
||||
lines.push(
|
||||
"- `meta-skill-installer` is installed: for capability gaps with no matching installed skill, proactively offer ClawHub search + security review + explicit install confirmation.",
|
||||
);
|
||||
} else {
|
||||
lines.push(
|
||||
"- If `meta-skill-installer` is available and no installed skill matches: proactively offer to search ClawHub for candidates and run security review before install.",
|
||||
);
|
||||
}
|
||||
|
||||
lines.push(
|
||||
"- Ask for explicit user confirmation before final `clawhub install` / `clawhub update` unless the user already clearly asked you to install in this turn.",
|
||||
"- After install/update, verify the skill path and retry the original user task.",
|
||||
"",
|
||||
budgeted,
|
||||
"",
|
||||
];
|
||||
);
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract skill IDs from SkillManager prompt headings.
|
||||
* Expected heading format: `## <emoji> <name> (<id>)`
|
||||
*/
|
||||
function extractSkillIdsFromSkillsPrompt(skillsPrompt: string): string[] {
|
||||
const ids: string[] = [];
|
||||
const seen = new Set<string>();
|
||||
const headingRegex = /^##\s+.*\(([^()\n]+)\)\s*$/gm;
|
||||
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = headingRegex.exec(skillsPrompt)) !== null) {
|
||||
const id = match[1]?.trim();
|
||||
if (!id || seen.has(id)) continue;
|
||||
seen.add(id);
|
||||
ids.push(id);
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue