Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

### Fixed

- Browser: preserve authenticated model-picker errors instead of appending a misleading cookie/login hint after login has already been verified.
- Browser: distinguish requested CLI model keys from verified ChatGPT picker labels without inferring a server-side GPT version from a generic label. Fixes #317. Thanks @DragonFSKY!
- Browser: recognize GPT-5.6 Sol as the selected model when ChatGPT exposes Pro in its independent effort pill. Thanks @jung0han!
- Browser: treat WSL's systemd-resolved loopback DNS stub as localhost when connecting to a freshly launched Chrome DevTools endpoint. Thanks @Rokurolize!
Expand Down
14 changes: 8 additions & 6 deletions src/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ function shouldPreserveBrowserOnError(error: unknown, headless: boolean): boolea
return classifyPreservedBrowserError(error, headless) !== null;
}

function normalizeAuthenticatedModelSelectionError(error: unknown): Error {
return error instanceof Error ? error : new Error(String(error));
}

function shouldKeepLocalBrowserOpen(options: {
effectiveKeepBrowser: boolean;
preserveBrowserOnError: boolean;
Expand Down Expand Up @@ -1474,12 +1478,9 @@ export async function runBrowserMode(options: BrowserRunOptions): Promise<Browse
},
),
).catch((error) => {
const base = error instanceof Error ? error.message : String(error);
const hint =
appliedCookies === 0
? " No cookies were applied; log in to ChatGPT in Chrome or provide inline cookies (--browser-inline-cookies[(-file)] or ORACLE_BROWSER_COOKIES_JSON)."
: "";
throw new Error(`${base}${hint}`);
// Login has already been verified above. Preserve the picker failure instead of
// misdiagnosing an unavailable model as missing cookies.
throw normalizeAuthenticatedModelSelectionError(error);
});
await raceWithDisconnect(ensurePromptReady(Runtime, config.inputTimeoutMs, logger));
logger(
Expand Down Expand Up @@ -3881,6 +3882,7 @@ export const __test__ = {
isManualLoginProfileInitialized,
isImageOnlyUiChromeText,
listIgnoredRemoteChromeFlags,
normalizeAuthenticatedModelSelectionError,
resolveManualLoginWaitMs,
shouldCleanupBlankTabsAfterLastLease,
shouldCloseOwnedRunTargetAfterRun,
Expand Down
15 changes: 15 additions & 0 deletions tests/browser/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ describe("shouldPreserveBrowserOnErrorForTest", () => {
});
});

describe("authenticated model-selection errors", () => {
test("preserves picker diagnostics without adding cookie guidance", () => {
const error = new BrowserAutomationError(
'Unable to find model option matching "GPT-5.2 Instant". Available: GPT-5.6 Sol.',
{ stage: "model-selection" },
);

const normalized = __test__.normalizeAuthenticatedModelSelectionError(error);

expect(normalized).toBe(error);
expect(normalized.message).toContain("Available: GPT-5.6 Sol");
expect(normalized.message).not.toMatch(/cookies|log in/i);
});
});

describe("browser run target cleanup", () => {
test("never retains a copied profile after a preserved browser error", () => {
expect(
Expand Down