openai-ws-opencode 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/SECURITY.md +11 -0
  4. package/bin/setup.js +239 -0
  5. package/dist/auth/oauth.d.ts +55 -0
  6. package/dist/auth/oauth.d.ts.map +1 -0
  7. package/dist/auth/oauth.js +205 -0
  8. package/dist/auth/oauth.js.map +1 -0
  9. package/dist/auth/tokens.d.ts +19 -0
  10. package/dist/auth/tokens.d.ts.map +1 -0
  11. package/dist/auth/tokens.js +59 -0
  12. package/dist/auth/tokens.js.map +1 -0
  13. package/dist/constants.d.ts +17 -0
  14. package/dist/constants.d.ts.map +1 -0
  15. package/dist/constants.js +17 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +2 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/models/defaults.d.ts +16 -0
  22. package/dist/models/defaults.d.ts.map +1 -0
  23. package/dist/models/defaults.js +82 -0
  24. package/dist/models/defaults.js.map +1 -0
  25. package/dist/models/resolve.d.ts +112 -0
  26. package/dist/models/resolve.d.ts.map +1 -0
  27. package/dist/models/resolve.js +159 -0
  28. package/dist/models/resolve.js.map +1 -0
  29. package/dist/plugin.d.ts +4 -0
  30. package/dist/plugin.d.ts.map +1 -0
  31. package/dist/plugin.js +142 -0
  32. package/dist/plugin.js.map +1 -0
  33. package/dist/testing.d.ts +7 -0
  34. package/dist/testing.d.ts.map +1 -0
  35. package/dist/testing.js +7 -0
  36. package/dist/testing.js.map +1 -0
  37. package/dist/transport/body.d.ts +3 -0
  38. package/dist/transport/body.d.ts.map +1 -0
  39. package/dist/transport/body.js +22 -0
  40. package/dist/transport/body.js.map +1 -0
  41. package/dist/transport/bridge.d.ts +3 -0
  42. package/dist/transport/bridge.d.ts.map +1 -0
  43. package/dist/transport/bridge.js +78 -0
  44. package/dist/transport/bridge.js.map +1 -0
  45. package/dist/transport/headers.d.ts +32 -0
  46. package/dist/transport/headers.d.ts.map +1 -0
  47. package/dist/transport/headers.js +55 -0
  48. package/dist/transport/headers.js.map +1 -0
  49. package/dist/transport/pool.d.ts +56 -0
  50. package/dist/transport/pool.d.ts.map +1 -0
  51. package/dist/transport/pool.js +259 -0
  52. package/dist/transport/pool.js.map +1 -0
  53. package/package.json +59 -0
package/dist/plugin.js ADDED
@@ -0,0 +1,142 @@
1
+ import crypto from "node:crypto";
2
+ import { CODEX_API_BASE, CODEX_API_ENDPOINT, INTERNAL_AGENT_HEADER, INTERNAL_MODEL_HEADER, INTERNAL_PREFIX_HASH_HEADER, INTERNAL_SESSION_HEADER, OPENAI_API_BASE, PROVIDER_ID, } from "./constants.js";
3
+ import { oauthMethods } from "./auth/oauth.js";
4
+ import { extractAccountId, refreshAccessToken, tokenExpiry } from "./auth/tokens.js";
5
+ import { resolveModelsBestEffort } from "./models/resolve.js";
6
+ import { prepareHttpFallbackBody } from "./transport/body.js";
7
+ import { bridgeWebSocket } from "./transport/bridge.js";
8
+ import { closeConnections } from "./transport/pool.js";
9
+ import { extractTransportContext, httpAuthHeaders, transportIdentity } from "./transport/headers.js";
10
+ function stableHash(value) {
11
+ return crypto.createHash("sha256").update(JSON.stringify(value ?? "")).digest("hex").slice(0, 32);
12
+ }
13
+ async function resolveOAuthAuth(auth, client) {
14
+ const expiryBufferMs = 5 * 60 * 1000;
15
+ if (auth.access && auth.expires && auth.expires > Date.now() + expiryBufferMs) {
16
+ return { accessToken: auth.access, accountId: auth.accountId };
17
+ }
18
+ const tokens = await refreshAccessToken(auth.refresh);
19
+ const accountId = extractAccountId(tokens) ?? auth.accountId;
20
+ await client.auth.set({
21
+ path: { id: PROVIDER_ID },
22
+ body: {
23
+ type: "oauth",
24
+ refresh: tokens.refresh_token ?? auth.refresh,
25
+ access: tokens.access_token,
26
+ expires: tokenExpiry(tokens.expires_in),
27
+ ...(accountId ? { accountId } : {}),
28
+ },
29
+ });
30
+ return { accessToken: tokens.access_token, accountId };
31
+ }
32
+ function shouldBridge(url, init) {
33
+ return (init?.method?.toUpperCase() === "POST" &&
34
+ (url.pathname.includes("/v1/responses") || url.pathname.includes("/backend-api/codex/responses")) &&
35
+ typeof init.body === "string");
36
+ }
37
+ const OpenAIWebSocketPlugin = async ({ client }) => {
38
+ const hooks = {
39
+ "chat.headers": async (input, output) => {
40
+ if (input.model.providerID !== PROVIDER_ID)
41
+ return;
42
+ const headers = (output.headers ??= {});
43
+ headers[INTERNAL_SESSION_HEADER] = input.sessionID;
44
+ headers[INTERNAL_AGENT_HEADER] = input.agent;
45
+ headers[INTERNAL_MODEL_HEADER] = input.model.id ?? input.model.modelID;
46
+ headers[INTERNAL_PREFIX_HASH_HEADER] = stableHash(input.message);
47
+ },
48
+ event: async ({ event }) => {
49
+ if (event.type === "session.deleted") {
50
+ const deletedSessionID = event.properties?.info?.id;
51
+ closeConnections((conn) => conn.activeSessionID === deletedSessionID || conn.lastSessionID === deletedSessionID);
52
+ return;
53
+ }
54
+ const eventType = String(event.type);
55
+ if (eventType === "server.instance.disposed" || eventType === "global.disposed") {
56
+ closeConnections();
57
+ }
58
+ },
59
+ auth: {
60
+ provider: PROVIDER_ID,
61
+ async loader(getAuth, provider) {
62
+ const auth = (await getAuth());
63
+ if (provider)
64
+ provider.models = (await resolveModelsBestEffort(provider.models));
65
+ if (auth?.type === "api" && auth.key) {
66
+ const apiKey = auth.key;
67
+ const identity = transportIdentity({ type: "api", apiKey });
68
+ return {
69
+ apiKey,
70
+ baseURL: OPENAI_API_BASE,
71
+ async fetch(input, init) {
72
+ const url = typeof input === "string" ? new URL(input) : input instanceof URL ? input : new URL(input.url);
73
+ const context = extractTransportContext(init?.headers);
74
+ if (shouldBridge(url, init)) {
75
+ try {
76
+ const body = JSON.parse(init?.body);
77
+ if (body.stream !== false) {
78
+ return bridgeWebSocket(identity.wsUrl, identity.wsHeaders, body, false, context, init?.signal ?? undefined);
79
+ }
80
+ }
81
+ catch { }
82
+ }
83
+ if (init?.method?.toUpperCase() === "POST" && typeof init.body === "string") {
84
+ try {
85
+ init = { ...init, body: JSON.stringify(prepareHttpFallbackBody(JSON.parse(init.body), false)) };
86
+ }
87
+ catch { }
88
+ }
89
+ return globalThis.fetch(input, {
90
+ ...init,
91
+ headers: httpAuthHeaders(context.forwardHeaders, { type: "api", apiKey }),
92
+ });
93
+ },
94
+ };
95
+ }
96
+ if (auth?.type === "oauth") {
97
+ const initialAuth = await resolveOAuthAuth(auth, client);
98
+ return {
99
+ apiKey: initialAuth.accessToken,
100
+ baseURL: CODEX_API_BASE,
101
+ async fetch(input, init) {
102
+ const currentAuth = (await getAuth());
103
+ if (currentAuth?.type !== "oauth")
104
+ throw new Error("OpenAI WebSocket OAuth auth is missing");
105
+ const { accessToken, accountId } = await resolveOAuthAuth(currentAuth, client);
106
+ const identity = transportIdentity({ type: "oauth", accessToken, accountId });
107
+ const url = typeof input === "string" ? new URL(input) : input instanceof URL ? input : new URL(input.url);
108
+ const context = extractTransportContext(init?.headers);
109
+ if (shouldBridge(url, init)) {
110
+ try {
111
+ const body = JSON.parse(init?.body);
112
+ if (body.stream !== false) {
113
+ return bridgeWebSocket(identity.wsUrl, identity.wsHeaders, body, true, context, init?.signal ?? undefined);
114
+ }
115
+ }
116
+ catch { }
117
+ }
118
+ if (init?.method?.toUpperCase() === "POST" && typeof init.body === "string") {
119
+ try {
120
+ init = { ...init, body: JSON.stringify(prepareHttpFallbackBody(JSON.parse(init.body), true)) };
121
+ }
122
+ catch { }
123
+ }
124
+ const rewrittenUrl = url.pathname.includes("/v1/responses") || url.pathname.includes("/chat/completions")
125
+ ? new URL(CODEX_API_ENDPOINT)
126
+ : url;
127
+ return globalThis.fetch(rewrittenUrl, {
128
+ ...init,
129
+ headers: httpAuthHeaders(context.forwardHeaders, { type: "oauth", accessToken, accountId }),
130
+ });
131
+ },
132
+ };
133
+ }
134
+ throw new Error("OpenAI WebSocket auth is missing; run `opencode auth login openai-ws`.");
135
+ },
136
+ methods: oauthMethods,
137
+ },
138
+ };
139
+ return hooks;
140
+ };
141
+ export default OpenAIWebSocketPlugin;
142
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { oauthTesting } from "./auth/oauth.js";
2
+ export { prepareBody, prepareHttpFallbackBody } from "./transport/body.js";
3
+ export { apiKeyWebSocketHeaders, oauthWebSocketHeaders, extractTransportContext, transportIdentity } from "./transport/headers.js";
4
+ export { connectionPool, readyState, resetPoolForTesting, resetWebSocketConstructorForTesting, setWebSocketConstructorForTesting, } from "./transport/pool.js";
5
+ export { bridgeWebSocket } from "./transport/bridge.js";
6
+ export { resolveModels, resolveModelsBestEffort, resolveModelsFromCatalog, providerConfig } from "./models/resolve.js";
7
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC1E,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAClI,OAAO,EACL,cAAc,EACd,UAAU,EACV,mBAAmB,EACnB,mCAAmC,EACnC,iCAAiC,GAClC,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,7 @@
1
+ export { oauthTesting } from "./auth/oauth.js";
2
+ export { prepareBody, prepareHttpFallbackBody } from "./transport/body.js";
3
+ export { apiKeyWebSocketHeaders, oauthWebSocketHeaders, extractTransportContext, transportIdentity } from "./transport/headers.js";
4
+ export { connectionPool, readyState, resetPoolForTesting, resetWebSocketConstructorForTesting, setWebSocketConstructorForTesting, } from "./transport/pool.js";
5
+ export { bridgeWebSocket } from "./transport/bridge.js";
6
+ export { resolveModels, resolveModelsBestEffort, resolveModelsFromCatalog, providerConfig } from "./models/resolve.js";
7
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC1E,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAClI,OAAO,EACL,cAAc,EACd,UAAU,EACV,mBAAmB,EACnB,mCAAmC,EACnC,iCAAiC,GAClC,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,3 @@
1
+ export declare function prepareBody(requestBody: Record<string, unknown>, isOAuth: boolean): Record<string, unknown>;
2
+ export declare function prepareHttpFallbackBody(requestBody: Record<string, unknown>, isOAuth: boolean): Record<string, unknown>;
3
+ //# sourceMappingURL=body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../src/transport/body.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAY3G;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKvH"}
@@ -0,0 +1,22 @@
1
+ import { DEFAULT_INSTRUCTIONS } from "../constants.js";
2
+ export function prepareBody(requestBody, isOAuth) {
3
+ const { stream: _stream, stream_options: _streamOptions, ...wsBody } = requestBody;
4
+ if (!wsBody.instructions)
5
+ wsBody.instructions = DEFAULT_INSTRUCTIONS;
6
+ if (isOAuth) {
7
+ if (wsBody.store === undefined)
8
+ wsBody.store = false;
9
+ delete wsBody.max_output_tokens;
10
+ delete wsBody.max_tokens;
11
+ }
12
+ return wsBody;
13
+ }
14
+ export function prepareHttpFallbackBody(requestBody, isOAuth) {
15
+ const next = { ...requestBody };
16
+ if (!next.instructions)
17
+ next.instructions = DEFAULT_INSTRUCTIONS;
18
+ if (isOAuth && next.store === undefined)
19
+ next.store = false;
20
+ return next;
21
+ }
22
+ //# sourceMappingURL=body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body.js","sourceRoot":"","sources":["../../src/transport/body.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,UAAU,WAAW,CAAC,WAAoC,EAAE,OAAgB;IAChF,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,GAAG,WAAW,CAAA;IAElF,IAAI,CAAC,MAAM,CAAC,YAAY;QAAE,MAAM,CAAC,YAAY,GAAG,oBAAoB,CAAA;IAEpE,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;QACpD,OAAO,MAAM,CAAC,iBAAiB,CAAA;QAC/B,OAAO,MAAM,CAAC,UAAU,CAAA;IAC1B,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,WAAoC,EAAE,OAAgB;IAC5F,MAAM,IAAI,GAAG,EAAE,GAAG,WAAW,EAAE,CAAA;IAC/B,IAAI,CAAC,IAAI,CAAC,YAAY;QAAE,IAAI,CAAC,YAAY,GAAG,oBAAoB,CAAA;IAChE,IAAI,OAAO,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IAC3D,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { TransportContext } from "./headers.js";
2
+ export declare function bridgeWebSocket(wsUrl: string, headers: Record<string, string>, requestBody: Record<string, unknown>, isOAuth: boolean, context?: TransportContext, signal?: AbortSignal): Response;
3
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/transport/bridge.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAkBpD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,gBAAqB,EAC9B,MAAM,CAAC,EAAE,WAAW,GACnB,QAAQ,CAyDV"}
@@ -0,0 +1,78 @@
1
+ import { prepareBody } from "./body.js";
2
+ import { acquireConnection, closeConnections } from "./pool.js";
3
+ function abortPending(conn, error) {
4
+ const pending = conn.pending;
5
+ if (!pending || pending.done)
6
+ return;
7
+ pending.done = true;
8
+ if (conn.ws?.readyState === 1) {
9
+ try {
10
+ conn.ws.send(JSON.stringify({ type: "response.cancel" }));
11
+ }
12
+ catch { }
13
+ }
14
+ try {
15
+ pending.controller.error(error);
16
+ }
17
+ catch { }
18
+ conn.pending = null;
19
+ closeConnections((candidate) => candidate === conn);
20
+ }
21
+ export function bridgeWebSocket(wsUrl, headers, requestBody, isOAuth, context = {}, signal) {
22
+ const wsBody = prepareBody(requestBody, isOAuth);
23
+ const conn = acquireConnection(wsUrl, headers, context);
24
+ let finalized = false;
25
+ const cleanupAbort = () => {
26
+ if (signal)
27
+ signal.removeEventListener("abort", onAbort);
28
+ };
29
+ const onAbort = () => {
30
+ if (finalized)
31
+ return;
32
+ finalized = true;
33
+ cleanupAbort();
34
+ abortPending(conn, signal?.reason instanceof Error ? signal.reason : new DOMException("Aborted", "AbortError"));
35
+ };
36
+ const readable = new ReadableStream({
37
+ start(controller) {
38
+ conn.activeSessionID = context.sessionID;
39
+ conn.activeAgent = context.agent;
40
+ conn.lastModelID = context.modelID ?? conn.lastModelID;
41
+ conn.lastStablePrefixHash = context.stablePrefixHash ?? conn.lastStablePrefixHash;
42
+ conn.pending = {
43
+ body: wsBody,
44
+ controller,
45
+ done: false,
46
+ sent: false,
47
+ forwarded: false,
48
+ };
49
+ if (signal?.aborted) {
50
+ onAbort();
51
+ return;
52
+ }
53
+ if (signal)
54
+ signal.addEventListener("abort", onAbort, { once: true });
55
+ if (conn.ws?.readyState === 1) {
56
+ conn.ws.send(JSON.stringify({ type: "response.create", ...wsBody }));
57
+ conn.pending.sent = true;
58
+ }
59
+ },
60
+ cancel() {
61
+ if (finalized)
62
+ return;
63
+ finalized = true;
64
+ cleanupAbort();
65
+ abortPending(conn, new DOMException("Aborted", "AbortError"));
66
+ },
67
+ });
68
+ return new Response(readable, {
69
+ status: 200,
70
+ headers: {
71
+ "content-type": "text/event-stream",
72
+ "cache-control": "no-cache",
73
+ connection: "keep-alive",
74
+ "x-request-id": `ws-${Date.now()}`,
75
+ },
76
+ });
77
+ }
78
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/transport/bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export type TransportContext = {
2
+ sessionID?: string;
3
+ agent?: string;
4
+ modelID?: string;
5
+ stablePrefixHash?: string;
6
+ };
7
+ export declare function apiKeyWebSocketHeaders(apiKey: string): Record<string, string>;
8
+ export declare function oauthWebSocketHeaders(accessToken: string, accountId?: string): Record<string, string>;
9
+ export declare function httpAuthHeaders(baseHeaders: HeadersInit | undefined, auth: {
10
+ type: "api";
11
+ apiKey: string;
12
+ } | {
13
+ type: "oauth";
14
+ accessToken: string;
15
+ accountId?: string;
16
+ }): Headers;
17
+ export declare function transportIdentity(auth: {
18
+ type: "api";
19
+ apiKey: string;
20
+ } | {
21
+ type: "oauth";
22
+ accessToken: string;
23
+ accountId?: string;
24
+ }): {
25
+ isOAuth: boolean;
26
+ wsUrl: string;
27
+ wsHeaders: Record<string, string>;
28
+ };
29
+ export declare function extractTransportContext(input?: HeadersInit): TransportContext & {
30
+ forwardHeaders: Headers;
31
+ };
32
+ //# sourceMappingURL=headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/transport/headers.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK7E;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOrG;AAED,wBAAgB,eAAe,CAC7B,WAAW,EAAE,WAAW,GAAG,SAAS,EACpC,IAAI,EAAE;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjG,OAAO,CAWT;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;;;;EAanI;AAED,wBAAgB,uBAAuB,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,gBAAgB,GAAG;IAAE,cAAc,EAAE,OAAO,CAAA;CAAE,CAa3G"}
@@ -0,0 +1,55 @@
1
+ import { CODEX_ORIGINATOR, CODEX_WS_URL, INTERNAL_AGENT_HEADER, INTERNAL_MODEL_HEADER, INTERNAL_PREFIX_HASH_HEADER, INTERNAL_SESSION_HEADER, OPENAI_WS_BETA, OPENAI_WS_URL, } from "../constants.js";
2
+ export function apiKeyWebSocketHeaders(apiKey) {
3
+ return {
4
+ Authorization: `Bearer ${apiKey}`,
5
+ "OpenAI-Beta": OPENAI_WS_BETA,
6
+ };
7
+ }
8
+ export function oauthWebSocketHeaders(accessToken, accountId) {
9
+ return {
10
+ Authorization: `Bearer ${accessToken}`,
11
+ ...(accountId ? { "ChatGPT-Account-Id": accountId } : {}),
12
+ originator: CODEX_ORIGINATOR,
13
+ "OpenAI-Beta": OPENAI_WS_BETA,
14
+ };
15
+ }
16
+ export function httpAuthHeaders(baseHeaders, auth) {
17
+ const headers = new Headers(baseHeaders);
18
+ headers.delete("authorization");
19
+ headers.delete("Authorization");
20
+ headers.set("Authorization", `Bearer ${auth.type === "api" ? auth.apiKey : auth.accessToken}`);
21
+ if (auth.type === "oauth") {
22
+ if (auth.accountId)
23
+ headers.set("ChatGPT-Account-Id", auth.accountId);
24
+ headers.set("originator", CODEX_ORIGINATOR);
25
+ headers.set("OpenAI-Beta", OPENAI_WS_BETA);
26
+ }
27
+ return headers;
28
+ }
29
+ export function transportIdentity(auth) {
30
+ if (auth.type === "oauth") {
31
+ return {
32
+ isOAuth: true,
33
+ wsUrl: CODEX_WS_URL,
34
+ wsHeaders: oauthWebSocketHeaders(auth.accessToken, auth.accountId),
35
+ };
36
+ }
37
+ return {
38
+ isOAuth: false,
39
+ wsUrl: OPENAI_WS_URL,
40
+ wsHeaders: apiKeyWebSocketHeaders(auth.apiKey),
41
+ };
42
+ }
43
+ export function extractTransportContext(input) {
44
+ const forwardHeaders = new Headers(input);
45
+ const sessionID = forwardHeaders.get(INTERNAL_SESSION_HEADER) ?? undefined;
46
+ const agent = forwardHeaders.get(INTERNAL_AGENT_HEADER) ?? undefined;
47
+ const modelID = forwardHeaders.get(INTERNAL_MODEL_HEADER) ?? undefined;
48
+ const stablePrefixHash = forwardHeaders.get(INTERNAL_PREFIX_HASH_HEADER) ?? undefined;
49
+ forwardHeaders.delete(INTERNAL_SESSION_HEADER);
50
+ forwardHeaders.delete(INTERNAL_AGENT_HEADER);
51
+ forwardHeaders.delete(INTERNAL_MODEL_HEADER);
52
+ forwardHeaders.delete(INTERNAL_PREFIX_HASH_HEADER);
53
+ return { sessionID, agent, modelID, stablePrefixHash, forwardHeaders };
54
+ }
55
+ //# sourceMappingURL=headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.js","sourceRoot":"","sources":["../../src/transport/headers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import type { TransportContext } from "./headers.js";
2
+ type WebSocketLike = {
3
+ readyState: number;
4
+ send(data: string): void;
5
+ close(code?: number, reason?: string): void;
6
+ terminate?: () => void;
7
+ ping?: () => void;
8
+ on?(event: string, listener: (...args: any[]) => void): unknown;
9
+ off?(event: string, listener: (...args: any[]) => void): unknown;
10
+ addEventListener?(event: string, listener: (...args: any[]) => void): unknown;
11
+ removeEventListener?(event: string, listener: (...args: any[]) => void): unknown;
12
+ };
13
+ type WebSocketConstructor = new (url: string, options: {
14
+ headers: Record<string, string>;
15
+ }) => WebSocketLike;
16
+ export interface PendingRequest {
17
+ body: Record<string, unknown>;
18
+ controller: ReadableStreamDefaultController<Uint8Array>;
19
+ done: boolean;
20
+ sent: boolean;
21
+ forwarded: boolean;
22
+ }
23
+ export interface PooledConnection {
24
+ ws: WebSocketLike | null;
25
+ wsUrl: string;
26
+ headers: Record<string, string>;
27
+ scopeKey: string;
28
+ busy: boolean;
29
+ pending: PendingRequest | null;
30
+ activeSessionID?: string;
31
+ lastSessionID?: string;
32
+ activeAgent?: string;
33
+ lastAgent?: string;
34
+ lastModelID?: string;
35
+ lastStablePrefixHash?: string;
36
+ generation: number;
37
+ reconnectAttempts: number;
38
+ idleTimer: ReturnType<typeof setTimeout> | null;
39
+ connectTimer: ReturnType<typeof setTimeout> | null;
40
+ retryTimer: ReturnType<typeof setTimeout> | null;
41
+ detach: (() => void) | null;
42
+ }
43
+ export declare const connectionPool: PooledConnection[];
44
+ export declare const readyState: {
45
+ readonly CONNECTING: 0;
46
+ readonly OPEN: 1;
47
+ readonly CLOSING: 2;
48
+ readonly CLOSED: 3;
49
+ };
50
+ export declare function acquireConnection(wsUrl: string, headers: Record<string, string>, context: TransportContext): PooledConnection;
51
+ export declare function closeConnections(predicate?: (conn: PooledConnection) => boolean): void;
52
+ export declare function resetPoolForTesting(): void;
53
+ export declare function setWebSocketConstructorForTesting(ctor: WebSocketConstructor): void;
54
+ export declare function resetWebSocketConstructorForTesting(): void;
55
+ export {};
56
+ //# sourceMappingURL=pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/transport/pool.ts"],"names":[],"mappings":"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"}