From 6ae628de65d3ec941dcbe46e4fbe34a75ac00803 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Fri, 26 Jun 2026 21:33:27 -0600 Subject: [PATCH] fix(supervise): give the router supervisor a real default prompt (was empty) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The supervisor brain defaulted to an EMPTY systemPrompt, so a supervise()/delegate() call with no authored prompt gave the LLM brain the coordination verbs but NO policy for when to use them — it over-spawned (15 workers for a 2-module task, 66x a single agent's tokens) or stalled (0 work). Add defaultSupervisorPrompt encoding the discipline the topology tournament showed wins: do small work yourself, delegate sparingly (conserved budget), give each worker a bounded brief, manage the context lifecycle, settle only on real delivery. A profile still overrides it; an explicit '' is preserved (?? fires on undefined only). Gates green, 50 supervise tests pass. --- src/runtime/supervise/supervisor-agent.ts | 24 ++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/runtime/supervise/supervisor-agent.ts b/src/runtime/supervise/supervisor-agent.ts index a67241d1..59743db0 100644 --- a/src/runtime/supervise/supervisor-agent.ts +++ b/src/runtime/supervise/supervisor-agent.ts @@ -21,6 +21,28 @@ import { driverAgent, finalizeBestDelivered } from './coordination-driver' import { serveCoordinationMcp } from './coordination-mcp' import type { Agent, Budget, ResultBlobStore, Scope } from './types' +/** The standing strategy a router-brained supervisor runs with when its profile names no + * `systemPrompt`. The brain's competence IS this prompt: without it the brain has the coordination + * verbs but no policy for WHEN to use them, and either over-spawns or stalls. A profile may override + * it for a specific topology. */ +export const defaultSupervisorPrompt = [ + 'You are a supervisor accountable for DELIVERING the task — not for looking busy. You succeed only', + 'when the deliverable is actually produced and verified, never on a worker reporting "done".', + '', + 'Spawning a worker spends the shared, conserved budget — so delegate with intent, not by reflex:', + '- Do small, sequential work YOURSELF when you have work tools; spawn a worker when a sub-task is', + ' large, independent (parallelizable), or needs a clean context the current one has filled.', + '- Prefer the FEWEST workers that deliver. Over-spawning burns the budget and rarely helps.', + '', + 'Manage the context lifecycle on long work: give each spawned worker a BOUNDED brief — the specific', + 'sub-task plus only the interfaces/state it needs — never your whole history. When one chapter is', + 'done, distill what the next chapter needs and spawn fresh, rather than steering one worker until', + 'its context fills and degrades.', + '', + 'Wait on real signals (await a settle, answer a blocking question), integrate the result, and stop', + 'as soon as the deliverable is met.', +].join('\n') + /** The supervisor's profile — the subset of an `AgentProfile` that selects + shapes its brain. * `harness` is the backend-as-data discriminant; `systemPrompt` is the standing instruction. */ export interface SupervisorProfile { @@ -80,7 +102,7 @@ export function supervisorAgent( deps: SupervisorAgentDeps, ): Agent { const name = profile.name ?? 'supervisor' - const systemPrompt = profile.systemPrompt ?? '' + const systemPrompt = profile.systemPrompt ?? defaultSupervisorPrompt const harness = profile.harness ?? null if (harness === null) {