diff --git a/src/agents/builtin-agents.ts b/src/agents/builtin-agents.ts index 350d69e54..0175bcaa9 100644 --- a/src/agents/builtin-agents.ts +++ b/src/agents/builtin-agents.ts @@ -26,7 +26,6 @@ import { collectPendingBuiltinAgents } from "./builtin-agents/general-agents" import { maybeCreateSisyphusConfig } from "./builtin-agents/sisyphus-agent" import { maybeCreateHephaestusConfig } from "./builtin-agents/hephaestus-agent" import { maybeCreateAtlasConfig } from "./builtin-agents/atlas-agent" -import { buildCustomAgentMetadata, parseRegisteredAgentSummaries } from "./custom-agent-summaries" type AgentSource = AgentFactory | AgentConfig @@ -120,23 +119,6 @@ export async function createBuiltinAgents( disableOmoEnv, }) - const registeredAgents = parseRegisteredAgentSummaries(customAgentSummaries) - const builtinAgentNames = new Set(Object.keys(agentSources).map((name) => name.toLowerCase())) - const disabledAgentNames = new Set(disabledAgents.map((name) => name.toLowerCase())) - - for (const agent of registeredAgents) { - const lowerName = agent.name.toLowerCase() - if (builtinAgentNames.has(lowerName)) continue - if (disabledAgentNames.has(lowerName)) continue - if (availableAgents.some((availableAgent) => availableAgent.name.toLowerCase() === lowerName)) continue - - availableAgents.push({ - name: agent.name, - description: agent.description, - metadata: buildCustomAgentMetadata(agent.name, agent.description), - }) - } - const sisyphusConfig = maybeCreateSisyphusConfig({ disabledAgents, agentOverrides, diff --git a/src/agents/custom-agent-orchestrator-visibility.test.ts b/src/agents/custom-agent-orchestrator-visibility.test.ts new file mode 100644 index 000000000..c0b709e4b --- /dev/null +++ b/src/agents/custom-agent-orchestrator-visibility.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, spyOn, test } from "bun:test" +import { createBuiltinAgents } from "./builtin-agents" +import * as shared from "../shared" + +const TEST_DEFAULT_MODEL = "anthropic/claude-opus-4-6" + +describe("createBuiltinAgents custom agent visibility", () => { + test("#given runtime custom agents #when orchestrator prompts are built #then custom agents are not advertised for automatic delegation", async () => { + //#given + const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue( + new Set(["anthropic/claude-opus-4-6", "openai/gpt-5.4"]) + ) + + try { + //#when + const agents = await createBuiltinAgents( + [], + {}, + undefined, + TEST_DEFAULT_MODEL, + undefined, + undefined, + [], + [ + { + name: "backend-engineer", + description: "Custom backend specialist", + }, + ] + ) + + //#then + expect(agents.sisyphus.prompt).not.toContain("backend-engineer") + expect(agents.hephaestus.prompt).not.toContain("backend-engineer") + expect(agents.atlas.prompt).not.toContain("backend-engineer") + } finally { + fetchSpy.mockRestore() + } + }) +}) diff --git a/src/agents/utils.test.ts b/src/agents/utils.test.ts index 7b606e5e4..a37a8c710 100644 --- a/src/agents/utils.test.ts +++ b/src/agents/utils.test.ts @@ -278,7 +278,7 @@ describe("createBuiltinAgents with model overrides", () => { fetchSpy.mockRestore() }) - test("includes custom agents in orchestrator prompts when provided via config", async () => { + test("does not advertise custom agents in orchestrator prompts when provided via config", async () => { // #given const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue( new Set([ @@ -313,9 +313,9 @@ describe("createBuiltinAgents with model overrides", () => { ) // #then - expect(agents.sisyphus.prompt).toContain("researcher") - expect(agents.hephaestus.prompt).toContain("researcher") - expect(agents.atlas.prompt).toContain("researcher") + expect(agents.sisyphus.prompt).not.toContain("researcher") + expect(agents.hephaestus.prompt).not.toContain("researcher") + expect(agents.atlas.prompt).not.toContain("researcher") } finally { fetchSpy.mockRestore() } @@ -429,7 +429,7 @@ describe("createBuiltinAgents with model overrides", () => { } }) - test("deduplicates custom agents case-insensitively", async () => { + test("does not advertise duplicate custom agents case-insensitively", async () => { // #given const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue( new Set(["anthropic/claude-opus-4-6", "openai/gpt-5.4"]) @@ -455,13 +455,13 @@ describe("createBuiltinAgents with model overrides", () => { // #then const matches = (agents.sisyphus?.prompt ?? "").match(/Custom agent: researcher/gi) ?? [] - expect(matches.length).toBe(1) + expect(matches.length).toBe(0) } finally { fetchSpy.mockRestore() } }) - test("sanitizes custom agent strings for markdown tables", async () => { + test("does not surface custom agent strings in orchestrator prompts", async () => { // #given const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue( new Set(["anthropic/claude-opus-4-6", "openai/gpt-5.4"]) @@ -488,7 +488,7 @@ describe("createBuiltinAgents with model overrides", () => { ) // #then - expect(agents.sisyphus.prompt).toContain("Line1 Alpha \\| Beta") + expect(agents.sisyphus.prompt).not.toContain("Line1 Alpha \\| Beta") } finally { fetchSpy.mockRestore() }