|
|
@@ -2,6 +2,7 @@ import { describe, expect, test } from 'bun:test';
|
|
|
import type { PluginConfig } from '../config';
|
|
|
import {
|
|
|
AgentOverrideConfigSchema,
|
|
|
+ CouncilConfigSchema,
|
|
|
DEFAULT_DISABLED_AGENTS,
|
|
|
DEFAULT_MODELS,
|
|
|
PluginConfigSchema,
|
|
|
@@ -388,6 +389,90 @@ describe('council agent model resolution', () => {
|
|
|
const councillor = agents.find((a) => a.name === 'councillor');
|
|
|
expect(councillor?.config.model).toBe(DEFAULT_MODELS.councillor);
|
|
|
});
|
|
|
+
|
|
|
+ test('council falls back to legacy master.model when no preset override', () => {
|
|
|
+ // Simulates a pre-1.0.0 config with council.master.model but no council
|
|
|
+ // entry in the agent preset — the exact scenario from issue #369.
|
|
|
+ const config: PluginConfig = {
|
|
|
+ agents: {
|
|
|
+ oracle: { model: 'openai/gpt-5.4' },
|
|
|
+ },
|
|
|
+ council: {
|
|
|
+ presets: {
|
|
|
+ default: {
|
|
|
+ alpha: { model: 'openai/gpt-5.4-mini' },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ _legacyMasterModel: 'anthropic/claude-opus-4-6',
|
|
|
+ },
|
|
|
+ };
|
|
|
+ const agents = createAgents(config);
|
|
|
+ const council = agents.find((a) => a.name === 'council');
|
|
|
+ expect(council?.config.model).toBe('anthropic/claude-opus-4-6');
|
|
|
+ });
|
|
|
+
|
|
|
+ test('council preset override takes precedence over legacy master.model', () => {
|
|
|
+ // If user has explicit council in preset, that wins — legacy is ignored.
|
|
|
+ const config: PluginConfig = {
|
|
|
+ agents: {
|
|
|
+ council: { model: 'google/gemini-3-pro' },
|
|
|
+ },
|
|
|
+ council: {
|
|
|
+ presets: {
|
|
|
+ default: {
|
|
|
+ alpha: { model: 'openai/gpt-5.4-mini' },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ _legacyMasterModel: 'anthropic/claude-opus-4-6',
|
|
|
+ },
|
|
|
+ };
|
|
|
+ const agents = createAgents(config);
|
|
|
+ const council = agents.find((a) => a.name === 'council');
|
|
|
+ expect(council?.config.model).toBe('google/gemini-3-pro');
|
|
|
+ });
|
|
|
+
|
|
|
+ test('council uses default when no legacy master and no preset override', () => {
|
|
|
+ // No legacy master, no preset override → standard default
|
|
|
+ const config: PluginConfig = {
|
|
|
+ council: {
|
|
|
+ presets: {
|
|
|
+ default: {
|
|
|
+ alpha: { model: 'openai/gpt-5.4-mini' },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ };
|
|
|
+ const agents = createAgents(config);
|
|
|
+ const council = agents.find((a) => a.name === 'council');
|
|
|
+ expect(council?.config.model).toBe(DEFAULT_MODELS.council);
|
|
|
+ });
|
|
|
+
|
|
|
+ test('end-to-end: raw master.model config flows through schema to council agent', () => {
|
|
|
+ // Integration test: start from raw user config with deprecated master.model,
|
|
|
+ // parse through CouncilConfigSchema, then pass to createAgents.
|
|
|
+ // This validates the full seam between schema transform and agent resolution.
|
|
|
+ const rawCouncilConfig = {
|
|
|
+ master: { model: 'anthropic/claude-opus-4-6' },
|
|
|
+ presets: {
|
|
|
+ default: {
|
|
|
+ alpha: { model: 'openai/gpt-5.4-mini' },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ const parsed = CouncilConfigSchema.safeParse(rawCouncilConfig);
|
|
|
+ expect(parsed.success).toBe(true);
|
|
|
+
|
|
|
+ if (parsed.success) {
|
|
|
+ const config: PluginConfig = {
|
|
|
+ council: parsed.data,
|
|
|
+ };
|
|
|
+ const agents = createAgents(config);
|
|
|
+ const council = agents.find((a) => a.name === 'council');
|
|
|
+ // Legacy master.model should flow through schema → agent
|
|
|
+ expect(council?.config.model).toBe('anthropic/claude-opus-4-6');
|
|
|
+ }
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
describe('options passthrough', () => {
|