Merge pull request #3745 from mastertyko/fix/3705-subagent-tools-frontmatter
fix(subagent): support list-style tools frontmatter
This commit is contained in:
commit
ae5e4af61e
2 changed files with 77 additions and 6 deletions
|
|
@ -42,3 +42,50 @@ test("discoverAgents falls back to legacy .pi/agents when needed", (t) => {
|
|||
assert.equal(discovery.projectAgentsDir, agentsDir);
|
||||
assert.deepEqual(discovery.agents.map((agent) => agent.name), ["ping"]);
|
||||
});
|
||||
|
||||
test("discoverAgents accepts tools frontmatter as a YAML list", (t) => {
|
||||
const root = makeProjectRoot(t);
|
||||
const agentsDir = join(root, ".gsd", "agents");
|
||||
mkdirSync(agentsDir, { recursive: true });
|
||||
writeFileSync(
|
||||
join(agentsDir, "reviewer.md"),
|
||||
[
|
||||
"---",
|
||||
"name: reviewer",
|
||||
"description: review agent",
|
||||
"tools:",
|
||||
" - bash",
|
||||
" - read",
|
||||
"---",
|
||||
"Review code",
|
||||
"",
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
const discovery = discoverAgents(root, "project");
|
||||
|
||||
assert.deepEqual(discovery.agents.map((agent) => agent.name), ["reviewer"]);
|
||||
assert.deepEqual(discovery.agents[0]?.tools, ["bash", "read"]);
|
||||
});
|
||||
|
||||
test("discoverAgents still accepts comma-separated tools frontmatter", (t) => {
|
||||
const root = makeProjectRoot(t);
|
||||
const agentsDir = join(root, ".gsd", "agents");
|
||||
mkdirSync(agentsDir, { recursive: true });
|
||||
writeFileSync(
|
||||
join(agentsDir, "reviewer.md"),
|
||||
[
|
||||
"---",
|
||||
"name: reviewer",
|
||||
"description: review agent",
|
||||
"tools: bash, read",
|
||||
"---",
|
||||
"Review code",
|
||||
"",
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
const discovery = discoverAgents(root, "project");
|
||||
|
||||
assert.deepEqual(discovery.agents[0]?.tools, ["bash", "read"]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,6 +25,33 @@ export interface AgentDiscoveryResult {
|
|||
projectAgentsDir: string | null;
|
||||
}
|
||||
|
||||
interface AgentFrontmatter extends Record<string, unknown> {
|
||||
name?: string;
|
||||
description?: string;
|
||||
tools?: string | string[];
|
||||
model?: string;
|
||||
}
|
||||
|
||||
function parseAgentTools(value: string | string[] | undefined): string[] | undefined {
|
||||
if (typeof value === "string") {
|
||||
const tools = value
|
||||
.split(",")
|
||||
.map((tool) => tool.trim())
|
||||
.filter(Boolean);
|
||||
return tools.length > 0 ? tools : undefined;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
const tools = value
|
||||
.flatMap((tool) => typeof tool === "string" ? tool.split(",") : [])
|
||||
.map((tool) => tool.trim())
|
||||
.filter(Boolean);
|
||||
return tools.length > 0 ? tools : undefined;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function loadAgentsFromDir(dir: string, source: "user" | "project"): AgentConfig[] {
|
||||
const agents: AgentConfig[] = [];
|
||||
|
||||
|
|
@ -51,16 +78,13 @@ function loadAgentsFromDir(dir: string, source: "user" | "project"): AgentConfig
|
|||
continue;
|
||||
}
|
||||
|
||||
const { frontmatter, body } = parseFrontmatter<Record<string, string>>(content);
|
||||
const { frontmatter, body } = parseFrontmatter<AgentFrontmatter>(content);
|
||||
|
||||
if (!frontmatter.name || !frontmatter.description) {
|
||||
if (typeof frontmatter.name !== "string" || typeof frontmatter.description !== "string") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const tools = frontmatter.tools
|
||||
?.split(",")
|
||||
.map((t: string) => t.trim())
|
||||
.filter(Boolean);
|
||||
const tools = parseAgentTools(frontmatter.tools);
|
||||
|
||||
agents.push({
|
||||
name: frontmatter.name,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue