refactor(prompt): dedupe repeated skill guidance blocks
This commit is contained in:
parent
810ebc0428
commit
fbf3018ee4
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { CategoryConfig } from "../../config/schema"
|
import type { CategoryConfig } from "../../config/schema"
|
||||||
import { formatCustomSkillsBlock, type AvailableAgent, type AvailableSkill } from "../dynamic-agent-prompt-builder"
|
import type { AvailableAgent, AvailableSkill } from "../dynamic-agent-prompt-builder"
|
||||||
import { CATEGORY_DESCRIPTIONS } from "../../tools/delegate-task/constants"
|
import { CATEGORY_DESCRIPTIONS } from "../../tools/delegate-task/constants"
|
||||||
import { mergeCategories } from "../../shared/merge-categories"
|
import { mergeCategories } from "../../shared/merge-categories"
|
||||||
import { truncateDescription } from "../../shared/truncate-description"
|
import { truncateDescription } from "../../shared/truncate-description"
|
||||||
@ -58,43 +58,16 @@ export function buildSkillsSection(skills: AvailableSkill[]): string {
|
|||||||
const builtinSkills = skills.filter((s) => s.location === "plugin")
|
const builtinSkills = skills.filter((s) => s.location === "plugin")
|
||||||
const customSkills = skills.filter((s) => s.location !== "plugin")
|
const customSkills = skills.filter((s) => s.location !== "plugin")
|
||||||
|
|
||||||
const builtinRows = builtinSkills.map((s) => {
|
|
||||||
const shortDesc = truncateDescription(s.description)
|
|
||||||
return `- **\`${s.name}\`** — ${shortDesc}`
|
|
||||||
})
|
|
||||||
|
|
||||||
const customRows = customSkills.map((s) => {
|
|
||||||
const shortDesc = truncateDescription(s.description)
|
|
||||||
const source = s.location === "project" ? "project" : "user"
|
|
||||||
return `- **\`${s.name}\`** (${source}): ${shortDesc}`
|
|
||||||
})
|
|
||||||
|
|
||||||
const customSkillBlock = formatCustomSkillsBlock(customRows, customSkills, "**")
|
|
||||||
|
|
||||||
let skillsTable: string
|
|
||||||
|
|
||||||
if (customSkills.length > 0 && builtinSkills.length > 0) {
|
|
||||||
skillsTable = `**Built-in Skills:**
|
|
||||||
|
|
||||||
${builtinRows.join("\n")}
|
|
||||||
|
|
||||||
${customSkillBlock}`
|
|
||||||
} else if (customSkills.length > 0) {
|
|
||||||
skillsTable = customSkillBlock
|
|
||||||
} else {
|
|
||||||
skillsTable = `${builtinRows.join("\n")}`
|
|
||||||
}
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
#### 3.2.2: Skill Selection (PREPEND TO PROMPT)
|
#### 3.2.2: Skill Selection (PREPEND TO PROMPT)
|
||||||
|
|
||||||
**Skills are specialized instructions that guide subagent behavior. Consider them alongside category selection.**
|
**Use the \`Category + Skills Delegation System\` section below as the single source of truth for skill details.**
|
||||||
|
- Built-in skills available: ${builtinSkills.length}
|
||||||
${skillsTable}
|
- User-installed skills available: ${customSkills.length}
|
||||||
|
|
||||||
**MANDATORY: Evaluate ALL skills (built-in AND user-installed) for relevance to your task.**
|
**MANDATORY: Evaluate ALL skills (built-in AND user-installed) for relevance to your task.**
|
||||||
|
|
||||||
Read each skill's description and ask: "Does this skill's domain overlap with my task?"
|
Read each skill's description in the section below and ask: "Does this skill's domain overlap with my task?"
|
||||||
- If YES: INCLUDE in load_skills=[...]
|
- If YES: INCLUDE in load_skills=[...]
|
||||||
- If NO: You MUST justify why in your pre-delegation declaration
|
- If NO: You MUST justify why in your pre-delegation declaration
|
||||||
|
|
||||||
|
|||||||
@ -43,16 +43,16 @@ describe("buildCategorySkillsDelegationGuide", () => {
|
|||||||
expect(result).toContain("HIGH PRIORITY")
|
expect(result).toContain("HIGH PRIORITY")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should include custom skill names in CRITICAL warning", () => {
|
it("should list custom skills and keep CRITICAL warning", () => {
|
||||||
//#given: custom skills installed
|
//#given: custom skills installed
|
||||||
const allSkills = [...builtinSkills, ...customUserSkills]
|
const allSkills = [...builtinSkills, ...customUserSkills]
|
||||||
|
|
||||||
//#when: building the delegation guide
|
//#when: building the delegation guide
|
||||||
const result = buildCategorySkillsDelegationGuide(categories, allSkills)
|
const result = buildCategorySkillsDelegationGuide(categories, allSkills)
|
||||||
|
|
||||||
//#then: should mention custom skills by name in the warning
|
//#then: should mention custom skills by name and include warning
|
||||||
expect(result).toContain('"react-19"')
|
expect(result).toContain("`react-19`")
|
||||||
expect(result).toContain('"tailwind-4"')
|
expect(result).toContain("`tailwind-4`")
|
||||||
expect(result).toContain("CRITICAL")
|
expect(result).toContain("CRITICAL")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -180,8 +180,8 @@ describe("formatCustomSkillsBlock", () => {
|
|||||||
//#then: contains all expected elements
|
//#then: contains all expected elements
|
||||||
expect(result).toContain("User-Installed Skills (HIGH PRIORITY)")
|
expect(result).toContain("User-Installed Skills (HIGH PRIORITY)")
|
||||||
expect(result).toContain("CRITICAL")
|
expect(result).toContain("CRITICAL")
|
||||||
expect(result).toContain('"react-19"')
|
expect(result).toContain("`react-19`")
|
||||||
expect(result).toContain('"tailwind-4"')
|
expect(result).toContain("`tailwind-4`")
|
||||||
expect(result).toContain("| user |")
|
expect(result).toContain("| user |")
|
||||||
expect(result).toContain("| project |")
|
expect(result).toContain("| project |")
|
||||||
})
|
})
|
||||||
|
|||||||
@ -167,7 +167,6 @@ export function formatCustomSkillsBlock(
|
|||||||
customSkills: AvailableSkill[],
|
customSkills: AvailableSkill[],
|
||||||
headerLevel: "####" | "**" = "####"
|
headerLevel: "####" | "**" = "####"
|
||||||
): string {
|
): string {
|
||||||
const customSkillNames = customSkills.map((s) => `"${s.name}"`).join(", ")
|
|
||||||
const header = headerLevel === "####"
|
const header = headerLevel === "####"
|
||||||
? `#### User-Installed Skills (HIGH PRIORITY)`
|
? `#### User-Installed Skills (HIGH PRIORITY)`
|
||||||
: `**User-Installed Skills (HIGH PRIORITY):**`
|
: `**User-Installed Skills (HIGH PRIORITY):**`
|
||||||
@ -180,7 +179,7 @@ Subagents are STATELESS — they lose all custom knowledge unless you pass these
|
|||||||
${customRows.join("\n")}
|
${customRows.join("\n")}
|
||||||
|
|
||||||
> **CRITICAL**: Ignoring user-installed skills when they match the task domain is a failure.
|
> **CRITICAL**: Ignoring user-installed skills when they match the task domain is a failure.
|
||||||
> The user installed ${customSkillNames} for a reason — USE THEM when the task overlaps with their domain.`
|
> The user installed custom skills for a reason — USE THEM when the task overlaps with their domain.`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildCategorySkillsDelegationGuide(categories: AvailableCategory[], skills: AvailableSkill[]): string {
|
export function buildCategorySkillsDelegationGuide(categories: AvailableCategory[], skills: AvailableSkill[]): string {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user