Browse Source

Fix subagents

Alvin Unreal 2 months ago
parent
commit
1a63dbf586
2 changed files with 34 additions and 17 deletions
  1. 28 15
      src/agents/index.ts
  2. 6 2
      src/tools/background.ts

+ 28 - 15
src/agents/index.ts

@@ -22,27 +22,40 @@ function applyOverrides(agent: AgentDefinition, override: AgentOverrideConfig):
   }
   }
 }
 }
 
 
-const SUBAGENT_FACTORIES: Omit<Record<AgentName, AgentFactory>, "orchestrator"> = {
-  oracle: createOracleAgent,
-  librarian: createLibrarianAgent,
-  explore: createExploreAgent,
-  "frontend-ui-ux-engineer": createFrontendAgent,
-  "document-writer": createDocumentWriterAgent,
-  "multimodal-looker": createMultimodalAgent,
-  "code-simplicity-reviewer": createSimplicityReviewerAgent,
-};
+type SubagentName = Exclude<AgentName, "orchestrator">;
+type SubagentInfo = { factory: AgentFactory; shortDesc: string };
+
+/** Short descriptions for each subagent (used in tool descriptions) */
+export const SUBAGENT_INFO = {
+  explore: { factory: createExploreAgent, shortDesc: "codebase grep" },
+  librarian: { factory: createLibrarianAgent, shortDesc: "docs/GitHub" },
+  oracle: { factory: createOracleAgent, shortDesc: "strategy" },
+  "frontend-ui-ux-engineer": { factory: createFrontendAgent, shortDesc: "UI/UX" },
+  "document-writer": { factory: createDocumentWriterAgent, shortDesc: "docs" },
+  "multimodal-looker": { factory: createMultimodalAgent, shortDesc: "image/visual analysis" },
+  "code-simplicity-reviewer": { factory: createSimplicityReviewerAgent, shortDesc: "code review" },
+} as const satisfies Record<SubagentName, SubagentInfo>;
+
+/** Generate agent list string for tool descriptions */
+export function getAgentListDescription(): string {
+  return (Object.entries(SUBAGENT_INFO) as [SubagentName, SubagentInfo][])
+    .map(([name, { shortDesc }]) => `${name} (${shortDesc})`)
+    .join(", ");
+}
+
+/** Get list of agent names */
+export function getAgentNames(): SubagentName[] {
+  return Object.keys(SUBAGENT_INFO) as SubagentName[];
+}
 
 
 export function createAgents(config?: PluginConfig): AgentDefinition[] {
 export function createAgents(config?: PluginConfig): AgentDefinition[] {
   const disabledAgents = new Set(config?.disabled_agents ?? []);
   const disabledAgents = new Set(config?.disabled_agents ?? []);
   const agentOverrides = config?.agents ?? {};
   const agentOverrides = config?.agents ?? {};
 
 
   // 1. Gather all sub-agent proto-definitions
   // 1. Gather all sub-agent proto-definitions
-  const protoSubAgents: AgentDefinition[] = [
-    ...Object.entries(SUBAGENT_FACTORIES).map(([name, factory]) => {
-      const model = DEFAULT_MODELS[name as AgentName];
-      return factory(model);
-    }),
-  ];
+  const protoSubAgents = (Object.entries(SUBAGENT_INFO) as [SubagentName, SubagentInfo][]).map(
+    ([name, { factory }]) => factory(DEFAULT_MODELS[name])
+  );
 
 
   // 2. Apply common filtering and overrides
   // 2. Apply common filtering and overrides
   const allSubAgents = protoSubAgents
   const allSubAgents = protoSubAgents

+ 6 - 2
src/tools/background.ts

@@ -1,5 +1,6 @@
 import { tool, type PluginInput, type ToolDefinition } from "@opencode-ai/plugin";
 import { tool, type PluginInput, type ToolDefinition } from "@opencode-ai/plugin";
 import type { BackgroundTaskManager } from "../features";
 import type { BackgroundTaskManager } from "../features";
+import { getAgentListDescription, getAgentNames } from "../agents";
 import {
 import {
   POLL_INTERVAL_MS,
   POLL_INTERVAL_MS,
   MAX_POLL_TIME_MS,
   MAX_POLL_TIME_MS,
@@ -20,17 +21,20 @@ export function createBackgroundTools(
   ctx: PluginInput,
   ctx: PluginInput,
   manager: BackgroundTaskManager
   manager: BackgroundTaskManager
 ): Record<string, ToolDefinition> {
 ): Record<string, ToolDefinition> {
+  const agentList = getAgentListDescription();
+  const agentNames = getAgentNames().join(", ");
+
   const background_task = tool({
   const background_task = tool({
     description: `Run agent task. Use sync=true to wait for result, sync=false (default) to run in background.
     description: `Run agent task. Use sync=true to wait for result, sync=false (default) to run in background.
 
 
-Agents: explore (codebase grep), librarian (docs/GitHub), oracle (strategy), frontend (UI/UX), document-writer (docs).
+Agents: ${agentList}.
 
 
 Async mode returns task_id immediately - use \`background_output\` to get results.
 Async mode returns task_id immediately - use \`background_output\` to get results.
 Sync mode blocks until completion and returns the result directly.`,
 Sync mode blocks until completion and returns the result directly.`,
     args: {
     args: {
       description: z.string().describe("Short description of the task (5-10 words)"),
       description: z.string().describe("Short description of the task (5-10 words)"),
       prompt: z.string().describe("The task prompt for the agent"),
       prompt: z.string().describe("The task prompt for the agent"),
-      agent: z.string().describe("Agent to use: explore, librarian, oracle, frontend, document-writer"),
+      agent: z.string().describe(`Agent to use: ${agentNames}`),
       sync: z.boolean().optional().describe("Wait for completion (default: false = async)"),
       sync: z.boolean().optional().describe("Wait for completion (default: false = async)"),
       session_id: z.string().optional().describe("Continue existing session (sync mode only)"),
       session_id: z.string().optional().describe("Continue existing session (sync mode only)"),
     },
     },