Merge pull request #1491 from itsmylife44/refactor/extract-formatCustomSkillsBlock

refactor(agents): extract formatCustomSkillsBlock to eliminate duplication
This commit is contained in:
YeonGyu-Kim 2026-02-05 17:40:54 +09:00 committed by GitHub
commit 77e99d8b68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 78 additions and 45 deletions

View File

@ -6,7 +6,7 @@
*/ */
import type { CategoryConfig } from "../../config/schema" import type { CategoryConfig } from "../../config/schema"
import type { AvailableAgent, AvailableSkill } from "../dynamic-agent-prompt-builder" import { formatCustomSkillsBlock, type AvailableAgent, type AvailableSkill } from "../dynamic-agent-prompt-builder"
import { DEFAULT_CATEGORIES, CATEGORY_DESCRIPTIONS } from "../../tools/delegate-task/constants" import { DEFAULT_CATEGORIES, CATEGORY_DESCRIPTIONS } from "../../tools/delegate-task/constants"
export const getCategoryDescription = (name: string, userCategories?: Record<string, CategoryConfig>) => export const getCategoryDescription = (name: string, userCategories?: Record<string, CategoryConfig>) =>
@ -70,7 +70,7 @@ export function buildSkillsSection(skills: AvailableSkill[]): string {
return `| \`${s.name}\` | ${shortDesc} | ${source} |` return `| \`${s.name}\` | ${shortDesc} | ${source} |`
}) })
const customSkillNames = customSkills.map((s) => `"${s.name}"`).join(", ") const customSkillBlock = formatCustomSkillsBlock(customRows, customSkills, "**")
let skillsTable: string let skillsTable: string
@ -81,27 +81,9 @@ export function buildSkillsSection(skills: AvailableSkill[]): string {
|-------|-------------| |-------|-------------|
${builtinRows.join("\n")} ${builtinRows.join("\n")}
**User-Installed Skills (HIGH PRIORITY):** ${customSkillBlock}`
The user installed these for their workflow. They MUST be evaluated for EVERY delegation.
| Skill | When to Use | Source |
|-------|-------------|--------|
${customRows.join("\n")}
> **CRITICAL**: The user installed ${customSkillNames} for a reason USE THEM when the task overlaps with their domain.
> When in doubt, INCLUDE a user-installed skill rather than omit it.`
} else if (customSkills.length > 0) { } else if (customSkills.length > 0) {
skillsTable = `**User-Installed Skills (HIGH PRIORITY):** skillsTable = customSkillBlock
The user installed these for their workflow. They MUST be evaluated for EVERY delegation.
| Skill | When to Use | Source |
|-------|-------------|--------|
${customRows.join("\n")}
> **CRITICAL**: The user installed ${customSkillNames} for a reason USE THEM when the task overlaps with their domain.
> When in doubt, INCLUDE a user-installed skill rather than omit it.`
} else { } else {
skillsTable = `| Skill | When to Use | skillsTable = `| Skill | When to Use |
|-------|-------------| |-------|-------------|

View File

@ -4,6 +4,7 @@ import { describe, it, expect } from "bun:test"
import { import {
buildCategorySkillsDelegationGuide, buildCategorySkillsDelegationGuide,
buildUltraworkSection, buildUltraworkSection,
formatCustomSkillsBlock,
type AvailableSkill, type AvailableSkill,
type AvailableCategory, type AvailableCategory,
type AvailableAgent, type AvailableAgent,
@ -159,3 +160,46 @@ describe("buildUltraworkSection", () => {
expect(result).not.toContain("User-Installed Skills") expect(result).not.toContain("User-Installed Skills")
}) })
}) })
describe("formatCustomSkillsBlock", () => {
const customSkills: AvailableSkill[] = [
{ name: "react-19", description: "React 19 patterns", location: "user" },
{ name: "tailwind-4", description: "Tailwind v4", location: "project" },
]
const customRows = customSkills.map((s) => {
const source = s.location === "project" ? "project" : "user"
return `| \`${s.name}\` | ${s.description} | ${source} |`
})
it("should produce consistent output used by both builders", () => {
//#given: custom skills and rows
//#when: formatting with default header level
const result = formatCustomSkillsBlock(customRows, customSkills)
//#then: contains all expected elements
expect(result).toContain("User-Installed Skills (HIGH PRIORITY)")
expect(result).toContain("CRITICAL")
expect(result).toContain('"react-19"')
expect(result).toContain('"tailwind-4"')
expect(result).toContain("| user |")
expect(result).toContain("| project |")
})
it("should use #### header by default", () => {
//#given: default header level
const result = formatCustomSkillsBlock(customRows, customSkills)
//#then: uses markdown h4
expect(result).toContain("#### User-Installed Skills")
})
it("should use bold header when specified", () => {
//#given: bold header level (used by Atlas)
const result = formatCustomSkillsBlock(customRows, customSkills, "**")
//#then: uses bold instead of h4
expect(result).toContain("**User-Installed Skills (HIGH PRIORITY):**")
expect(result).not.toContain("#### User-Installed Skills")
})
})

View File

@ -166,6 +166,33 @@ export function buildDelegationTable(agents: AvailableAgent[]): string {
return rows.join("\n") return rows.join("\n")
} }
/**
* Renders the "User-Installed Skills (HIGH PRIORITY)" block used across multiple agent prompts.
* Extracted to avoid duplication between buildCategorySkillsDelegationGuide, buildSkillsSection, etc.
*/
export function formatCustomSkillsBlock(
customRows: string[],
customSkills: AvailableSkill[],
headerLevel: "####" | "**" = "####"
): string {
const customSkillNames = customSkills.map((s) => `"${s.name}"`).join(", ")
const header = headerLevel === "####"
? `#### User-Installed Skills (HIGH PRIORITY)`
: `**User-Installed Skills (HIGH PRIORITY):**`
return `${header}
**The user has installed these custom skills. They MUST be evaluated for EVERY delegation.**
Subagents are STATELESS they lose all custom knowledge unless you pass these skills via \`load_skills\`.
| Skill | Expertise Domain | Source |
|-------|------------------|--------|
${customRows.join("\n")}
> **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.`
}
export function buildCategorySkillsDelegationGuide(categories: AvailableCategory[], skills: AvailableSkill[]): string { export function buildCategorySkillsDelegationGuide(categories: AvailableCategory[], skills: AvailableSkill[]): string {
if (categories.length === 0 && skills.length === 0) return "" if (categories.length === 0 && skills.length === 0) return ""
@ -188,7 +215,7 @@ export function buildCategorySkillsDelegationGuide(categories: AvailableCategory
return `| \`${s.name}\` | ${desc} | ${source} |` return `| \`${s.name}\` | ${desc} | ${source} |`
}) })
const customSkillNames = customSkills.map((s) => `"${s.name}"`).join(", ") const customSkillBlock = formatCustomSkillsBlock(customRows, customSkills)
let skillsSection: string let skillsSection: string
@ -199,29 +226,9 @@ export function buildCategorySkillsDelegationGuide(categories: AvailableCategory
|-------|------------------| |-------|------------------|
${builtinRows.join("\n")} ${builtinRows.join("\n")}
#### User-Installed Skills (HIGH PRIORITY) ${customSkillBlock}`
**The user has installed these custom skills. They MUST be evaluated for EVERY delegation.**
Subagents are STATELESS they lose all custom knowledge unless you pass these skills via \`load_skills\`.
| Skill | Expertise Domain | Source |
|-------|------------------|--------|
${customRows.join("\n")}
> **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.`
} else if (customSkills.length > 0) { } else if (customSkills.length > 0) {
skillsSection = `#### User-Installed Skills (HIGH PRIORITY) skillsSection = customSkillBlock
**The user has installed these custom skills. They MUST be evaluated for EVERY delegation.**
Subagents are STATELESS they lose all custom knowledge unless you pass these skills via \`load_skills\`.
| Skill | Expertise Domain | Source |
|-------|------------------|--------|
${customRows.join("\n")}
> **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.`
} else { } else {
skillsSection = `#### Available Skills (Domain Expertise Injection) skillsSection = `#### Available Skills (Domain Expertise Injection)