feat(plan): support automatic model switching for Plan Mode (#20240)

This commit is contained in:
Jerop Kipruto
2026-02-24 19:15:14 -05:00
committed by GitHub
parent 1f9da6723f
commit bf278ef2b0
19 changed files with 422 additions and 31 deletions

View File

@@ -14,10 +14,12 @@ import { DefaultStrategy } from './strategies/defaultStrategy.js';
import { CompositeStrategy } from './strategies/compositeStrategy.js';
import { FallbackStrategy } from './strategies/fallbackStrategy.js';
import { OverrideStrategy } from './strategies/overrideStrategy.js';
import { ApprovalModeStrategy } from './strategies/approvalModeStrategy.js';
import { ClassifierStrategy } from './strategies/classifierStrategy.js';
import { NumericalClassifierStrategy } from './strategies/numericalClassifierStrategy.js';
import { logModelRouting } from '../telemetry/loggers.js';
import { ModelRoutingEvent } from '../telemetry/types.js';
import { ApprovalMode } from '../policy/types.js';
vi.mock('../config/config.js');
vi.mock('../core/baseLlmClient.js');
@@ -25,6 +27,7 @@ vi.mock('./strategies/defaultStrategy.js');
vi.mock('./strategies/compositeStrategy.js');
vi.mock('./strategies/fallbackStrategy.js');
vi.mock('./strategies/overrideStrategy.js');
vi.mock('./strategies/approvalModeStrategy.js');
vi.mock('./strategies/classifierStrategy.js');
vi.mock('./strategies/numericalClassifierStrategy.js');
vi.mock('../telemetry/loggers.js');
@@ -45,11 +48,15 @@ describe('ModelRouterService', () => {
vi.spyOn(mockConfig, 'getBaseLlmClient').mockReturnValue(mockBaseLlmClient);
vi.spyOn(mockConfig, 'getNumericalRoutingEnabled').mockResolvedValue(false);
vi.spyOn(mockConfig, 'getClassifierThreshold').mockResolvedValue(undefined);
vi.spyOn(mockConfig, 'getApprovalMode').mockReturnValue(
ApprovalMode.DEFAULT,
);
mockCompositeStrategy = new CompositeStrategy(
[
new FallbackStrategy(),
new OverrideStrategy(),
new ApprovalModeStrategy(),
new ClassifierStrategy(),
new NumericalClassifierStrategy(),
new DefaultStrategy(),
@@ -79,12 +86,13 @@ describe('ModelRouterService', () => {
const compositeStrategyArgs = vi.mocked(CompositeStrategy).mock.calls[0];
const childStrategies = compositeStrategyArgs[0];
expect(childStrategies.length).toBe(5);
expect(childStrategies.length).toBe(6);
expect(childStrategies[0]).toBeInstanceOf(FallbackStrategy);
expect(childStrategies[1]).toBeInstanceOf(OverrideStrategy);
expect(childStrategies[2]).toBeInstanceOf(ClassifierStrategy);
expect(childStrategies[3]).toBeInstanceOf(NumericalClassifierStrategy);
expect(childStrategies[4]).toBeInstanceOf(DefaultStrategy);
expect(childStrategies[2]).toBeInstanceOf(ApprovalModeStrategy);
expect(childStrategies[3]).toBeInstanceOf(ClassifierStrategy);
expect(childStrategies[4]).toBeInstanceOf(NumericalClassifierStrategy);
expect(childStrategies[5]).toBeInstanceOf(DefaultStrategy);
expect(compositeStrategyArgs[1]).toBe('agent-router');
});
@@ -127,6 +135,7 @@ describe('ModelRouterService', () => {
'Strategy reasoning',
false,
undefined,
ApprovalMode.DEFAULT,
false,
undefined,
);
@@ -153,6 +162,7 @@ describe('ModelRouterService', () => {
'An exception occurred during routing.',
true,
'Strategy failed',
ApprovalMode.DEFAULT,
false,
undefined,
);