Browse Source

fix(council): thread variant through to councillor agents

Single-model councillors configured with a variant lost it because
buildCouncillorAgents passed only the bare model ID to
createCouncillorAgent. Add an optional variant param and thread
cfg.variant through. Multi-model councillors already keep per-entry
variants via _modelArray.
Michael Henke 3 weeks ago
parent
commit
f2795b3d8a

+ 24 - 0
src/agents/council-agents.test.ts

@@ -61,6 +61,30 @@ describe('buildCouncillorAgents', () => {
     expect(agent._modelArray).toBeUndefined();
   });
 
+  test('single-model councillor with variant propagates variant to agent config', () => {
+    const config = makeConfig({
+      presets: {
+        default: {
+          beta: {
+            model: 'google/gemini-3-pro',
+            variant: 'high',
+            prompt: undefined,
+            models: [{ id: 'google/gemini-3-pro' }],
+          },
+        },
+      },
+    });
+
+    const agents = buildCouncillorAgents(config, new Set());
+    expect(agents).toHaveLength(1);
+
+    const [agent] = agents;
+    expect(agent.name).toBe('councillor-beta');
+    expect(agent.config.model).toBe('google/gemini-3-pro');
+    expect(agent.config.variant).toBe('high');
+    expect(agent._modelArray).toBeUndefined();
+  });
+
   test('multi-model councillor has _modelArray and config.model undefined', () => {
     const config = makeConfig({
       presets: {

+ 6 - 1
src/agents/council-agents.ts

@@ -28,7 +28,12 @@ export function buildCouncillorAgents(
 
     const agentName = `${COUNCILLOR_AGENT_PREFIX}${name}`;
     if (disabled.has(agentName)) continue;
-    const base = createCouncillorAgent(cfg.model, undefined, cfg.prompt);
+    const base = createCouncillorAgent(
+      cfg.model,
+      undefined,
+      cfg.prompt,
+      cfg.variant,
+    );
 
     // If a fallback chain is configured, attach _modelArray for runtime
     // resolution and clear the primary model so the single-model field

+ 15 - 0
src/agents/councillor.test.ts

@@ -62,6 +62,21 @@ describe('createCouncillorAgent', () => {
   });
 });
 
+test('sets variant when provided', () => {
+  const agent = createCouncillorAgent(
+    'test-model',
+    undefined,
+    undefined,
+    'high',
+  );
+  expect(agent.config.variant).toBe('high');
+});
+
+test('variant is undefined when not provided', () => {
+  const agent = createCouncillorAgent('test-model');
+  expect(agent.config.variant).toBeUndefined();
+});
+
 describe('councillor permissions', () => {
   test('denies all by default with wildcard', () => {
     const agent = createCouncillorAgent('test-model');

+ 2 - 0
src/agents/councillor.ts

@@ -55,6 +55,7 @@ export function createCouncillorAgent(
   model: string,
   customPrompt?: string,
   customAppendPrompt?: string,
+  variant?: string,
 ): AgentDefinition {
   const prompt = resolvePrompt(
     COUNCILLOR_PROMPT,
@@ -68,6 +69,7 @@ export function createCouncillorAgent(
       'Read-only council advisor. Examines codebase and provides independent analysis. Spawned internally by the council system.',
     config: {
       model,
+      variant,
       temperature: 0.2,
       prompt,
       // Strict read-only allowlist: deny all, then allow inspection tools only.