Skip to content

Commit eb5c61e

Browse files
gewenyu99claude
andauthored
fix(switchboard): gate the pi harness flag to posthog-integration only (#824)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 2c33885 commit eb5c61e

3 files changed

Lines changed: 81 additions & 7 deletions

File tree

src/lib/agent/runner/__tests__/switchboard.test.ts

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,52 @@ describe('switchboard resolveHarness — CLI precedence', () => {
154154
});
155155
});
156156

157+
describe('switchboard resolveHarness — pi flag is gated to posthog-integration', () => {
158+
it('honours the pi flag for posthog-integration', () => {
159+
const pick = resolveHarness({
160+
program: 'posthog-integration',
161+
flags: { [WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true' },
162+
});
163+
expect(pick).toEqual({ harness: Harness.pi, model: GPT5_4_MODEL });
164+
});
165+
166+
it('ignores the pi flag for self-driving — stays on the anthropic default', () => {
167+
const pick = resolveHarness({
168+
program: 'self-driving',
169+
flags: { [WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true' },
170+
});
171+
expect(pick).toEqual({
172+
harness: Harness.anthropic,
173+
model: DEFAULT_AGENT_MODEL,
174+
});
175+
});
176+
177+
it('ignores the pi flag for every non-posthog-integration program', () => {
178+
for (const program of PROGRAM_IDS) {
179+
if (program === 'posthog-integration') continue;
180+
expect(
181+
resolveHarness({
182+
program,
183+
flags: { [WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true' },
184+
}).harness,
185+
).toBe(Harness.anthropic);
186+
}
187+
});
188+
189+
it('leaves the sequence unclamped for a gated program (pi never selected)', () => {
190+
const ctx: SwitchboardCtx = {
191+
program: 'self-driving',
192+
flags: { [WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true' },
193+
};
194+
resolveBinding(ctx);
195+
expect(ctx.trace).toEqual({
196+
harness: 'binding',
197+
model: 'binding',
198+
sequence: 'binding',
199+
});
200+
});
201+
});
202+
157203
describe('switchboard decision trace', () => {
158204
it('stamps binding sources when nothing overrides', () => {
159205
const ctx: SwitchboardCtx = { program: 'posthog-integration', flags: {} };
@@ -237,17 +283,38 @@ describe('switchboard modelCapabilities', () => {
237283
});
238284

239285
describe('switchboard wizard-pi-effort flag', () => {
286+
const PI_ON = { [WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true' };
287+
240288
it('overrides effort for reasoning models; ignores invalid; skips non-reasoning', () => {
241289
expect(
242-
modelCapabilities(GPT5_4_MODEL, { [WIZARD_PI_EFFORT_FLAG_KEY]: 'high' })
243-
.thinkingLevel,
290+
modelCapabilities(GPT5_4_MODEL, {
291+
...PI_ON,
292+
[WIZARD_PI_EFFORT_FLAG_KEY]: 'high',
293+
}).thinkingLevel,
244294
).toBe('high');
245295
expect(
246-
modelCapabilities(GPT5_4_MODEL, { [WIZARD_PI_EFFORT_FLAG_KEY]: 'banana' })
247-
.thinkingLevel,
296+
modelCapabilities(GPT5_4_MODEL, {
297+
...PI_ON,
298+
[WIZARD_PI_EFFORT_FLAG_KEY]: 'banana',
299+
}).thinkingLevel,
248300
).toBe('low');
249301
expect(
250302
modelCapabilities('openai/gpt-4o', {
303+
...PI_ON,
304+
[WIZARD_PI_EFFORT_FLAG_KEY]: 'high',
305+
}).thinkingLevel,
306+
).toBeUndefined();
307+
});
308+
309+
it('is inert unless the pi-harness flag is on — effort cannot ride a non-pi pick', () => {
310+
// Effort set but the pi flag off: the override is ignored, so the model's
311+
// own table effort stands (gpt-5.4 → low) and anthropic keeps no effort.
312+
expect(
313+
modelCapabilities(GPT5_4_MODEL, { [WIZARD_PI_EFFORT_FLAG_KEY]: 'high' })
314+
.thinkingLevel,
315+
).toBe('low');
316+
expect(
317+
modelCapabilities(DEFAULT_AGENT_MODEL, {
251318
[WIZARD_PI_EFFORT_FLAG_KEY]: 'high',
252319
}).thinkingLevel,
253320
).toBeUndefined();

src/lib/agent/runner/switchboard/harness.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
WIZARD_USE_PI_HARNESS_FLAG_KEY,
1515
} from '@lib/constants';
1616
import { logToFile } from '@utils/debug';
17+
import type { ProgramId } from '@lib/programs/program-registry';
1718
import { anthropicBackend } from '../harness/anthropic';
1819
import { piBackend } from '../harness/pi';
1920
import type { AgentHarness } from '../harness/types';
@@ -48,13 +49,18 @@ const PI_MODEL_FLAG_VARIANTS: Record<string, string> = {
4849
'sonnet-5': SONNET_5_MODEL,
4950
};
5051

52+
/** Programs the wizard-use-pi-harness flag may switch to pi; off this set the flag is a no-op and the binding default stands. */
53+
const PI_FLAG_PROGRAMS = new Set<ProgramId>(['posthog-integration']);
54+
5155
/**
5256
* `wizard-use-pi-harness` on → pi, paired with the `wizard-pi-model` variant
53-
* (unknown/missing variant → gpt-5.4). Otherwise binding default.
57+
* (unknown/missing variant → gpt-5.4). Off `PI_FLAG_PROGRAMS`, the flag is
58+
* ignored and the binding default stands.
5459
*/
5560
const flagRunnerOverride: Middleware<HarnessPick> = (ctx, next) => {
5661
const pick = next();
5762
if (ctx.flags[WIZARD_USE_PI_HARNESS_FLAG_KEY] !== 'true') return pick;
63+
if (!PI_FLAG_PROGRAMS.has(ctx.program)) return pick;
5864
if (ctx.trace) Object.assign(ctx.trace, { harness: 'flag', model: 'flag' });
5965
const variant = ctx.flags[WIZARD_PI_MODEL_FLAG_KEY] ?? '';
6066
return {

src/lib/agent/runner/switchboard/models.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
GPT5_4_MODEL,
1919
GPT5_MINI_MODEL,
2020
WIZARD_PI_EFFORT_FLAG_KEY,
21+
WIZARD_USE_PI_HARNESS_FLAG_KEY,
2122
} from '@lib/constants';
2223

2324
/** Reasoning effort. pi maps it to `reasoning_effort` for openai-completions. */
@@ -77,8 +78,8 @@ export function modelCapabilities(
7778
flags: Record<string, string> = {},
7879
): ModelCapabilities {
7980
const caps = MODEL_CAPABILITIES[modelId] ?? defaultCaps(modelId);
80-
// `wizard-pi-effort` overrides the table for reasoning models only; an
81-
// unknown variant is ignored.
81+
// The wizard-pi-effort override applies only when the pi-harness flag selected the run; otherwise the model's own table effort stands.
82+
if (flags[WIZARD_USE_PI_HARNESS_FLAG_KEY] !== 'true') return caps;
8283
const effort = flags[WIZARD_PI_EFFORT_FLAG_KEY] as ThinkingLevel;
8384
if (caps.reasoning && EFFORT_FLAG_VARIANTS.includes(effort)) {
8485
return { ...caps, thinkingLevel: effort };

0 commit comments

Comments
 (0)