Browse Source

fix(council): resolve agent model from council config instead of hardcoded default (#238)

* fix(council): resolve agent model from council.master config instead of hardcoded default

* Update src/agents/index.test.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix: address review feedback — extend fix to council-master, fix duplicate test line, use DEFAULT_MODELS constant

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
ReqX 1 week ago
parent
commit
ededf1cce4
2 changed files with 62 additions and 1 deletions
  1. 53 1
      src/agents/index.test.ts
  2. 9 0
      src/agents/index.ts

+ 53 - 1
src/agents/index.test.ts

@@ -1,6 +1,6 @@
 import { describe, expect, test } from 'bun:test';
 import type { PluginConfig } from '../config';
-import { SUBAGENT_NAMES } from '../config';
+import { DEFAULT_MODELS, SUBAGENT_NAMES } from '../config';
 import { createAgents, getAgentConfigs, isSubagent } from './index';
 
 describe('agent alias backward compatibility', () => {
@@ -319,3 +319,55 @@ describe('getAgentConfigs', () => {
     expect(configs.explorer.description).toBeDefined();
   });
 });
+
+describe('council agent model resolution', () => {
+  test('council agent uses config.council.master.model', () => {
+    const config = {
+      council: {
+        master: { model: 'anthropic/claude-sonnet-4-6' },
+        presets: {
+          default: {
+            councillors: {
+              alpha: { model: 'test/alpha-model' },
+            },
+            master: undefined,
+          },
+        },
+      },
+    } as unknown as PluginConfig;
+    const agents = createAgents(config);
+    const council = agents.find((a) => a.name === 'council');
+    expect(council?.config.model).toBe('anthropic/claude-sonnet-4-6');
+  });
+
+  test('council agent falls back to default without council config', () => {
+    const agents = createAgents();
+    const council = agents.find((a) => a.name === 'council');
+    expect(council?.config.model).toBe(DEFAULT_MODELS.council);
+  });
+
+  test('council-master agent uses config.council.master.model', () => {
+    const config = {
+      council: {
+        master: { model: 'anthropic/claude-sonnet-4-6' },
+        presets: {
+          default: {
+            councillors: {
+              alpha: { model: 'test/alpha-model' },
+            },
+            master: undefined,
+          },
+        },
+      },
+    } as unknown as PluginConfig;
+    const agents = createAgents(config);
+    const councilMaster = agents.find((a) => a.name === 'council-master');
+    expect(councilMaster?.config.model).toBe('anthropic/claude-sonnet-4-6');
+  });
+
+  test('council-master agent falls back to default without council config', () => {
+    const agents = createAgents();
+    const councilMaster = agents.find((a) => a.name === 'council-master');
+    expect(councilMaster?.config.model).toBe(DEFAULT_MODELS['council-master']);
+  });
+});

+ 9 - 0
src/agents/index.ts

@@ -137,6 +137,15 @@ export function createAgents(config?: PluginConfig): AgentDefinition[] {
       }
       return librarianModel ?? (DEFAULT_MODELS.librarian as string);
     }
+    // Council and council-master agents' model comes from
+    // config.council.master.model so the TUI validates the user's
+    // actual model, not the hardcoded default
+    if (
+      (name === 'council' || name === 'council-master') &&
+      config?.council?.master?.model
+    ) {
+      return config.council.master.model;
+    }
     // Subagents always have a defined default model; cast is safe here
     return DEFAULT_MODELS[name] as string;
   };