mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-16 20:02:45 +03:00
Restores ChatGPT Web on a clean-room browser transport, merged on the operator's explicit decision. Worth stating precisely, because this touches a provenance decision: the PR does not revert #11754. It narrows RETIRED_COMMON_CHATGPT_WEB_PROVIDER_IDS to the single GPL-derived alias cgpt-web and registers chatgpt-web as a separate clean-room id. The old implementation stays retired and blocked; the retirement machinery, its error code and its 410 contract are untouched. All four retirement suites agree with that distinction and pass unchanged. The 44 protected agent-instruction surfaces this PR touches (AGENTS.md, llm.txt and its 42 mirrors, README) were verified rather than trusted: masking digits and comparing the removed and added line sets gives 264 lines on each side, identical — every change is a provider-count substitution, with no sentence added, removed or reworded. Reconciled on merge: clean against the tip, with the two chat chokepoints this PR grows (src/sse/handlers/chat.ts +40, open-sse/handlers/chatCore.ts +30) recorded in the file-size baseline under an annotation. Verified that exactly those two caps move and nothing else, so the #12411 ratchet holds. The rebaseline is carried on this branch rather than left in a validation worktree — the propagation mistake that put the 2026-09-02 merge waves base-red in #12434. Verified: 504/504 across the PR's 44 test files plus all four chatgpt-web retirement suites, check:provider-consistency OK (272 REGISTRY entries, 355 canonical providers), check-file-size OK, and every changed TypeScript file parses. Thanks @backryun — separating the clean-room id from the retired alias, instead of reopening the old one, is what made this reviewable.
52 lines
1.9 KiB
TypeScript
52 lines
1.9 KiB
TypeScript
import { chatgpt_webProvider } from "../config/providers/registry/chatgpt-web/index.ts";
|
|
import {
|
|
executeChatGptWebCleanRoom,
|
|
type ChatGptWebExecutorAdapterDeps,
|
|
} from "../utils/chatgptWebExecutorAdapter.ts";
|
|
import { makeExecutorErrorResult, sanitizeErrorMessage } from "../utils/error.ts";
|
|
import { BaseExecutor, type ExecuteInput } from "./base.ts";
|
|
|
|
const CHATGPT_WEB_URL = "https://chatgpt.com";
|
|
|
|
function statusForAdapterError(message: string): number {
|
|
if (/storage state|credentials|connection ID/i.test(message)) return 401;
|
|
// Preserve upstream quota semantics so the shared account-fallback loop can exclude a
|
|
// depleted Free session and immediately try the next configured ChatGPT Web account.
|
|
if (
|
|
/(?:\bHTTP[_\s-]*429\b|\bstatus\s+429\b|\brate[-_\s]?limit(?:ed)?\b|\bquota\s+(?:exhausted|reached|exceeded)\b|\b(?:image(?:\s+upload)?|upload|usage)\s+limit\s+(?:reached|exceeded)\b|\breached\s+(?:your\s+)?(?:image(?:\s+upload)?|upload|usage)\s+limit\b)/i.test(
|
|
message
|
|
)
|
|
) {
|
|
return 429;
|
|
}
|
|
if (/request|messages|prompt|model|tools|text content|reasoning effort/i.test(message))
|
|
return 400;
|
|
return 502;
|
|
}
|
|
|
|
/** Common ChatGPT Web executor rebuilt solely from first-party UI/network observations. */
|
|
export class ChatGptWebExecutor extends BaseExecutor {
|
|
constructor(private readonly deps: ChatGptWebExecutorAdapterDeps = {}) {
|
|
super("chatgpt-web", {
|
|
id: chatgpt_webProvider.id,
|
|
baseUrl: chatgpt_webProvider.baseUrl,
|
|
});
|
|
}
|
|
|
|
async execute(input: ExecuteInput) {
|
|
try {
|
|
return await executeChatGptWebCleanRoom(input, this.deps);
|
|
} catch (error) {
|
|
const message = sanitizeErrorMessage(error);
|
|
return makeExecutorErrorResult(
|
|
statusForAdapterError(message),
|
|
message || "ChatGPT Web browser execution failed",
|
|
input.body,
|
|
CHATGPT_WEB_URL
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
export default ChatGptWebExecutor;
|