mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-12 10:12:11 +03:00
Add native ChatGPT Web provider for Codex clients (#8949)
* Bypass proxy compaction for native Codex context
* Add native ChatGPT Web provider pipeline
* Add managed browser and tunnel deployment
* Add ChatGPT Web setup and doctor UI
* Document and test ChatGPT Web integration
* fix(security): register chatgpt-web-codex-doctor in LOCAL_ONLY_API_PATTERNS
The diagnostic route under /api/providers/{id}/chatgpt-web-codex-doctor
was not registered in the spawn-capable route guard. Adding it for
parity with the existing /login pattern.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(providers): route chatgpt-web-codex admin routes through a service boundary
The provider CRUD/doctor routes imported chatgpt-web-codex helpers
(finalizeValidatedChatGptWebCodexSecrets, encode/decodeChatGptWebCodexSecrets,
getChatGptWebCodexDoctorStatus) directly from open-sse/executors/**, which
no-restricted-imports (EXECUTOR_IMPORT_RESTRICTION) forbids for src/app/**
files — executor implementations must stay behind an open-sse handler or
service boundary.
Add open-sse/services/chatgptWebCodexAdmin.ts as a thin re-export boundary
(mirroring the existing tokenRefresh.ts re-export pattern) and import from
there instead. No behavior change.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
@@ -585,12 +585,18 @@ class ResponsesWsSession {
|
||||
// preparedContext, but never touches this.upstream/this.upstreamReady; the caller decides
|
||||
// whether a new upstream socket is needed.
|
||||
async runPrepare(message, responseBody) {
|
||||
const prepared = await callInternal(this.fetchImpl, this.baseUrl, this.bridgeSecret, "prepare", {
|
||||
requestUrl: this.requestUrl,
|
||||
headers: getAuthHeaders(this.requestUrl, this.requestHeaders),
|
||||
message,
|
||||
response: responseBody,
|
||||
});
|
||||
const prepared = await callInternal(
|
||||
this.fetchImpl,
|
||||
this.baseUrl,
|
||||
this.bridgeSecret,
|
||||
"prepare",
|
||||
{
|
||||
requestUrl: this.requestUrl,
|
||||
headers: getAuthHeaders(this.requestUrl, this.requestHeaders),
|
||||
message,
|
||||
response: responseBody,
|
||||
}
|
||||
);
|
||||
|
||||
if (!prepared.ok) {
|
||||
const message2 =
|
||||
@@ -602,6 +608,7 @@ class ResponsesWsSession {
|
||||
const error = new Error(message2);
|
||||
error.code = code;
|
||||
error.status = prepared.status;
|
||||
if (code === "responses_websocket_http_fallback") error.httpFallback = true;
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -716,11 +723,28 @@ class ResponsesWsSession {
|
||||
// otherwise every turn after the first bypasses the whole pipeline. This reuses
|
||||
// the already-established upstream transport; it must NOT recreate the socket.
|
||||
const prepared = await this.runPrepare(message, nextTurnBody);
|
||||
this.upstream.send(jsonStringifySafe(withPreparedResponseCreate(message, prepared.json.response)));
|
||||
this.upstream.send(
|
||||
jsonStringifySafe(withPreparedResponseCreate(message, prepared.json.response))
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.upstream.send(jsonStringifySafe(message));
|
||||
} catch (error) {
|
||||
if (error?.httpFallback) {
|
||||
const failurePayload = this.sendFailure(
|
||||
"responses_websocket_http_fallback",
|
||||
"Retry this request over HTTP/SSE Responses"
|
||||
);
|
||||
void this.persistHistory({
|
||||
status: 426,
|
||||
success: false,
|
||||
errorCode: "responses_websocket_http_fallback",
|
||||
errorMessage: "HTTP/SSE Responses transport required",
|
||||
terminalMessage: failurePayload,
|
||||
});
|
||||
this.close(1013, "http_fallback_required");
|
||||
return;
|
||||
}
|
||||
const code = error?.code || "upstream_websocket_connect_failed";
|
||||
const messageText = error instanceof Error ? error.message : String(error);
|
||||
const failurePayload = this.sendFailure(code, messageText);
|
||||
|
||||
Reference in New Issue
Block a user