Skip to content

Commit f28f3f0

Browse files
gewenyu99claude
andauthored
fix(switchboard): disable the pi-harness flag on the headless (cloud) path (#832)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent e21add5 commit f28f3f0

3 files changed

Lines changed: 60 additions & 4 deletions

File tree

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

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect } from 'vitest';
1+
import { describe, it, expect, vi } from 'vitest';
22
import { PROGRAM_REGISTRY } from '@lib/programs/program-registry';
33
import {
44
DEFAULT_AGENT_MODEL,
@@ -23,6 +23,17 @@ import {
2323
} from '@lib/agent/runner/switchboard';
2424
import { modelCapabilities } from '@lib/agent/runner/switchboard/models';
2525

26+
// RUN_SURFACE is read live in flagRunnerOverride; a getter lets a test flip it.
27+
const envState = vi.hoisted(() => ({
28+
runSurface: 'local' as 'cloud' | 'local',
29+
}));
30+
vi.mock('@env', async (importOriginal) => ({
31+
...(await importOriginal<typeof import('@env')>()),
32+
get RUN_SURFACE() {
33+
return envState.runSurface;
34+
},
35+
}));
36+
2637
const PROGRAM_IDS = PROGRAM_REGISTRY.map((c) => c.id);
2738

2839
describe('switchboard PROGRAM_BINDINGS', () => {
@@ -163,6 +174,30 @@ describe('switchboard resolveHarness — pi flag is gated to posthog-integration
163174
expect(pick).toEqual({ harness: Harness.pi, model: GPT5_4_MODEL });
164175
});
165176

177+
it('disables the pi flag on the cloud run surface, even for posthog-integration', () => {
178+
envState.runSurface = 'cloud';
179+
try {
180+
const pick = resolveHarness({
181+
program: 'posthog-integration',
182+
flags: { [WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true' },
183+
});
184+
expect(pick).toEqual({
185+
harness: Harness.anthropic,
186+
model: DEFAULT_AGENT_MODEL,
187+
});
188+
} finally {
189+
envState.runSurface = 'local';
190+
}
191+
});
192+
193+
it('keeps the pi flag on the local run surface for posthog-integration', () => {
194+
const pick = resolveHarness({
195+
program: 'posthog-integration',
196+
flags: { [WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true' },
197+
});
198+
expect(pick.harness).toBe(Harness.pi);
199+
});
200+
166201
it('ignores the pi flag for self-driving — stays on the anthropic default', () => {
167202
const pick = resolveHarness({
168203
program: 'self-driving',
@@ -319,6 +354,20 @@ describe('switchboard wizard-pi-effort flag', () => {
319354
}).thinkingLevel,
320355
).toBeUndefined();
321356
});
357+
358+
it('is inert on the cloud surface even with the pi flag on', () => {
359+
envState.runSurface = 'cloud';
360+
try {
361+
expect(
362+
modelCapabilities(GPT5_4_MODEL, {
363+
[WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true',
364+
[WIZARD_PI_EFFORT_FLAG_KEY]: 'high',
365+
}).thinkingLevel,
366+
).toBe('low');
367+
} finally {
368+
envState.runSurface = 'local';
369+
}
370+
});
322371
});
323372

324373
describe('switchboard resolveSequence — orchestrator stays flag-gated', () => {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Harness axis: registry, middleware, resolver. Mirrors `sequence.ts`.
33
*/
44

5-
import { IS_PRODUCTION_BUILD } from '@env';
5+
import { IS_PRODUCTION_BUILD, RUN_SURFACE } from '@env';
66
import {
77
DEFAULT_AGENT_MODEL,
88
GPT5_4_MODEL,
@@ -60,6 +60,8 @@ const PI_FLAG_PROGRAMS = new Set<ProgramId>(['posthog-integration']);
6060
const flagRunnerOverride: Middleware<HarnessPick> = (ctx, next) => {
6161
const pick = next();
6262
if (ctx.flags[WIZARD_USE_PI_HARNESS_FLAG_KEY] !== 'true') return pick;
63+
// The pi experiment is disabled on the cloud (headless) run surface.
64+
if (RUN_SURFACE === 'cloud') return pick;
6365
if (!PI_FLAG_PROGRAMS.has(ctx.program)) return pick;
6466
if (ctx.trace) Object.assign(ctx.trace, { harness: 'flag', model: 'flag' });
6567
const variant = ctx.flags[WIZARD_PI_MODEL_FLAG_KEY] ?? '';

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
WIZARD_PI_EFFORT_FLAG_KEY,
2121
WIZARD_USE_PI_HARNESS_FLAG_KEY,
2222
} from '@lib/constants';
23+
import { RUN_SURFACE } from '@env';
2324

2425
/** Reasoning effort. pi maps it to `reasoning_effort` for openai-completions. */
2526
export type ThinkingLevel =
@@ -78,8 +79,12 @@ export function modelCapabilities(
7879
flags: Record<string, string> = {},
7980
): ModelCapabilities {
8081
const caps = MODEL_CAPABILITIES[modelId] ?? defaultCaps(modelId);
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;
82+
// The wizard-pi-effort override applies only to a pi run — inert on the cloud surface or without the pi flag.
83+
if (
84+
RUN_SURFACE === 'cloud' ||
85+
flags[WIZARD_USE_PI_HARNESS_FLAG_KEY] !== 'true'
86+
)
87+
return caps;
8388
const effort = flags[WIZARD_PI_EFFORT_FLAG_KEY] as ThinkingLevel;
8489
if (caps.reasoning && EFFORT_FLAG_VARIANTS.includes(effort)) {
8590
return { ...caps, thinkingLevel: effort };

0 commit comments

Comments
 (0)