Skip to content

Commit 8e23117

Browse files
gewenyu99claude
andcommitted
fix(switchboard): disable the pi-harness flag on the headless (cloud) path
The experimental pi harness should not run on the headless-DONOTUSE-EXPERIMENTAL cloud path. Thread a `headless` signal from the session (set only for that flag, not --ci) into the switchboard, and decline the wizard-use-pi-harness flag when it is set — the run stays on the anthropic binding default. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 9ad7756 commit 8e23117

7 files changed

Lines changed: 32 additions & 0 deletions

File tree

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,27 @@ describe('switchboard resolveHarness — pi flag is gated to posthog-integration
163163
expect(pick).toEqual({ harness: Harness.pi, model: GPT5_4_MODEL });
164164
});
165165

166+
it('disables the pi flag on the headless (cloud) path, even for posthog-integration', () => {
167+
const pick = resolveHarness({
168+
program: 'posthog-integration',
169+
flags: { [WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true' },
170+
headless: true,
171+
});
172+
expect(pick).toEqual({
173+
harness: Harness.anthropic,
174+
model: DEFAULT_AGENT_MODEL,
175+
});
176+
});
177+
178+
it('keeps the pi flag for a non-headless (local/--ci) posthog-integration run', () => {
179+
const pick = resolveHarness({
180+
program: 'posthog-integration',
181+
flags: { [WIZARD_USE_PI_HARNESS_FLAG_KEY]: 'true' },
182+
headless: false,
183+
});
184+
expect(pick.harness).toBe(Harness.pi);
185+
});
186+
166187
it('ignores the pi flag for self-driving — stays on the anthropic default', () => {
167188
const pick = resolveHarness({
168189
program: 'self-driving',

src/lib/agent/runner/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ function resolveProgramRunner(
130130
cliHarness: session.harness,
131131
cliSequence: session.sequence,
132132
cliModel: session.model,
133+
headless: session.headless,
133134
};
134135
const binding = resolveBinding(ctx);
135136
tagBinding(boot, binding);

src/lib/agent/runner/sequence/linear.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export async function runLinearProgram(
130130
flags: wizardFlags,
131131
cliHarness: session.harness,
132132
cliModel: session.model,
133+
headless: session.headless,
133134
});
134135
const agentResult = await getHarness(pick.harness).run({
135136
session,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 headless-DONOTUSE-EXPERIMENTAL (cloud) path.
64+
if (ctx.headless) 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/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ export interface SwitchboardCtx {
3131
cliSequence?: Sequence;
3232
/** CLI override (`--model`, gateway id). Wins over the binding's model. */
3333
cliModel?: string;
34+
/** The headless-DONOTUSE-EXPERIMENTAL (cloud) run path; disables the pi-harness flag. */
35+
headless?: boolean;
3436
/** Filled during resolution; read by the caller for telemetry. */
3537
trace?: SwitchboardTrace;
3638
}

src/lib/runners/run-non-interactive.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ export function runNonInteractive(
107107
debug: options.debug as boolean | undefined,
108108
installDir,
109109
ci: true,
110+
headless: mode === 'headless',
110111
signup: options.signup as boolean | undefined,
111112
localMcp: options.localMcp as boolean | undefined,
112113
apiKey,

src/lib/wizard-session.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ export interface WizardSession {
171171
debug: boolean;
172172
installDir: string;
173173
ci: boolean;
174+
/** The experimental headless-DONOTUSE-EXPERIMENTAL (cloud) run path; false for --ci. */
175+
headless: boolean;
174176
signup: boolean;
175177
localMcp: boolean;
176178
mcpFeatures?: string[];
@@ -342,6 +344,7 @@ export function buildSession(args: {
342344
debug?: boolean;
343345
installDir?: string;
344346
ci?: boolean;
347+
headless?: boolean;
345348
signup?: boolean;
346349
localMcp?: boolean;
347350
mcpFeatures?: string[];
@@ -363,6 +366,7 @@ export function buildSession(args: {
363366
debug: args.debug ?? false,
364367
installDir: args.installDir ?? process.cwd(),
365368
ci: args.ci ?? false,
369+
headless: args.headless ?? false,
366370
signup: args.signup ?? false,
367371
localMcp: args.localMcp ?? false,
368372
mcpFeatures: args.mcpFeatures,

0 commit comments

Comments
 (0)