@jeffusion/bungee-core 5.4.1 → 5.4.3
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.
- package/dist/main.js +132 -31
- package/dist/plugins/chatgpt-oauth/index.js +110 -22
- package/dist/plugins/chatgpt-oauth/index.js.map +6 -5
- package/package.json +2 -2
|
@@ -14823,15 +14823,47 @@ function definePlugin(plugin) {
|
|
|
14823
14823
|
return plugin;
|
|
14824
14824
|
}
|
|
14825
14825
|
|
|
14826
|
+
// plugins/chatgpt-oauth/server/error-diagnostics.ts
|
|
14827
|
+
var MAX_MESSAGE_CHARS = 1024;
|
|
14828
|
+
function errorDiagnostic(value, source, fallback, redact) {
|
|
14829
|
+
const object = value !== null && typeof value === "object" ? value : {};
|
|
14830
|
+
const clean = (value) => {
|
|
14831
|
+
let text = value.slice(0, 16384);
|
|
14832
|
+
text = redact?.(text) ?? text;
|
|
14833
|
+
text = text.replace(/\bBearer\s+[^\s,;"'<>]+/gi, "Bearer [REDACTED]").replace(/\b(?:sk-[\w-]+|eyJ[\w-]+\.[\w-]+\.[\w-]+)/g, "[REDACTED]").replace(/((?:authorization|access_token|refresh_token|id_token|api[_-]?key|cookie)["']?\s*[=:]\s*["']?)[^\s,;&"'<>]+/gi, "$1[REDACTED]").replace(/[\x00-\x1f\x7f]+/g, " ");
|
|
14834
|
+
return text.slice(0, MAX_MESSAGE_CHARS).trim();
|
|
14835
|
+
};
|
|
14836
|
+
const identifier = (value) => {
|
|
14837
|
+
if (typeof value !== "string")
|
|
14838
|
+
return;
|
|
14839
|
+
const text = clean(value);
|
|
14840
|
+
return /^[a-zA-Z0-9_.-]{1,128}$/.test(text) ? text : undefined;
|
|
14841
|
+
};
|
|
14842
|
+
const cause = source === "transport" && object.cause !== null && typeof object.cause === "object" ? object.cause : {};
|
|
14843
|
+
const message = clean([
|
|
14844
|
+
typeof object.message === "string" ? object.message : "",
|
|
14845
|
+
typeof cause.message === "string" ? cause.message : ""
|
|
14846
|
+
].filter(Boolean).join("; "));
|
|
14847
|
+
const code = identifier(object.code ?? cause.code);
|
|
14848
|
+
const type = identifier(source === "transport" ? object.name ?? object.type : object.type);
|
|
14849
|
+
return { source, message: message || fallback, ...code ? { code } : {}, ...type ? { type } : {} };
|
|
14850
|
+
}
|
|
14851
|
+
function upstreamErrorDiagnostic(value, fallback, redact) {
|
|
14852
|
+
const object = value !== null && typeof value === "object" ? value : {};
|
|
14853
|
+
return errorDiagnostic(object.response?.error ?? object.error ?? object, "upstream", fallback, redact);
|
|
14854
|
+
}
|
|
14855
|
+
|
|
14826
14856
|
// plugins/chatgpt-oauth/server/codex-protocol.ts
|
|
14827
14857
|
class CodexProtocolError extends Error {
|
|
14828
14858
|
kind;
|
|
14829
14859
|
reason;
|
|
14830
|
-
|
|
14860
|
+
diagnostic;
|
|
14861
|
+
constructor(kind, message, reason, diagnostic) {
|
|
14831
14862
|
super(message);
|
|
14832
14863
|
this.name = "CodexProtocolError";
|
|
14833
14864
|
this.kind = kind;
|
|
14834
14865
|
this.reason = reason;
|
|
14866
|
+
this.diagnostic = diagnostic;
|
|
14835
14867
|
}
|
|
14836
14868
|
}
|
|
14837
14869
|
var UNSUPPORTED_RESPONSES_FIELDS = [
|
|
@@ -15349,9 +15381,11 @@ class CodexResponseProcessor {
|
|
|
15349
15381
|
toolIndex = 0;
|
|
15350
15382
|
outputOrder = 0;
|
|
15351
15383
|
sawDone = false;
|
|
15384
|
+
redactDiagnostic;
|
|
15352
15385
|
constructor(options = {}) {
|
|
15353
15386
|
this.includeUsage = options.includeUsage ?? (options.request ? streamIncludesUsage(options.request) : false);
|
|
15354
15387
|
this.target = options.target ?? "chat";
|
|
15388
|
+
this.redactDiagnostic = options.redactDiagnostic;
|
|
15355
15389
|
}
|
|
15356
15390
|
validateOutputItem(item) {
|
|
15357
15391
|
if (this.target === "responses")
|
|
@@ -15456,18 +15490,18 @@ class CodexResponseProcessor {
|
|
|
15456
15490
|
return [];
|
|
15457
15491
|
}
|
|
15458
15492
|
if (type === "response.failed" || data.response?.status === "failed")
|
|
15459
|
-
throw new CodexProtocolError("failed", "Codex response failed");
|
|
15493
|
+
throw new CodexProtocolError("failed", "Codex response failed", undefined, upstreamErrorDiagnostic(data, "Codex response failed", this.redactDiagnostic));
|
|
15460
15494
|
if (this.sawDone && !this.terminal)
|
|
15461
15495
|
throw new CodexProtocolError("incomplete", "Codex emitted an event after [DONE] without a terminal response");
|
|
15462
15496
|
if (this.terminal) {
|
|
15463
15497
|
if (type === "error" || type === "response.failed")
|
|
15464
|
-
throw new CodexProtocolError("failed", "Codex response failed after terminal event");
|
|
15498
|
+
throw new CodexProtocolError("failed", "Codex response failed after terminal event", undefined, upstreamErrorDiagnostic(data, "Codex response failed after terminal event", this.redactDiagnostic));
|
|
15465
15499
|
if (type === "response.completed" || type === "response.incomplete")
|
|
15466
15500
|
return [];
|
|
15467
15501
|
return [];
|
|
15468
15502
|
}
|
|
15469
15503
|
if (type === "error")
|
|
15470
|
-
throw new CodexProtocolError("failed", "Codex response contained an error event");
|
|
15504
|
+
throw new CodexProtocolError("failed", "Codex response contained an error event", undefined, upstreamErrorDiagnostic(data, "Codex response contained an error event", this.redactDiagnostic));
|
|
15471
15505
|
if (type === "response.created" || type === "response.in_progress") {
|
|
15472
15506
|
const response = data.response ?? {};
|
|
15473
15507
|
this.responseId ||= String(response.id ?? "");
|
|
@@ -15861,10 +15895,10 @@ function responseHeaders(response, contentType) {
|
|
|
15861
15895
|
headers.set("content-type", contentType);
|
|
15862
15896
|
return headers;
|
|
15863
15897
|
}
|
|
15864
|
-
function
|
|
15865
|
-
return
|
|
15898
|
+
function errorBody(error, fallbackCode = "upstream_error") {
|
|
15899
|
+
return { message: error?.message ?? "Upstream response could not be adapted", type: error?.type ?? "upstream_error", code: error?.code ?? fallbackCode };
|
|
15866
15900
|
}
|
|
15867
|
-
function completionFromError(error) {
|
|
15901
|
+
function completionFromError(error, redact) {
|
|
15868
15902
|
if (error instanceof CodexProtocolError) {
|
|
15869
15903
|
if (error.kind === "cancelled")
|
|
15870
15904
|
return { status: "cancelled" };
|
|
@@ -15872,12 +15906,54 @@ function completionFromError(error) {
|
|
|
15872
15906
|
return { status: "incomplete", code: "incomplete" };
|
|
15873
15907
|
if (error.kind === "unexpected_eof")
|
|
15874
15908
|
return { status: "failed", code: "unexpected_eof" };
|
|
15875
|
-
return { status: "failed", code: error.kind
|
|
15909
|
+
return { status: "failed", code: error.kind, ...error.diagnostic ? {
|
|
15910
|
+
error: errorDiagnostic(error.diagnostic, error.diagnostic.source, error.message, redact)
|
|
15911
|
+
} : {} };
|
|
15876
15912
|
}
|
|
15877
15913
|
if (error instanceof CodexModelsError) {
|
|
15878
15914
|
return error.kind === "aborted" ? { status: "cancelled" } : { status: "failed", code: error.kind };
|
|
15879
15915
|
}
|
|
15880
|
-
return { status: "failed", code: "body_error" };
|
|
15916
|
+
return { status: "failed", code: "body_error", error: errorDiagnostic(error, "transport", "Upstream response body could not be read", redact) };
|
|
15917
|
+
}
|
|
15918
|
+
async function readHttpError(response, context) {
|
|
15919
|
+
if (!response.body)
|
|
15920
|
+
return { status: "failed", code: "upstream_http_error" };
|
|
15921
|
+
const reader = response.body.getReader();
|
|
15922
|
+
const decoder = new TextDecoder;
|
|
15923
|
+
const signal = AbortSignal.any([context.signal, AbortSignal.timeout(1000)]);
|
|
15924
|
+
let text = "";
|
|
15925
|
+
let bytes = 0;
|
|
15926
|
+
try {
|
|
15927
|
+
for (;; ) {
|
|
15928
|
+
const next = await readWithSignal(reader, signal);
|
|
15929
|
+
if (next.done)
|
|
15930
|
+
break;
|
|
15931
|
+
bytes += next.value?.byteLength ?? 0;
|
|
15932
|
+
if (bytes > MAX_DISCARD_BYTES) {
|
|
15933
|
+
reader.cancel("body_limit").catch(() => {
|
|
15934
|
+
return;
|
|
15935
|
+
});
|
|
15936
|
+
return { status: "failed", code: "body_limit" };
|
|
15937
|
+
}
|
|
15938
|
+
text += decoder.decode(next.value, { stream: true });
|
|
15939
|
+
}
|
|
15940
|
+
const body = JSON.parse(text + decoder.decode());
|
|
15941
|
+
const error = body?.error;
|
|
15942
|
+
if (error && typeof error === "object" && !Array.isArray(error)) {
|
|
15943
|
+
return { status: "failed", code: "upstream_http_error", error: errorDiagnostic(error, "upstream", "Upstream returned an HTTP error", context.redactDiagnostic) };
|
|
15944
|
+
}
|
|
15945
|
+
} catch (error) {
|
|
15946
|
+
reader.cancel("error capture stopped").catch(() => {
|
|
15947
|
+
return;
|
|
15948
|
+
});
|
|
15949
|
+
if (context.signal.aborted)
|
|
15950
|
+
return { status: "cancelled" };
|
|
15951
|
+
} finally {
|
|
15952
|
+
try {
|
|
15953
|
+
reader.releaseLock();
|
|
15954
|
+
} catch {}
|
|
15955
|
+
}
|
|
15956
|
+
return { status: "failed", code: "upstream_http_error" };
|
|
15881
15957
|
}
|
|
15882
15958
|
function joinCompletion(upstream, body, signal) {
|
|
15883
15959
|
const safe = (promise) => promise.catch(() => ({ status: "failed", code: "upstream_completion" }));
|
|
@@ -15995,7 +16071,7 @@ function serialize(event) {
|
|
|
15995
16071
|
|
|
15996
16072
|
`;
|
|
15997
16073
|
}
|
|
15998
|
-
function protocolStreamBody(source, target, includeUsage, signal) {
|
|
16074
|
+
function protocolStreamBody(source, target, includeUsage, signal, redact) {
|
|
15999
16075
|
const protocolController = new AbortController;
|
|
16000
16076
|
const onAbort = () => protocolController.abort(signal.reason ?? "cancelled");
|
|
16001
16077
|
if (signal.aborted)
|
|
@@ -16013,7 +16089,7 @@ function protocolStreamBody(source, target, includeUsage, signal) {
|
|
|
16013
16089
|
const completion = new Promise((resolve) => {
|
|
16014
16090
|
resolveCompletion = resolve;
|
|
16015
16091
|
});
|
|
16016
|
-
const processor = new CodexResponseProcessor({ target, includeUsage });
|
|
16092
|
+
const processor = new CodexResponseProcessor({ target, includeUsage, redactDiagnostic: redact });
|
|
16017
16093
|
let terminalOutcome;
|
|
16018
16094
|
const events = parseCodexSSE(source, { signal: protocolController.signal });
|
|
16019
16095
|
const iterator = async function* () {
|
|
@@ -16040,8 +16116,18 @@ function protocolStreamBody(source, target, includeUsage, signal) {
|
|
|
16040
16116
|
`;
|
|
16041
16117
|
settle(outcome);
|
|
16042
16118
|
} catch (error) {
|
|
16043
|
-
const outcome = completionFromError(error);
|
|
16119
|
+
const outcome = completionFromError(error, redact);
|
|
16044
16120
|
settle(outcome.status === "cancelled" ? terminalOutcome ?? outcome : outcome);
|
|
16121
|
+
if (outcome.status === "failed" && outcome.error) {
|
|
16122
|
+
const safe = errorBody(outcome.error, outcome.code);
|
|
16123
|
+
yield target === "responses" ? `event: error
|
|
16124
|
+
data: ${JSON.stringify({ type: "error", code: safe.code, message: safe.message, param: null, error: safe })}
|
|
16125
|
+
|
|
16126
|
+
` : `data: ${JSON.stringify({ error: safe })}
|
|
16127
|
+
|
|
16128
|
+
`;
|
|
16129
|
+
return;
|
|
16130
|
+
}
|
|
16045
16131
|
throw error;
|
|
16046
16132
|
} finally {
|
|
16047
16133
|
signal.removeEventListener("abort", onAbort);
|
|
@@ -16152,8 +16238,8 @@ class ChatgptOauthAdapter {
|
|
|
16152
16238
|
current.adaptedResponses.add(response);
|
|
16153
16239
|
return response;
|
|
16154
16240
|
};
|
|
16155
|
-
const errorResponse = (status, completion) => {
|
|
16156
|
-
const response = mark(new Response(
|
|
16241
|
+
const errorResponse = (status, completion, error) => {
|
|
16242
|
+
const response = mark(new Response(JSON.stringify({ error: errorBody(error) }), {
|
|
16157
16243
|
status,
|
|
16158
16244
|
statusText: result.response.statusText,
|
|
16159
16245
|
headers: responseHeaders(result.response, "application/json; charset=utf-8")
|
|
@@ -16162,8 +16248,8 @@ class ChatgptOauthAdapter {
|
|
|
16162
16248
|
return { response, completion };
|
|
16163
16249
|
};
|
|
16164
16250
|
if (!result.response.ok) {
|
|
16165
|
-
const
|
|
16166
|
-
return errorResponse(result.response.status, joinCompletion(result.completion,
|
|
16251
|
+
const failure = await readHttpError(result.response, context);
|
|
16252
|
+
return errorResponse(result.response.status, joinCompletion(result.completion, Promise.resolve(failure), context.signal), "error" in failure ? failure.error : undefined);
|
|
16167
16253
|
}
|
|
16168
16254
|
if (state.target === "models") {
|
|
16169
16255
|
if (!isJsonContentType(result.response)) {
|
|
@@ -16188,7 +16274,8 @@ class ChatgptOauthAdapter {
|
|
|
16188
16274
|
completion.then(cleanup, cleanup);
|
|
16189
16275
|
return { response, completion };
|
|
16190
16276
|
} catch (error) {
|
|
16191
|
-
|
|
16277
|
+
const failure = completionFromError(error, context.redactDiagnostic);
|
|
16278
|
+
return errorResponse(502, joinCompletion(result.completion, Promise.resolve(failure), context.signal), "error" in failure ? failure.error : undefined);
|
|
16192
16279
|
}
|
|
16193
16280
|
}
|
|
16194
16281
|
const contentType = result.response.headers.get("content-type");
|
|
@@ -16199,7 +16286,7 @@ class ChatgptOauthAdapter {
|
|
|
16199
16286
|
return errorResponse(502, joinCompletion(result.completion, bodyCompletion, context.signal));
|
|
16200
16287
|
}
|
|
16201
16288
|
if (state.stream) {
|
|
16202
|
-
const converted = protocolStreamBody(result.response.body, state.target, state.includeUsage, context.signal);
|
|
16289
|
+
const converted = protocolStreamBody(result.response.body, state.target, state.includeUsage, context.signal, context.redactDiagnostic);
|
|
16203
16290
|
const streamCompletion = joinCompletion(result.completion, converted.completion, context.signal);
|
|
16204
16291
|
streamCompletion.then(cleanup, cleanup);
|
|
16205
16292
|
return {
|
|
@@ -16211,7 +16298,8 @@ class ChatgptOauthAdapter {
|
|
|
16211
16298
|
const stateResult = await consumeCodexResponse(result.response.body, {
|
|
16212
16299
|
signal: context.signal,
|
|
16213
16300
|
request: { stream_options: { include_usage: state.includeUsage } },
|
|
16214
|
-
target: state.target
|
|
16301
|
+
target: state.target,
|
|
16302
|
+
redactDiagnostic: context.redactDiagnostic
|
|
16215
16303
|
});
|
|
16216
16304
|
const body = state.target === "chat" ? responsesToChatCompletion(stateResult.response) : stateResult.response;
|
|
16217
16305
|
const protocolCompletion = Promise.resolve(stateResult.terminal === "completed" ? { status: "completed" } : { status: "incomplete", code: "incomplete" });
|
|
@@ -16219,9 +16307,9 @@ class ChatgptOauthAdapter {
|
|
|
16219
16307
|
nonStreamCompletion.then(cleanup, cleanup);
|
|
16220
16308
|
return { response: mark(new Response(JSON.stringify(body), { status: result.response.status, statusText: result.response.statusText, headers: responseHeaders(result.response, "application/json; charset=utf-8") })), completion: nonStreamCompletion };
|
|
16221
16309
|
} catch (error) {
|
|
16222
|
-
const failure = completionFromError(error);
|
|
16310
|
+
const failure = completionFromError(error, context.redactDiagnostic);
|
|
16223
16311
|
const failedCompletion = joinCompletion(result.completion, Promise.resolve(failure), context.signal);
|
|
16224
|
-
return errorResponse(502, failedCompletion);
|
|
16312
|
+
return errorResponse(502, failedCompletion, "error" in failure ? failure.error : undefined);
|
|
16225
16313
|
}
|
|
16226
16314
|
}
|
|
16227
16315
|
}
|
|
@@ -16252,4 +16340,4 @@ export {
|
|
|
16252
16340
|
server_default as default
|
|
16253
16341
|
};
|
|
16254
16342
|
|
|
16255
|
-
//# debugId=
|
|
16343
|
+
//# debugId=D19FB0DB9863C8D864756E2164756E21
|