@opengeni/codex 0.2.11 → 0.2.13
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/fetch.d.ts +4 -4
- package/dist/index.js +24 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/fetch.ts +20 -23
- package/src/mcp-sanitize.ts +12 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/codex",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"description": "ChatGPT/Codex subscription auth + transport: device-code login, token refresh, and the Responses-backend fetch. Pure HTTP + transforms; no database dependency.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
package/src/fetch.ts
CHANGED
|
@@ -510,17 +510,12 @@ export function codexSubscriptionFetch(base: FetchLike = globalThis.fetch): Fetc
|
|
|
510
510
|
authenticationAttempt === 0 ? requestId : `${requestId}:auth-${authenticationAttempt}`,
|
|
511
511
|
);
|
|
512
512
|
if (process.env.CODEX_DEBUG) {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
console.error(
|
|
522
|
-
`[codex-debug] POST ${rewritten} stream=${callerWantsStream} bodyKeys=[${keys.join(",")}]`,
|
|
523
|
-
);
|
|
513
|
+
console.error("[codex-debug] request dispatched", {
|
|
514
|
+
method: "POST",
|
|
515
|
+
origin: "codex-subscription",
|
|
516
|
+
route: "codex_responses",
|
|
517
|
+
stream: callerWantsStream,
|
|
518
|
+
});
|
|
524
519
|
}
|
|
525
520
|
let res: Response;
|
|
526
521
|
transportAttempt += 1;
|
|
@@ -587,12 +582,13 @@ export function codexSubscriptionFetch(base: FetchLike = globalThis.fetch): Fetc
|
|
|
587
582
|
ctx.onUsageHeaders?.(usage);
|
|
588
583
|
}
|
|
589
584
|
if (process.env.CODEX_DEBUG && !res.ok) {
|
|
590
|
-
// Never log provider bodies: they can contain
|
|
591
|
-
// account
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
585
|
+
// Never log provider bodies, identifiers, or headers: they can contain
|
|
586
|
+
// request-derived or account content. A bounded status is sufficient.
|
|
587
|
+
console.error("[codex-debug] request failed", {
|
|
588
|
+
origin: "codex-subscription",
|
|
589
|
+
route: "codex_responses",
|
|
590
|
+
status: res.status,
|
|
591
|
+
});
|
|
596
592
|
}
|
|
597
593
|
// The codex backend leaves the terminal event's response.output empty and
|
|
598
594
|
// delivers the assistant items via output_item.done events instead. The
|
|
@@ -1016,9 +1012,9 @@ function codexSseFailureProjection(
|
|
|
1016
1012
|
* A provider terminal carried inside an accepted HTTP-200 stream. The OpenAI
|
|
1017
1013
|
* SDK cannot turn that late terminal into a non-2xx APIError because headers
|
|
1018
1014
|
* have already been accepted, so the body transform throws this equivalent
|
|
1019
|
-
* bounded shape. Provider-supplied message/param text
|
|
1020
|
-
*
|
|
1021
|
-
*
|
|
1015
|
+
* bounded shape. Provider-supplied message/param text remains exact within the
|
|
1016
|
+
* explicit terminal-field byte contract; retry classification is additive and
|
|
1017
|
+
* never substitutes for the source diagnostic.
|
|
1022
1018
|
*/
|
|
1023
1019
|
export class CodexStreamingTerminalError extends Error {
|
|
1024
1020
|
readonly status: number;
|
|
@@ -1030,8 +1026,8 @@ export class CodexStreamingTerminalError extends Error {
|
|
|
1030
1026
|
readonly headers: Headers;
|
|
1031
1027
|
readonly error: Record<string, unknown>;
|
|
1032
1028
|
|
|
1033
|
-
constructor(projection: CodexSseFailureProjection
|
|
1034
|
-
super(
|
|
1029
|
+
constructor(projection: CodexSseFailureProjection) {
|
|
1030
|
+
super(projection.error.message);
|
|
1035
1031
|
this.name = "CodexStreamingTerminalError";
|
|
1036
1032
|
this.status = projection.status;
|
|
1037
1033
|
this.code = projection.error.code;
|
|
@@ -1049,6 +1045,8 @@ export class CodexStreamingTerminalError extends Error {
|
|
|
1049
1045
|
this.error = {
|
|
1050
1046
|
type: projection.error.type,
|
|
1051
1047
|
code: projection.error.code,
|
|
1048
|
+
message: projection.error.message,
|
|
1049
|
+
...(projection.error.param ? { param: projection.error.param } : {}),
|
|
1052
1050
|
...(projection.error.event_type ? { event_type: projection.error.event_type } : {}),
|
|
1053
1051
|
...(projection.error.response_id ? { response_id: projection.error.response_id } : {}),
|
|
1054
1052
|
...(projection.error.response_status
|
|
@@ -1072,7 +1070,6 @@ function codexSseFailureError(
|
|
|
1072
1070
|
): CodexStreamingTerminalError {
|
|
1073
1071
|
return new CodexStreamingTerminalError(
|
|
1074
1072
|
codexSseFailureProjection(source, rawError, fallbackCode, publicMessage, metadata),
|
|
1075
|
-
publicMessage,
|
|
1076
1073
|
);
|
|
1077
1074
|
}
|
|
1078
1075
|
|
package/src/mcp-sanitize.ts
CHANGED
|
@@ -169,8 +169,10 @@ function sanitizeToolsInRpcMessage(
|
|
|
169
169
|
* leaving the original content untouched.
|
|
170
170
|
*
|
|
171
171
|
* No-op when there is no `structuredContent` — so a tools/list response (or any
|
|
172
|
-
* result without it) passes through unchanged.
|
|
173
|
-
*
|
|
172
|
+
* result without it) passes through unchanged. Valid object payloads stay intact
|
|
173
|
+
* for protocol-aware consumers. Invalid optional values (such as null) are removed
|
|
174
|
+
* after any useful value is copied into `content`, because the MCP client validates
|
|
175
|
+
* this field as an object before the tool can return. Runs after the outputSchema drop.
|
|
174
176
|
*/
|
|
175
177
|
function inlineStructuredContentInRpcMessage(message: unknown): void {
|
|
176
178
|
if (!message || typeof message !== "object") {
|
|
@@ -185,13 +187,15 @@ function inlineStructuredContentInRpcMessage(message: unknown): void {
|
|
|
185
187
|
return;
|
|
186
188
|
}
|
|
187
189
|
const structured = record.structuredContent;
|
|
188
|
-
if (structured
|
|
189
|
-
|
|
190
|
+
if (structured !== undefined && structured !== null) {
|
|
191
|
+
const text = typeof structured === "string" ? structured : JSON.stringify(structured);
|
|
192
|
+
const content = Array.isArray(record.content) ? [...record.content] : [];
|
|
193
|
+
content.push({ type: "text", text });
|
|
194
|
+
record.content = content;
|
|
195
|
+
}
|
|
196
|
+
if (typeof structured !== "object" || structured === null || Array.isArray(structured)) {
|
|
197
|
+
delete record.structuredContent;
|
|
190
198
|
}
|
|
191
|
-
const text = typeof structured === "string" ? structured : JSON.stringify(structured);
|
|
192
|
-
const content = Array.isArray(record.content) ? [...record.content] : [];
|
|
193
|
-
content.push({ type: "text", text });
|
|
194
|
-
record.content = content;
|
|
195
199
|
}
|
|
196
200
|
|
|
197
201
|
/** Sanitize a single JSON body (application/json MCP response). */
|