From 698e09621b8e33cf41e71b8e570ee2bf0b8eb517 Mon Sep 17 00:00:00 2001 From: BinBin He Date: Thu, 30 Jul 2026 10:19:57 -0700 Subject: [PATCH] Treat fast mode as opt-in so a turn that never asked for it is not billed against a tier the organization may have no quota for --- src/harness/pi-harness.ts | 20 ++++++++++++++++++-- test/pi-harness-fast-mode.test.ts | 22 +++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/harness/pi-harness.ts b/src/harness/pi-harness.ts index 7a54c5130..133429dfe 100644 --- a/src/harness/pi-harness.ts +++ b/src/harness/pi-harness.ts @@ -1034,6 +1034,22 @@ const FAST_MODE_BETA = "fast-mode-2026-02-01"; export { modelSupportsFastMode } from "../model/pi-models.ts"; +/** + * Whether a turn should run in fast mode. + * + * Fast mode is OPT-IN: only an explicit `true` selects it. An unset `fastMode` means the + * caller expressed no preference, and treating that as "yes" bills the turn against a tier + * it never asked for — or fails it outright on an organization with no fast-mode quota, + * where the provider answers `rate_limit_error: … 0 fast mode input tokens per minute`. + * + * Only the web UI ever sets the field today, so every other entry point (CLI, API clients, + * integrations) leaves it undefined. `claude-harness` already reads it as opt-in + * (`turn.fastMode && …`); this keeps both harnesses agreeing on the same default. + */ +export function wantsFastMode(fastMode: boolean | undefined, modelId: string | undefined): boolean { + return fastMode === true && modelSupportsFastMode(modelId); +} + export const TURN_PROVIDER_EFFORT_ALIASES: Record = { max: "max", ultracode: "max", @@ -1447,7 +1463,7 @@ export function createPiHarness(opts?: PiHarnessOptions): Harness { entry.ref.toolApprovalGate = turn.toolApprovalGate; const desiredModelId = turn.model ?? resolveModelId(turn.scopeLabel); - const wantFast = turn.fastMode !== false && modelSupportsFastMode(desiredModelId); + const wantFast = wantsFastMode(turn.fastMode, desiredModelId); const current = entry.agentSession.model as { id?: string; headers?: Record } | undefined; const currentFast = Boolean(current?.headers?.["anthropic-beta"]?.includes(FAST_MODE_BETA)); if (current?.id !== desiredModelId || currentFast !== wantFast) { @@ -1707,7 +1723,7 @@ export function createPiHarness(opts?: PiHarnessOptions): Harness { console.error( `[pi] provider refusal — retrying on fallback model ${fromId} -> ${fallbackId} session=${turn.session.id}: ${refusal}`, ); - const wantFast = turn.fastMode !== false && modelSupportsFastMode(fallbackId); + const wantFast = wantsFastMode(turn.fastMode, fallbackId); await entry.agentSession.setModel(wantFast ? withFastModeHeaders(fallback) : fallback); const active = entry.agentSession.model as { headers?: Record } | undefined; entry.ref.fast = Boolean(active?.headers?.["anthropic-beta"]?.includes(FAST_MODE_BETA)); diff --git a/test/pi-harness-fast-mode.test.ts b/test/pi-harness-fast-mode.test.ts index 65415af13..0d6d5f458 100644 --- a/test/pi-harness-fast-mode.test.ts +++ b/test/pi-harness-fast-mode.test.ts @@ -1,6 +1,11 @@ import { test } from "node:test"; import assert from "node:assert/strict"; -import { applyFastSpeed, modelSupportsFastMode, TURN_PROVIDER_EFFORT_ALIASES } from "../src/harness/pi-harness.ts"; +import { + applyFastSpeed, + modelSupportsFastMode, + wantsFastMode, + TURN_PROVIDER_EFFORT_ALIASES, +} from "../src/harness/pi-harness.ts"; import { defaultInteractiveThinkingLevel } from "../src/model/pi-models.ts"; test("modelSupportsFastMode allows only the documented direct Opus ids", () => { @@ -50,3 +55,18 @@ test("defaultInteractiveThinkingLevel keeps human turns light by provider", () = assert.equal(defaultInteractiveThinkingLevel({ provider: "anthropic", api: "anthropic-messages" }), "low"); assert.equal(defaultInteractiveThinkingLevel({ provider: "openai", api: "openai-responses" }), "auto"); }); + +test("fast mode is opt-in: only an explicit true selects it", () => { + // A turn that never mentions fastMode has expressed no preference. Reading that as "yes" + // bills it against a tier nobody asked for, and on an organization with no fast-mode + // quota the provider rejects every such turn outright. + assert.equal(wantsFastMode(undefined, "claude-opus-5"), false, "unset must not select fast mode"); + assert.equal(wantsFastMode(false, "claude-opus-5"), false); + assert.equal(wantsFastMode(true, "claude-opus-5"), true, "an explicit opt-in is honoured"); +}); + +test("an explicit opt-in still cannot select fast mode on a model that lacks it", () => { + assert.equal(wantsFastMode(true, "claude-sonnet-5"), false); + assert.equal(wantsFastMode(true, undefined), false); + assert.equal(wantsFastMode(true, ""), false); +});