@oh-my-pi/pi-ai 12.11.2 → 12.12.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-ai",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.12.0",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"@connectrpc/connect-node": "^2.1.1",
|
|
64
64
|
"@google/genai": "^1.41.0",
|
|
65
65
|
"@mistralai/mistralai": "^1.14.0",
|
|
66
|
-
"@oh-my-pi/pi-utils": "12.
|
|
66
|
+
"@oh-my-pi/pi-utils": "12.12.0",
|
|
67
67
|
"@sinclair/typebox": "^0.34.48",
|
|
68
68
|
"@smithy/node-http-handler": "^4.4.10",
|
|
69
69
|
"ajv": "^8.18.0",
|
|
@@ -387,6 +387,7 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
|
|
|
387
387
|
const websocketV2Enabled = isCodexWebSocketV2Enabled();
|
|
388
388
|
let websocketRetries = 0;
|
|
389
389
|
while (true) {
|
|
390
|
+
const websocketRequest = buildCodexWebSocketRequest(transformedBody, websocketState, websocketV2Enabled);
|
|
390
391
|
const websocketHeaders = createCodexHeaders(
|
|
391
392
|
requestHeaders,
|
|
392
393
|
accountId,
|
|
@@ -396,13 +397,14 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
|
|
|
396
397
|
websocketState,
|
|
397
398
|
websocketV2Enabled,
|
|
398
399
|
);
|
|
399
|
-
const websocketRequest = buildCodexWebSocketRequest(transformedBody, websocketState, websocketV2Enabled);
|
|
400
400
|
requestBodyForState = cloneRequestBody(transformedBody);
|
|
401
401
|
logCodexDebug("codex websocket request", {
|
|
402
402
|
url: toWebSocketUrl(url),
|
|
403
403
|
model: params.model,
|
|
404
404
|
reasoningEffort,
|
|
405
405
|
headers: redactHeaders(websocketHeaders),
|
|
406
|
+
sentTurnStateHeader: websocketHeaders.has(X_CODEX_TURN_STATE_HEADER),
|
|
407
|
+
sentModelsEtagHeader: websocketHeaders.has(X_MODELS_ETAG_HEADER),
|
|
406
408
|
requestType: websocketRequest.type,
|
|
407
409
|
retry: websocketRetries,
|
|
408
410
|
retryBudget: websocketRetryBudget,
|
|
@@ -467,6 +469,7 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
|
|
|
467
469
|
const blocks = output.content;
|
|
468
470
|
const blockIndex = () => blocks.length - 1;
|
|
469
471
|
let websocketStreamRetries = 0;
|
|
472
|
+
let sawTerminalEvent = false;
|
|
470
473
|
while (true) {
|
|
471
474
|
try {
|
|
472
475
|
for await (const rawEvent of eventStream) {
|
|
@@ -645,6 +648,7 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
|
|
|
645
648
|
}
|
|
646
649
|
}
|
|
647
650
|
} else if (eventType === "response.completed" || eventType === "response.done") {
|
|
651
|
+
sawTerminalEvent = true;
|
|
648
652
|
const response = (
|
|
649
653
|
rawEvent as {
|
|
650
654
|
response?: {
|
|
@@ -712,6 +716,11 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
|
|
|
712
716
|
websocketStreamRetries += 1;
|
|
713
717
|
await abortableSleep(getCodexWebSocketRetryDelayMs(websocketStreamRetries), options?.signal);
|
|
714
718
|
const websocketV2Enabled = isCodexWebSocketV2Enabled();
|
|
719
|
+
const websocketRequest = buildCodexWebSocketRequest(
|
|
720
|
+
transformedBody,
|
|
721
|
+
websocketState,
|
|
722
|
+
websocketV2Enabled,
|
|
723
|
+
);
|
|
715
724
|
const websocketHeaders = createCodexHeaders(
|
|
716
725
|
requestHeaders,
|
|
717
726
|
accountId,
|
|
@@ -721,11 +730,6 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
|
|
|
721
730
|
websocketState,
|
|
722
731
|
websocketV2Enabled,
|
|
723
732
|
);
|
|
724
|
-
const websocketRequest = buildCodexWebSocketRequest(
|
|
725
|
-
transformedBody,
|
|
726
|
-
websocketState,
|
|
727
|
-
websocketV2Enabled,
|
|
728
|
-
);
|
|
729
733
|
requestBodyForState = cloneRequestBody(transformedBody);
|
|
730
734
|
eventStream = await openCodexWebSocketEventStream(
|
|
731
735
|
toWebSocketUrl(url),
|
|
@@ -761,6 +765,21 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
|
|
|
761
765
|
throw new Error("Request was aborted");
|
|
762
766
|
}
|
|
763
767
|
|
|
768
|
+
if (!sawTerminalEvent) {
|
|
769
|
+
if (usingWebsocket && websocketState) {
|
|
770
|
+
resetCodexWebSocketAppendState(websocketState);
|
|
771
|
+
resetCodexSessionMetadata(websocketState);
|
|
772
|
+
}
|
|
773
|
+
logCodexDebug("codex stream ended unexpectedly", {
|
|
774
|
+
transport: usingWebsocket ? "websocket" : "sse",
|
|
775
|
+
terminalEventSeen: sawTerminalEvent,
|
|
776
|
+
unexpectedStreamEnd: true,
|
|
777
|
+
sentTurnStateHeader: Boolean(websocketState?.turnState),
|
|
778
|
+
sentModelsEtagHeader: Boolean(websocketState?.modelsEtag),
|
|
779
|
+
});
|
|
780
|
+
throw new Error("Codex stream ended before terminal completion event");
|
|
781
|
+
}
|
|
782
|
+
|
|
764
783
|
if (output.stopReason === "aborted" || output.stopReason === "error") {
|
|
765
784
|
throw new Error("Codex response failed");
|
|
766
785
|
}
|
|
@@ -773,6 +792,7 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
|
|
|
773
792
|
for (const block of output.content) delete (block as { index?: number }).index;
|
|
774
793
|
if (usingWebsocket && websocketState) {
|
|
775
794
|
resetCodexWebSocketAppendState(websocketState);
|
|
795
|
+
resetCodexSessionMetadata(websocketState);
|
|
776
796
|
}
|
|
777
797
|
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
778
798
|
output.errorMessage = formatErrorMessageWithRetryAfter(error);
|
|
@@ -866,6 +886,12 @@ function resetCodexWebSocketAppendState(state: CodexWebSocketSessionState): void
|
|
|
866
886
|
state.lastResponseId = undefined;
|
|
867
887
|
}
|
|
868
888
|
|
|
889
|
+
function resetCodexSessionMetadata(state: CodexWebSocketSessionState): void {
|
|
890
|
+
state.turnState = undefined;
|
|
891
|
+
state.modelsEtag = undefined;
|
|
892
|
+
state.reasoningIncluded = undefined;
|
|
893
|
+
}
|
|
894
|
+
|
|
869
895
|
function recordCodexWebSocketFailure(state: CodexWebSocketSessionState, activateFallback: boolean): void {
|
|
870
896
|
resetCodexWebSocketAppendState(state);
|
|
871
897
|
state.connection?.close("fallback");
|
|
@@ -970,6 +996,14 @@ function buildCodexWebSocketRequest(
|
|
|
970
996
|
input: appendInput,
|
|
971
997
|
};
|
|
972
998
|
}
|
|
999
|
+
if (state?.canAppend) {
|
|
1000
|
+
logCodexDebug("codex websocket append reset", {
|
|
1001
|
+
hadTurnStateHeader: Boolean(state.turnState),
|
|
1002
|
+
hadModelsEtagHeader: Boolean(state.modelsEtag),
|
|
1003
|
+
});
|
|
1004
|
+
resetCodexWebSocketAppendState(state);
|
|
1005
|
+
resetCodexSessionMetadata(state);
|
|
1006
|
+
}
|
|
973
1007
|
return {
|
|
974
1008
|
type: "response.create",
|
|
975
1009
|
...requestBody,
|
|
@@ -1245,6 +1279,8 @@ async function openCodexSseEventStream(
|
|
|
1245
1279
|
url,
|
|
1246
1280
|
model: body.model,
|
|
1247
1281
|
headers: redactHeaders(headers),
|
|
1282
|
+
sentTurnStateHeader: headers.has(X_CODEX_TURN_STATE_HEADER),
|
|
1283
|
+
sentModelsEtagHeader: headers.has(X_MODELS_ETAG_HEADER),
|
|
1248
1284
|
});
|
|
1249
1285
|
const response = await fetchWithRetry(
|
|
1250
1286
|
url,
|