mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-15 19:52:50 +03:00
* 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>
70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import {
|
|
applyNativeCodexTurnPin,
|
|
clearNativeCodexTurnPinsForTests,
|
|
getNativeCodexTurnPin,
|
|
pinNativeCodexTurn,
|
|
revokeNativeCodexTurnPinsForConnection,
|
|
} from "../../open-sse/services/combo/nativeCodexTurnPin.ts";
|
|
import type { ResolvedComboTarget } from "../../open-sse/services/combo/types.ts";
|
|
|
|
const body = {
|
|
client_metadata: {
|
|
"x-codex-turn-metadata": JSON.stringify({ thread_id: "thread-1", turn_id: "turn-1" }),
|
|
},
|
|
};
|
|
|
|
function target(modelStr: string, provider: string): ResolvedComboTarget {
|
|
return {
|
|
kind: "model",
|
|
stepId: `step-${provider}`,
|
|
executionKey: `${provider}:${modelStr}`,
|
|
modelStr,
|
|
provider,
|
|
providerId: provider,
|
|
connectionId: null,
|
|
weight: 1,
|
|
label: null,
|
|
};
|
|
}
|
|
|
|
test("native continuation pins provider, model and connection", () => {
|
|
clearNativeCodexTurnPinsForTests();
|
|
const pinnedTarget = target("chatgpt-web-codex/high", "chatgpt-web-codex");
|
|
pinNativeCodexTurn({
|
|
body,
|
|
comboName: "coding",
|
|
target: pinnedTarget,
|
|
connectionId: "connection-a",
|
|
});
|
|
const pin = getNativeCodexTurnPin(body, "coding");
|
|
assert.ok(pin);
|
|
assert.deepEqual(applyNativeCodexTurnPin([pinnedTarget], pin), [
|
|
{ ...pinnedTarget, connectionId: "connection-a", allowedConnectionIds: ["connection-a"] },
|
|
]);
|
|
assert.equal(revokeNativeCodexTurnPinsForConnection("connection-a"), 1);
|
|
assert.equal(getNativeCodexTurnPin(body, "coding"), null);
|
|
});
|
|
|
|
test("a pinned turn cannot silently move to another target", () => {
|
|
clearNativeCodexTurnPinsForTests();
|
|
pinNativeCodexTurn({
|
|
body,
|
|
comboName: "coding",
|
|
target: target("chatgpt-web-codex/high", "chatgpt-web-codex"),
|
|
connectionId: "connection-a",
|
|
});
|
|
assert.throws(
|
|
() =>
|
|
pinNativeCodexTurn({
|
|
body,
|
|
comboName: "coding",
|
|
target: target("codex/gpt-5.6-sol", "codex"),
|
|
connectionId: "connection-b",
|
|
}),
|
|
/changed after output/
|
|
);
|
|
});
|