@openclaw/ai 2026.9.5 → 2026.9.6
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/{anthropic-COtDvgtt.mjs → anthropic-DZQ_7gD1.mjs} +35 -35
- package/dist/{anthropic-payload-policy-5Erq1Nzy.d.mts → anthropic-payload-policy-DyfwikYJ.d.mts} +4 -4
- package/dist/{anthropic-stream-reducer-BvdYYWL8.mjs → anthropic-stream-reducer-D6ZI1wwj.mjs} +32 -16
- package/dist/{api-registry-Ba2Cv-ut.d.mts → api-registry-C2T3lTV7.d.mts} +2 -2
- package/dist/{assistant-output-BsEkB-vU.mjs → assistant-output-DM1JBNs1.mjs} +1 -1
- package/dist/{azure-openai-responses-YrgnD583.mjs → azure-openai-responses-DS86GYzq.mjs} +5 -5
- package/dist/{base64-BQOzsvUH.mjs → base64-CPmadnUf.mjs} +8 -8
- package/dist/{diagnostics-Dm4bisWG.mjs → diagnostics-CH8j2wIG.mjs} +55 -10
- package/dist/{diagnostics-CPeq9F7y.mjs → diagnostics-DzrF1h4J.mjs} +18 -1
- package/dist/diagnostics.d.mts +11 -5
- package/dist/diagnostics.mjs +4 -4
- package/dist/event-stream-C0nsgbj2.d.mts +1 -0
- package/dist/{event-stream-CCoa-qSI.d.mts → event-stream-CjnIZZst.d.mts} +1 -1
- package/dist/event-stream.d.mts +2 -2
- package/dist/{google-BuhpRO9r.mjs → google-BZJFjhuC.mjs} +5 -5
- package/dist/{google-messages-CyWnYlh0.mjs → google-messages-DB7GKkDk.mjs} +3 -3
- package/dist/{google-shared-BT5ZeNer.mjs → google-shared-Bok4I6zB.mjs} +5 -5
- package/dist/{google-vertex-C7EplRvt.mjs → google-vertex-3eVNR2qW.mjs} +4 -4
- package/dist/{host-FZ1RA_qD.d.mts → host-DH-Z-LDb.d.mts} +3 -3
- package/dist/{host-policy-DUnXSx0I.mjs → host-policy-DZO3oPPk.mjs} +1 -1
- package/dist/{host-B4MeUNBc.mjs → host-yTvBrYM2.mjs} +41 -7
- package/dist/{index-DaF2QbwS.d.mts → index-C25RT6bP.d.mts} +36 -8
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +4 -4
- package/dist/internal/anthropic.d.mts +12 -8
- package/dist/internal/anthropic.mjs +5 -5
- package/dist/internal/openai-completions-compat.d.mts +1 -1
- package/dist/internal/openai-completions-compat.mjs +1 -1
- package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
- package/dist/internal/openai-responses-payload-policy.mjs +1 -1
- package/dist/internal/openai.d.mts +22 -8
- package/dist/internal/openai.mjs +11 -10
- package/dist/internal/runtime.d.mts +6 -6
- package/dist/internal/runtime.mjs +5 -5
- package/dist/internal/shared.d.mts +5 -4
- package/dist/internal/shared.mjs +4 -4
- package/dist/internal/tool-schema.d.mts +1 -1
- package/dist/internal/tool-schema.mjs +1 -1
- package/dist/{mistral-moA-mbwl.mjs → mistral-C_13dVBn.mjs} +5 -5
- package/dist/{model-transport-url-DKocrEsb.d.mts → model-transport-url-C5f59L3Y.d.mts} +1 -1
- package/dist/{openai-chatgpt-responses-DWID3EFO.mjs → openai-chatgpt-responses-sTxPl4zM.mjs} +107 -84
- package/dist/{openai-completions-DJ1Vm-CD.mjs → openai-completions-BO6D_hrB.mjs} +10 -10
- package/dist/{openai-completions-compat-CkwdxTZx.mjs → openai-completions-compat-CUollwl6.mjs} +1 -1
- package/dist/{openai-completions-compat-JE7gqxb9.d.mts → openai-completions-compat-DfJG1wSO.d.mts} +3 -3
- package/dist/{openai-completions-stream-Bu98b0Hv.mjs → openai-completions-stream-BpuJ0ZOA.mjs} +38 -25
- package/dist/{openai-prompt-cache-CJ_xEevu.d.mts → openai-prompt-cache-C4RHdN4n.d.mts} +2 -2
- package/dist/{openai-prompt-cache-1wfaIszn.mjs → openai-prompt-cache-CjV_2IRI.mjs} +1 -1
- package/dist/{openai-provider-client-DPo0Hmak.mjs → openai-provider-client-BP8J1aeg.mjs} +2 -2
- package/dist/{openai-reasoning-effort-NlFZmfEu.mjs → openai-reasoning-effort-ash8dPrd.mjs} +12 -4
- package/dist/{openai-responses-BejZzQCP.mjs → openai-responses-BJ_IEoMU.mjs} +7 -7
- package/dist/{openai-responses-compaction-window-D6P5oZP5.mjs → openai-responses-compaction-window-BiNCT0bS.mjs} +3 -3
- package/dist/{openai-responses-contracts-Dflvrfa8.d.mts → openai-responses-contracts-B1ENJFpI.d.mts} +4 -4
- package/dist/{openai-responses-prompt-observer-internal-C15_-OwV.mjs → openai-responses-prompt-observer-internal-DPHWgbBH.mjs} +14 -11
- package/dist/openai-responses-request-lifecycle-DFuyO1pQ.mjs +36 -0
- package/dist/{openai-responses-shared-CwsziD_m.mjs → openai-responses-shared-DvSqtJ6_.mjs} +481 -410
- package/dist/{openai-responses-terminal-usage-Dl3J6zrf.d.mts → openai-responses-terminal-usage-BNFbvY9f.d.mts} +2 -2
- package/dist/{openai-tool-schema-BO8rwyAD.mjs → openai-tool-schema-D4BMcj2D.mjs} +171 -95
- package/dist/{openai-transport-params-DQeuAvBl.mjs → openai-transport-params-DZKOTSfH.mjs} +9 -9
- package/dist/{positive-integer-DtjCkbue.mjs → positive-integer-BiUxrd71.mjs} +1 -1
- package/dist/{provider-error-DDqw9Qda.mjs → provider-error-CRhW7lkJ.mjs} +40 -7
- package/dist/{provider-error-CzNw4BWX.d.mts → provider-error-xumb1V3F.d.mts} +3 -1
- package/dist/{provider-options-DprLsWh9.d.mts → provider-options-DZYq53lj.d.mts} +6 -4
- package/dist/{provider-replay-context-CnUSOwhr.mjs → provider-replay-context-DPr3w20a.mjs} +1 -1
- package/dist/{provider-transcript-transform-BsRAhuWJ.mjs → provider-transcript-transform-BTocjCRs.mjs} +1 -1
- package/dist/{provider-transport-turn-state-CkGToCD2.mjs → provider-transport-turn-state-lrXEFkYr.mjs} +1 -1
- package/dist/{provider-types-CAKRC7N5.d.mts → provider-types-w1rEqrGP.d.mts} +3 -3
- package/dist/provider-types.d.mts +6 -6
- package/dist/providers.d.mts +2 -2
- package/dist/providers.mjs +10 -10
- package/dist/{reasoning-tag-text-partitioner-Dy9IO8Dc.mjs → reasoning-tag-text-partitioner-Di38crhI.mjs} +154 -35
- package/dist/{simple-options-C6cFWj_f.mjs → simple-options-np1XPuhm.mjs} +2 -2
- package/dist/{src-DeKjbE8I.mjs → src-DwGYYyZp.mjs} +15 -6
- package/dist/{stream-first-event-timeout-C9ZadkJW.mjs → stream-first-event-timeout-BeptfRL6.mjs} +1 -1
- package/dist/{transport-stream-shared-D-6FQSHm.mjs → transport-stream-shared-B5RioB_Q.mjs} +5 -13
- package/dist/{transport-stream-shared-BbUkFaHi.d.mts → transport-stream-shared-B7Z9oCYg.d.mts} +5 -5
- package/dist/{transport-utils-1cyq5Y7x.mjs → transport-utils-03Qi0CN2.mjs} +3 -3
- package/dist/transports.d.mts +11 -11
- package/dist/transports.mjs +70 -45
- package/dist/types-DTvddOfm.d.mts +1 -0
- package/dist/{types-4_uVs5WH.d.mts → types-qZFbaDbK.d.mts} +2 -0
- package/dist/types.d.mts +6 -6
- package/dist/types.mjs +3 -3
- package/dist/{validation-Ctzu2DhF.d.mts → validation-DhQhmt6t.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/package.json +5 -5
- package/dist/event-stream-DmSCpi1T.d.mts +0 -1
- package/dist/types-DkJfb4W3.d.mts +0 -1
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import { t as appendAssistantMessageDiagnostic } from "./diagnostics-
|
|
1
|
+
import { o as readProviderRefusalReview, t as appendAssistantMessageDiagnostic } from "./diagnostics-DzrF1h4J.mjs";
|
|
2
2
|
import { r as appendAssistantThinking } from "./event-stream-D8PARQfL.mjs";
|
|
3
|
-
import { a as normalizeOptionalString } from "./string-coerce-fsri9iCu.mjs";
|
|
3
|
+
import { a as normalizeOptionalString, o as normalizeStringifiedOptionalString, s as readStringValue } from "./string-coerce-fsri9iCu.mjs";
|
|
4
4
|
import { o as isRecord } from "./record-coerce-DwRYMj3t.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { d as supportsOpenAITemperature } from "./openai-reasoning-effort-ash8dPrd.mjs";
|
|
6
|
+
import { M as calculateCost, _ as isImageWithMediaPayload, d as describeToolResultMediaPlaceholder, m as extractToolResultText, n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-yTvBrYM2.mjs";
|
|
7
7
|
import { t as truncateUtf16Safe } from "./utf16-slice-CvGodqok.mjs";
|
|
8
|
-
import { o as stableStringify } from "./provider-error-
|
|
9
|
-
import { a as resolveModelSseDebugMode, d as
|
|
10
|
-
import { o as redactSensitiveText } from "./transport-utils-
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
8
|
+
import { o as stableStringify } from "./provider-error-CRhW7lkJ.mjs";
|
|
9
|
+
import { a as resolveModelSseDebugMode, d as isResponsesProviderTool, g as resolveResponsesTerminalStopReason, h as readResponsesReasoningTokens, i as resolveModelPayloadDebugMode, l as ResponsesOutputIdentityError, m as mapResponsesTerminalUsage, r as emitModelTransportDebug, u as hasOnlyResponsesFunctionTools } from "./diagnostics-CH8j2wIG.mjs";
|
|
10
|
+
import { o as redactSensitiveText } from "./transport-utils-03Qi0CN2.mjs";
|
|
11
|
+
import { i as resolveOpenAICompletionsCompat } from "./openai-completions-compat-CUollwl6.mjs";
|
|
12
|
+
import { s as transformTransportMessages } from "./host-policy-DZO3oPPk.mjs";
|
|
13
|
+
import { m as stripSystemPromptCacheBoundary, v as sortPromptCacheToolsByName } from "./simple-options-np1XPuhm.mjs";
|
|
14
|
+
import { M as redactIdentifier, N as sha256Hex, b as createOpenAIProviderAcceptanceHook, d as prepareOpenAITools, h as resolveOpenAIRequestReasoning, u as resolveOpenAIStrictToolFlagWithDiagnostics, w as log, y as createModelStreamCooperativeScheduler } from "./openai-transport-params-DZKOTSfH.mjs";
|
|
15
|
+
import { E as parseStreamingJson, O as shortHash, _ as sanitizeTransportPayloadText, b as withProviderResponseHook, g as sanitizeNonEmptyTransportPayloadText, h as parseTerminalToolCallArguments, l as finalizeTransportStream, s as failTransportStream, t as IncompleteToolCallError, v as transportAbortError, w as createToolArgumentPreviewSchedule, x as parseJsonObjectPreservingUnsafeIntegers } from "./transport-stream-shared-B5RioB_Q.mjs";
|
|
16
|
+
import { n as providerReplayContextMatches, t as buildProviderReplayContext } from "./provider-replay-context-DPr3w20a.mjs";
|
|
16
17
|
import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
|
|
17
|
-
import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-
|
|
18
|
-
import { t as transformProviderMessages } from "./provider-transcript-transform-
|
|
19
|
-
import { a as resolveOpenAIProjectedToolsStrictToolFlag, f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-
|
|
18
|
+
import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-BeptfRL6.mjs";
|
|
19
|
+
import { t as transformProviderMessages } from "./provider-transcript-transform-BTocjCRs.mjs";
|
|
20
|
+
import { a as resolveOpenAIProjectedToolsStrictToolFlag, f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-D4BMcj2D.mjs";
|
|
20
21
|
import { a as OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE, c as OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE, f as RESPONSE_FAILED_NO_DETAILS_MESSAGE, o as OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY, p as isPreviousResponseRejection, s as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY } from "./openai-responses-contracts-DWrfMODE.mjs";
|
|
21
|
-
import { n as isOpenAIResponsesCompactionOutput, r as readOpenAIResponsesCompactionWindow } from "./openai-responses-compaction-window-
|
|
22
|
+
import { n as isOpenAIResponsesCompactionOutput, r as readOpenAIResponsesCompactionWindow } from "./openai-responses-compaction-window-BiNCT0bS.mjs";
|
|
22
23
|
import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
|
|
23
24
|
import { createHash, randomUUID } from "node:crypto";
|
|
24
25
|
//#region packages/ai/src/transports/openai-responses-replay.ts
|
|
@@ -877,257 +878,6 @@ function isProviderMessage(message) {
|
|
|
877
878
|
return message.role === "user" || message.role === "assistant" || message.role === "toolResult";
|
|
878
879
|
}
|
|
879
880
|
//#endregion
|
|
880
|
-
//#region packages/ai/src/transports/openai-responses-replay-internal.ts
|
|
881
|
-
function isAsyncIterable(value) {
|
|
882
|
-
return (typeof value === "object" && value !== null || typeof value === "function") && Symbol.asyncIterator in value;
|
|
883
|
-
}
|
|
884
|
-
function isInvalidEncryptedContentError(error) {
|
|
885
|
-
if (!error || typeof error !== "object") return false;
|
|
886
|
-
const record = error;
|
|
887
|
-
if (record.code === "invalid_encrypted_content" || record.code === "thinking_signature_invalid") return true;
|
|
888
|
-
const message = typeof record.message === "string" ? record.message.toLowerCase() : "";
|
|
889
|
-
return message.includes("invalid_encrypted_content") || message.includes("thinking_signature_invalid") || (record.status === 400 || record.status == null && /(?:^|[\s(])400(?:[\s):]|$)/.test(message)) && (message.includes("could not decrypt the provided encrypted_content") || message.includes("encrypted content") && (message.includes("could not be verified") || message.includes("could not be decrypted or parsed")));
|
|
890
|
-
}
|
|
891
|
-
function isOrphanedFunctionCallOutputError(error) {
|
|
892
|
-
if (!error || typeof error !== "object") return false;
|
|
893
|
-
const record = error;
|
|
894
|
-
const message = typeof record.message === "string" ? record.message : "";
|
|
895
|
-
return /No tool call found for function call output with call_id [A-Za-z0-9_-]+/.test(message);
|
|
896
|
-
}
|
|
897
|
-
function commitResponsesEncryptedContentAttempt(attempt, commit) {
|
|
898
|
-
if (attempt.kind === "compaction-stripped") commit(attempt.rejectedCompaction);
|
|
899
|
-
}
|
|
900
|
-
function stripResponsesRequestEncryptedReasoning(request) {
|
|
901
|
-
const stripped = stripEncryptedReasoningContentFields(request.input);
|
|
902
|
-
if (!stripped.changed) return request;
|
|
903
|
-
return {
|
|
904
|
-
...request,
|
|
905
|
-
input: stripped.value
|
|
906
|
-
};
|
|
907
|
-
}
|
|
908
|
-
function stripResponsesRequestCompaction(request) {
|
|
909
|
-
if (!Array.isArray(request.input)) return request;
|
|
910
|
-
const input = request.input.filter((item) => !(item !== null && typeof item === "object" && item.type === "compaction"));
|
|
911
|
-
return input.length === request.input.length ? request : {
|
|
912
|
-
...request,
|
|
913
|
-
input
|
|
914
|
-
};
|
|
915
|
-
}
|
|
916
|
-
function readOpenAIResponsesCompactionRejection(request) {
|
|
917
|
-
if (!Array.isArray(request.input)) return;
|
|
918
|
-
const item = request.input.find((candidate) => candidate !== null && typeof candidate === "object" && candidate.type === "compaction" && typeof candidate.encrypted_content === "string");
|
|
919
|
-
return item ? {
|
|
920
|
-
data: item.encrypted_content,
|
|
921
|
-
...typeof item.id === "string" ? { id: item.id } : {}
|
|
922
|
-
} : void 0;
|
|
923
|
-
}
|
|
924
|
-
async function resolveNextResponsesEncryptedContentAttempt(attempt, error, options) {
|
|
925
|
-
const orphanedFunctionOutput = isOrphanedFunctionCallOutputError(error);
|
|
926
|
-
if (!isInvalidEncryptedContentError(error) && !orphanedFunctionOutput || attempt.kind === "compaction-stripped") return;
|
|
927
|
-
if (!orphanedFunctionOutput && (attempt.kind === "initial" || attempt.kind === "continuation-rejected")) {
|
|
928
|
-
const reasoningStripped = stripResponsesRequestEncryptedReasoning(attempt.request);
|
|
929
|
-
if (reasoningStripped !== attempt.request) return {
|
|
930
|
-
kind: "reasoning-stripped",
|
|
931
|
-
request: reasoningStripped
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
|
-
const locallyStripped = stripResponsesRequestCompaction(attempt.request);
|
|
935
|
-
if (locallyStripped === attempt.request) return;
|
|
936
|
-
let compactionStripped = options?.buildFullHistoryRequest ? await options.buildFullHistoryRequest() : locallyStripped;
|
|
937
|
-
compactionStripped = stripResponsesRequestCompaction(compactionStripped);
|
|
938
|
-
if (attempt.kind === "reasoning-stripped") compactionStripped = stripResponsesRequestEncryptedReasoning(compactionStripped);
|
|
939
|
-
return {
|
|
940
|
-
kind: "compaction-stripped",
|
|
941
|
-
request: compactionStripped,
|
|
942
|
-
rejectedCompaction: readOpenAIResponsesCompactionRejection(attempt.request)
|
|
943
|
-
};
|
|
944
|
-
}
|
|
945
|
-
async function createResponsesStreamWithEncryptedContentRetry(params) {
|
|
946
|
-
const send = async (initialAttempt) => {
|
|
947
|
-
let attempt = initialAttempt;
|
|
948
|
-
for (;;) {
|
|
949
|
-
params.observePrompt?.(attempt.request, {
|
|
950
|
-
egress: "responses-sdk",
|
|
951
|
-
payloadVariant: attempt.kind
|
|
952
|
-
});
|
|
953
|
-
try {
|
|
954
|
-
const { data, response } = await params.client.responses.create(attempt.request, params.requestOptions).withResponse();
|
|
955
|
-
commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => {
|
|
956
|
-
if (checkpoint) params.onCompactionRejected?.(checkpoint);
|
|
957
|
-
});
|
|
958
|
-
if (!isAsyncIterable(data)) throw new Error("OpenAI Responses streaming request returned a non-stream response");
|
|
959
|
-
return {
|
|
960
|
-
stream: data,
|
|
961
|
-
response,
|
|
962
|
-
attempt
|
|
963
|
-
};
|
|
964
|
-
} catch (error) {
|
|
965
|
-
let nextAttempt = await resolveNextResponsesEncryptedContentAttempt(attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest });
|
|
966
|
-
if (!nextAttempt && attempt.request.previous_response_id && error && typeof error === "object" && typeof error.status === "number" && isPreviousResponseRejection(error)) {
|
|
967
|
-
const request = { ...params.buildFullHistoryRequest ? await params.buildFullHistoryRequest() : attempt.request };
|
|
968
|
-
delete request.previous_response_id;
|
|
969
|
-
nextAttempt = {
|
|
970
|
-
kind: "continuation-rejected",
|
|
971
|
-
request
|
|
972
|
-
};
|
|
973
|
-
}
|
|
974
|
-
if (!nextAttempt) throw error;
|
|
975
|
-
const retryDescription = nextAttempt.kind === "reasoning-stripped" ? "without encrypted reasoning content" : nextAttempt.kind === "compaction-stripped" ? "without encrypted compaction content" : "full history after rejected previous_response_id";
|
|
976
|
-
log.warn(`[responses] retrying ${retryDescription} provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
|
|
977
|
-
attempt = nextAttempt;
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
};
|
|
981
|
-
const result = await send({
|
|
982
|
-
kind: params.initialAttemptKind ?? "initial",
|
|
983
|
-
request: params.request,
|
|
984
|
-
...params.initialRejectedCompaction ? { rejectedCompaction: params.initialRejectedCompaction } : {}
|
|
985
|
-
});
|
|
986
|
-
return { stream: { async *[Symbol.asyncIterator]() {
|
|
987
|
-
let current = result;
|
|
988
|
-
for (;;) {
|
|
989
|
-
let rejectedEvent;
|
|
990
|
-
try {
|
|
991
|
-
for await (const event of params.wrapStream?.(current) ?? current.stream) {
|
|
992
|
-
if (isRecord(event)) {
|
|
993
|
-
const failure = event.type === "response.failed" && isRecord(event.response) ? event.response.error : event.type === "error" ? event.error ?? event : void 0;
|
|
994
|
-
if (isRecord(failure) && params.canRetryStream?.() === true && isInvalidEncryptedContentError(failure)) {
|
|
995
|
-
rejectedEvent = event;
|
|
996
|
-
const message = typeof failure.message === "string" ? failure.message : "";
|
|
997
|
-
throw Object.assign(new Error(message), {
|
|
998
|
-
code: failure.code,
|
|
999
|
-
status: failure.status
|
|
1000
|
-
});
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
yield event;
|
|
1004
|
-
}
|
|
1005
|
-
return;
|
|
1006
|
-
} catch (error) {
|
|
1007
|
-
const nextAttempt = params.canRetryStream?.() === true && !params.requestOptions?.signal?.aborted ? await resolveNextResponsesEncryptedContentAttempt(current.attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest }) : void 0;
|
|
1008
|
-
if (!nextAttempt) {
|
|
1009
|
-
if (rejectedEvent !== void 0) {
|
|
1010
|
-
yield rejectedEvent;
|
|
1011
|
-
return;
|
|
1012
|
-
}
|
|
1013
|
-
throw error;
|
|
1014
|
-
}
|
|
1015
|
-
log.warn(`[responses] retrying streamed encrypted content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
|
|
1016
|
-
current = await send(nextAttempt);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
} } };
|
|
1020
|
-
}
|
|
1021
|
-
function resolveAzureOpenAIApiVersion(env = process.env) {
|
|
1022
|
-
return env.AZURE_OPENAI_API_VERSION?.trim() || "preview";
|
|
1023
|
-
}
|
|
1024
|
-
//#endregion
|
|
1025
|
-
//#region packages/ai/src/providers/openai-responses-stream-compat.ts
|
|
1026
|
-
const OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE = "output_text";
|
|
1027
|
-
const AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE = "text";
|
|
1028
|
-
const OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE = "response.output_text.delta";
|
|
1029
|
-
const AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE = "response.text.delta";
|
|
1030
|
-
function isResponsesTextContentPartType(type) {
|
|
1031
|
-
return type === "output_text" || type === "text";
|
|
1032
|
-
}
|
|
1033
|
-
function isResponsesTextDeltaEventType(type) {
|
|
1034
|
-
return type === "response.output_text.delta" || type === "response.text.delta";
|
|
1035
|
-
}
|
|
1036
|
-
function isAzureResponsesTextDeltaEventType(type) {
|
|
1037
|
-
return type === AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE;
|
|
1038
|
-
}
|
|
1039
|
-
function isAzureResponsesTextDeltaEvent(event) {
|
|
1040
|
-
return isAzureResponsesTextDeltaEventType(event.type) && typeof event.delta === "string";
|
|
1041
|
-
}
|
|
1042
|
-
function resolveResponsesMessageSnapshotCollapse(params) {
|
|
1043
|
-
const { prior, nextText } = params;
|
|
1044
|
-
if (!prior?.text || !nextText || prior.phase !== params.nextPhase) return { kind: "keep" };
|
|
1045
|
-
if (nextText.length > prior.text.length && nextText.startsWith(prior.text)) return {
|
|
1046
|
-
kind: "extend",
|
|
1047
|
-
text: nextText
|
|
1048
|
-
};
|
|
1049
|
-
return { kind: "keep" };
|
|
1050
|
-
}
|
|
1051
|
-
//#endregion
|
|
1052
|
-
//#region packages/ai/src/providers/openai-responses-tool-call-tracker.ts
|
|
1053
|
-
function readOutputIndex(event) {
|
|
1054
|
-
return typeof event.output_index === "number" && Number.isInteger(event.output_index) && event.output_index >= 0 ? event.output_index : void 0;
|
|
1055
|
-
}
|
|
1056
|
-
function readEventIdentity(event) {
|
|
1057
|
-
return { itemId: normalizeOptionalString(event.item_id) };
|
|
1058
|
-
}
|
|
1059
|
-
function readResponsesToolCallItemIdentity(item) {
|
|
1060
|
-
return {
|
|
1061
|
-
itemId: normalizeOptionalString(item.id),
|
|
1062
|
-
callId: normalizeOptionalString(item.call_id)
|
|
1063
|
-
};
|
|
1064
|
-
}
|
|
1065
|
-
function createResponsesToolCallTracker() {
|
|
1066
|
-
const indexedCalls = /* @__PURE__ */ new Map();
|
|
1067
|
-
const unindexedCalls = /* @__PURE__ */ new Set();
|
|
1068
|
-
const identitiesConflict = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId !== identity.itemId || state.callId && identity.callId && state.callId !== identity.callId);
|
|
1069
|
-
const sharesIdentity = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId === identity.itemId || state.callId && identity.callId && state.callId === identity.callId);
|
|
1070
|
-
const adoptIdentity = (state, identity) => {
|
|
1071
|
-
state.itemId ??= identity.itemId;
|
|
1072
|
-
state.callId ??= identity.callId;
|
|
1073
|
-
return state;
|
|
1074
|
-
};
|
|
1075
|
-
const resolveCompatible = (candidates, identity, allowUnmatchedIdentity) => {
|
|
1076
|
-
const uniqueCandidates = [...new Set(candidates)];
|
|
1077
|
-
if (!identity.itemId && !identity.callId) return allowUnmatchedIdentity && uniqueCandidates.length === 1 ? uniqueCandidates.at(0) : void 0;
|
|
1078
|
-
const compatible = uniqueCandidates.filter((state) => !identitiesConflict(state, identity));
|
|
1079
|
-
const matches = compatible.filter((state) => sharesIdentity(state, identity));
|
|
1080
|
-
const matched = matches.length === 1 ? matches.at(0) : void 0;
|
|
1081
|
-
if (matched) return adoptIdentity(matched, identity);
|
|
1082
|
-
const soleCompatible = allowUnmatchedIdentity && uniqueCandidates.length === 1 && compatible.length === 1 && matches.length === 0 ? compatible.at(0) : void 0;
|
|
1083
|
-
return soleCompatible ? adoptIdentity(soleCompatible, identity) : void 0;
|
|
1084
|
-
};
|
|
1085
|
-
return {
|
|
1086
|
-
register(event, state) {
|
|
1087
|
-
const outputIndex = readOutputIndex(event);
|
|
1088
|
-
if (outputIndex === void 0) {
|
|
1089
|
-
unindexedCalls.add(state);
|
|
1090
|
-
return;
|
|
1091
|
-
}
|
|
1092
|
-
if (indexedCalls.has(outputIndex)) throw new Error(`Responses stream reused active tool-call output index ${outputIndex}`);
|
|
1093
|
-
state.outputIndex = outputIndex;
|
|
1094
|
-
indexedCalls.set(outputIndex, state);
|
|
1095
|
-
},
|
|
1096
|
-
resolve(event, identity = readEventIdentity(event), allowUnmatchedIdentity = true) {
|
|
1097
|
-
const outputIndex = readOutputIndex(event);
|
|
1098
|
-
if (outputIndex !== void 0) {
|
|
1099
|
-
const indexed = indexedCalls.get(outputIndex);
|
|
1100
|
-
if (indexed) {
|
|
1101
|
-
if (indexed.callId && identity.callId && indexed.callId !== identity.callId) return;
|
|
1102
|
-
return adoptIdentity(indexed, identity);
|
|
1103
|
-
}
|
|
1104
|
-
const unindexed = resolveCompatible(unindexedCalls, identity, allowUnmatchedIdentity);
|
|
1105
|
-
if (unindexed) {
|
|
1106
|
-
unindexedCalls.delete(unindexed);
|
|
1107
|
-
unindexed.outputIndex = outputIndex;
|
|
1108
|
-
indexedCalls.set(outputIndex, unindexed);
|
|
1109
|
-
}
|
|
1110
|
-
return unindexed;
|
|
1111
|
-
}
|
|
1112
|
-
return resolveCompatible([...indexedCalls.values(), ...unindexedCalls], identity, allowUnmatchedIdentity);
|
|
1113
|
-
},
|
|
1114
|
-
forget(toolCall) {
|
|
1115
|
-
for (const [outputIndex, tracked] of indexedCalls) if (tracked === toolCall) indexedCalls.delete(outputIndex);
|
|
1116
|
-
unindexedCalls.delete(toolCall);
|
|
1117
|
-
},
|
|
1118
|
-
markArgumentsUnreliable() {
|
|
1119
|
-
for (const toolCall of /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls])) toolCall.argumentStreamReliable = false;
|
|
1120
|
-
},
|
|
1121
|
-
hasActive() {
|
|
1122
|
-
return indexedCalls.size > 0 || unindexedCalls.size > 0;
|
|
1123
|
-
},
|
|
1124
|
-
hasExactlyActive(expected) {
|
|
1125
|
-
const active = /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls]);
|
|
1126
|
-
return active.size === expected.length && expected.every((state) => active.has(state));
|
|
1127
|
-
}
|
|
1128
|
-
};
|
|
1129
|
-
}
|
|
1130
|
-
//#endregion
|
|
1131
881
|
//#region packages/ai/src/transports/openai-responses-debug.ts
|
|
1132
882
|
function stringifyUnknown(value, fallback = "") {
|
|
1133
883
|
if (typeof value === "string") return value;
|
|
@@ -1295,141 +1045,392 @@ function collectResponseFailedIdentifierHashes(value, opts = {}) {
|
|
|
1295
1045
|
out.push(`${childPath}=${redactIdentifier(childString, { len: 12 })}`);
|
|
1296
1046
|
continue;
|
|
1297
1047
|
}
|
|
1298
|
-
collectResponseFailedIdentifierHashes(child, {
|
|
1299
|
-
path: childPath,
|
|
1300
|
-
depth: depth + 1,
|
|
1301
|
-
identifierKey: isResponseFailedIdentifierKey(key) ? key : void 0,
|
|
1302
|
-
out,
|
|
1303
|
-
seen
|
|
1304
|
-
});
|
|
1305
|
-
}
|
|
1306
|
-
return out;
|
|
1048
|
+
collectResponseFailedIdentifierHashes(child, {
|
|
1049
|
+
path: childPath,
|
|
1050
|
+
depth: depth + 1,
|
|
1051
|
+
identifierKey: isResponseFailedIdentifierKey(key) ? key : void 0,
|
|
1052
|
+
out,
|
|
1053
|
+
seen
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
return out;
|
|
1057
|
+
}
|
|
1058
|
+
function redactResponseFailedDiagnosticValue(value, opts = {}) {
|
|
1059
|
+
const key = opts.key ?? "";
|
|
1060
|
+
const depth = opts.depth ?? 0;
|
|
1061
|
+
if (typeof value === "string" || typeof value === "number") return key && isResponseFailedIdentifierKey(key) ? redactIdentifier(String(value), { len: 12 }) : value;
|
|
1062
|
+
if (depth > 6 || !value || typeof value !== "object") return value;
|
|
1063
|
+
const seen = opts.seen ?? /* @__PURE__ */ new WeakSet();
|
|
1064
|
+
if (seen.has(value)) return "<circular>";
|
|
1065
|
+
seen.add(value);
|
|
1066
|
+
if (Array.isArray(value)) return value.slice(0, 16).map((item) => redactResponseFailedDiagnosticValue(item, {
|
|
1067
|
+
key,
|
|
1068
|
+
depth: depth + 1,
|
|
1069
|
+
seen
|
|
1070
|
+
}));
|
|
1071
|
+
const out = {};
|
|
1072
|
+
for (const [childKey, child] of Object.entries(value)) out[childKey] = redactResponseFailedDiagnosticValue(child, {
|
|
1073
|
+
key: childKey,
|
|
1074
|
+
depth: depth + 1,
|
|
1075
|
+
seen
|
|
1076
|
+
});
|
|
1077
|
+
return out;
|
|
1078
|
+
}
|
|
1079
|
+
function buildResponsesFailedFailureFields(response) {
|
|
1080
|
+
if (!response) return {};
|
|
1081
|
+
const fields = {};
|
|
1082
|
+
for (const key of RESPONSE_FAILED_FAILURE_FIELD_KEYS) if (response[key] !== void 0 && response[key] !== null) fields[key] = response[key];
|
|
1083
|
+
return fields;
|
|
1084
|
+
}
|
|
1085
|
+
function buildResponsesFailedNoDetailsObservation(event, model, response = isRecord(event.response) ? event.response : void 0) {
|
|
1086
|
+
const failureFields = redactResponseFailedDiagnosticValue(buildResponsesFailedFailureFields(response));
|
|
1087
|
+
const metadataKeys = isRecord(response?.metadata) ? Object.keys(response.metadata).toSorted() : [];
|
|
1088
|
+
const responsePreview = {
|
|
1089
|
+
id: readResponseFailedString(response, "id"),
|
|
1090
|
+
status: readResponseFailedString(response, "status"),
|
|
1091
|
+
model: readResponseFailedString(response, "model"),
|
|
1092
|
+
object: readResponseFailedString(response, "object"),
|
|
1093
|
+
failureFields,
|
|
1094
|
+
metadataKeys
|
|
1095
|
+
};
|
|
1096
|
+
return {
|
|
1097
|
+
event: "openai_responses_response_failed_without_details",
|
|
1098
|
+
provider: model.provider,
|
|
1099
|
+
api: model.api,
|
|
1100
|
+
transportModel: model.id,
|
|
1101
|
+
providerRuntimeFailureKind: "no_error_details",
|
|
1102
|
+
responseId: responsePreview.id,
|
|
1103
|
+
responseStatus: responsePreview.status,
|
|
1104
|
+
responseModel: responsePreview.model,
|
|
1105
|
+
responseObject: responsePreview.object,
|
|
1106
|
+
metadataKeys,
|
|
1107
|
+
requestIdHashes: collectResponseFailedIdentifierHashes(event),
|
|
1108
|
+
failureFieldsPreview: stringifyRedactedEvent(failureFields),
|
|
1109
|
+
responsePreview: stringifyRedactedEvent(responsePreview)
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
function summarizeResponsesFailedNoDetailsObservation(observation) {
|
|
1113
|
+
const requestIds = observation.requestIdHashes.join(",");
|
|
1114
|
+
const metadataKeys = observation.metadataKeys.join(",");
|
|
1115
|
+
return `responseId=${safeDebugValue(observation.responseId || void 0)} responseStatus=${safeDebugValue(observation.responseStatus || void 0)} responseModel=${safeDebugValue(observation.responseModel || void 0)} requestIds=${requestIds || "none"} metadataKeys=${metadataKeys || "none"} failureFields=${observation.failureFieldsPreview}`;
|
|
1116
|
+
}
|
|
1117
|
+
function normalizeResponsesFailedEvent(event, model) {
|
|
1118
|
+
const response = isRecord(event.response) ? event.response : void 0;
|
|
1119
|
+
const responseId = readResponseFailedString(response, "id") || void 0;
|
|
1120
|
+
const error = isRecord(response?.error) ? response.error : void 0;
|
|
1121
|
+
if (error) {
|
|
1122
|
+
const code = readResponseFailedString(error, "code").trim();
|
|
1123
|
+
const message = readResponseFailedString(error, "message").trim();
|
|
1124
|
+
if (code || message) return buildResponsesFailedEventSummary(`${code || "unknown"}: ${message || "no message"}`, responseId, code || void 0);
|
|
1125
|
+
}
|
|
1126
|
+
const incompleteReason = readResponseFailedString(isRecord(response?.incomplete_details) ? response.incomplete_details : void 0, "reason");
|
|
1127
|
+
if (incompleteReason) return buildResponsesFailedEventSummary(`incomplete: ${incompleteReason}`, responseId);
|
|
1128
|
+
return buildResponsesFailedEventSummary(RESPONSE_FAILED_NO_DETAILS_MESSAGE, responseId, void 0, buildResponsesFailedNoDetailsObservation(event, model, response));
|
|
1129
|
+
}
|
|
1130
|
+
var ResponsesStreamFailure = class extends Error {
|
|
1131
|
+
constructor(failure, response) {
|
|
1132
|
+
super(failure.message);
|
|
1133
|
+
this.name = "ResponsesStreamFailure";
|
|
1134
|
+
this.responseId = failure.responseId;
|
|
1135
|
+
this.response = response;
|
|
1136
|
+
this.code = failure.code;
|
|
1137
|
+
this.observation = failure.observation;
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
function logResponsesFailedNoDetails(observation) {
|
|
1141
|
+
log.warn(`[responses] response.failed missing error details provider=${observation.provider} api=${observation.api} model=${observation.transportModel} ` + summarizeResponsesFailedNoDetailsObservation(observation), observation);
|
|
1142
|
+
}
|
|
1143
|
+
function summarizeResponsesPayload(params) {
|
|
1144
|
+
if (!params || typeof params !== "object") return "payload=non-object";
|
|
1145
|
+
const record = params;
|
|
1146
|
+
const input = record.input;
|
|
1147
|
+
const reasoning = record.reasoning && typeof record.reasoning === "object" ? record.reasoning : void 0;
|
|
1148
|
+
const text = record.text && typeof record.text === "object" ? record.text : void 0;
|
|
1149
|
+
const parts = [
|
|
1150
|
+
`fields=${Object.keys(record).toSorted().join(",")}`,
|
|
1151
|
+
`model=${safeDebugValue(record.model)}`,
|
|
1152
|
+
`stream=${safeDebugValue(record.stream)}`,
|
|
1153
|
+
`inputItems=${Array.isArray(input) ? input.length : typeof input}`,
|
|
1154
|
+
`inputItemShape=${responseInputItemShape(input)}`,
|
|
1155
|
+
`inputRoles=${responseInputRoles(input) || "none"}`,
|
|
1156
|
+
`inputTextChars=${responseInputTextChars(input)}`,
|
|
1157
|
+
`tools=${summarizeResponsesTools(record.tools)}`,
|
|
1158
|
+
`reasoningEffort=${safeDebugValue(reasoning?.effort)}`,
|
|
1159
|
+
`reasoningSummary=${safeDebugValue(reasoning?.summary)}`,
|
|
1160
|
+
`textVerbosity=${safeDebugValue(text?.verbosity)}`,
|
|
1161
|
+
`serviceTier=${safeDebugValue(record.service_tier)}`,
|
|
1162
|
+
...summarizeResponsesCompactionItems(input),
|
|
1163
|
+
`store=${safeDebugValue(record.store)}`,
|
|
1164
|
+
`promptCacheKey=${record.prompt_cache_key === void 0 ? "absent" : "present"}`,
|
|
1165
|
+
`metadataKeys=${record.metadata && typeof record.metadata === "object" ? Object.keys(record.metadata).toSorted().join(",") : "none"}`
|
|
1166
|
+
];
|
|
1167
|
+
if (resolveModelPayloadDebugMode() === "full-redacted") parts.push(`payload=${stringifyRedactedPayload(record)}`);
|
|
1168
|
+
return parts.join(" ");
|
|
1169
|
+
}
|
|
1170
|
+
function summarizeOpenAITransportError(error) {
|
|
1171
|
+
if (!error || typeof error !== "object") return `type=${typeof error} message=${safeDebugValue(error)}`;
|
|
1172
|
+
const record = error;
|
|
1173
|
+
const cause = record.cause && typeof record.cause === "object" ? record.cause : void 0;
|
|
1174
|
+
return [
|
|
1175
|
+
`name=${safeDebugValue(record.name)}`,
|
|
1176
|
+
`status=${safeDebugValue(record.status)}`,
|
|
1177
|
+
`code=${safeDebugValue(record.code)}`,
|
|
1178
|
+
`type=${safeDebugValue(record.type)}`,
|
|
1179
|
+
`causeName=${safeDebugValue(cause?.name)}`,
|
|
1180
|
+
`causeCode=${safeDebugValue(cause?.code)}`,
|
|
1181
|
+
`message=${error instanceof Error ? error.message : safeDebugValue(error)}`
|
|
1182
|
+
].join(" ");
|
|
1183
|
+
}
|
|
1184
|
+
//#endregion
|
|
1185
|
+
//#region packages/ai/src/transports/openai-responses-replay-internal.ts
|
|
1186
|
+
function isAsyncIterable(value) {
|
|
1187
|
+
return (typeof value === "object" && value !== null || typeof value === "function") && Symbol.asyncIterator in value;
|
|
1188
|
+
}
|
|
1189
|
+
function isInvalidEncryptedContentError(error) {
|
|
1190
|
+
if (!error || typeof error !== "object") return false;
|
|
1191
|
+
const record = error;
|
|
1192
|
+
if (record.code === "invalid_encrypted_content" || record.code === "thinking_signature_invalid") return true;
|
|
1193
|
+
const message = typeof record.message === "string" ? record.message.toLowerCase() : "";
|
|
1194
|
+
return message.includes("invalid_encrypted_content") || message.includes("thinking_signature_invalid") || (record.status === 400 || record.status == null && /(?:^|[\s(])400(?:[\s):]|$)/.test(message)) && (message.includes("could not decrypt the provided encrypted_content") || message.includes("encrypted content") && (message.includes("could not be verified") || message.includes("could not be decrypted or parsed")));
|
|
1195
|
+
}
|
|
1196
|
+
function isOrphanedFunctionCallOutputError(error) {
|
|
1197
|
+
if (!error || typeof error !== "object") return false;
|
|
1198
|
+
const record = error;
|
|
1199
|
+
const message = typeof record.message === "string" ? record.message : "";
|
|
1200
|
+
return /No tool call found for function call output with call_id [A-Za-z0-9_-]+/.test(message);
|
|
1201
|
+
}
|
|
1202
|
+
function commitResponsesEncryptedContentAttempt(attempt, commit) {
|
|
1203
|
+
if (attempt.kind === "compaction-stripped") commit(attempt.rejectedCompaction);
|
|
1204
|
+
}
|
|
1205
|
+
function stripResponsesRequestEncryptedReasoning(request) {
|
|
1206
|
+
const stripped = stripEncryptedReasoningContentFields(request.input);
|
|
1207
|
+
if (!stripped.changed) return request;
|
|
1208
|
+
return {
|
|
1209
|
+
...request,
|
|
1210
|
+
input: stripped.value
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
function stripResponsesRequestCompaction(request) {
|
|
1214
|
+
if (!Array.isArray(request.input)) return request;
|
|
1215
|
+
const input = request.input.filter((item) => !(item !== null && typeof item === "object" && item.type === "compaction"));
|
|
1216
|
+
return input.length === request.input.length ? request : {
|
|
1217
|
+
...request,
|
|
1218
|
+
input
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
function readOpenAIResponsesCompactionRejection(request) {
|
|
1222
|
+
if (!Array.isArray(request.input)) return;
|
|
1223
|
+
const item = request.input.find((candidate) => candidate !== null && typeof candidate === "object" && candidate.type === "compaction" && typeof candidate.encrypted_content === "string");
|
|
1224
|
+
return item ? {
|
|
1225
|
+
data: item.encrypted_content,
|
|
1226
|
+
...typeof item.id === "string" ? { id: item.id } : {}
|
|
1227
|
+
} : void 0;
|
|
1228
|
+
}
|
|
1229
|
+
async function resolveNextResponsesEncryptedContentAttempt(attempt, error, options) {
|
|
1230
|
+
const orphanedFunctionOutput = isOrphanedFunctionCallOutputError(error);
|
|
1231
|
+
if (!isInvalidEncryptedContentError(error) && !orphanedFunctionOutput || attempt.kind === "compaction-stripped") return;
|
|
1232
|
+
if (!orphanedFunctionOutput && (attempt.kind === "initial" || attempt.kind === "continuation-rejected")) {
|
|
1233
|
+
const reasoningStripped = stripResponsesRequestEncryptedReasoning(attempt.request);
|
|
1234
|
+
if (reasoningStripped !== attempt.request) return {
|
|
1235
|
+
kind: "reasoning-stripped",
|
|
1236
|
+
request: reasoningStripped
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
const locallyStripped = stripResponsesRequestCompaction(attempt.request);
|
|
1240
|
+
if (locallyStripped === attempt.request) return;
|
|
1241
|
+
let compactionStripped = options?.buildFullHistoryRequest ? await options.buildFullHistoryRequest() : locallyStripped;
|
|
1242
|
+
compactionStripped = stripResponsesRequestCompaction(compactionStripped);
|
|
1243
|
+
if (attempt.kind === "reasoning-stripped") compactionStripped = stripResponsesRequestEncryptedReasoning(compactionStripped);
|
|
1244
|
+
return {
|
|
1245
|
+
kind: "compaction-stripped",
|
|
1246
|
+
request: compactionStripped,
|
|
1247
|
+
rejectedCompaction: readOpenAIResponsesCompactionRejection(attempt.request)
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
async function createResponsesStreamWithEncryptedContentRetry(params) {
|
|
1251
|
+
const send = async (initialAttempt) => {
|
|
1252
|
+
let attempt = initialAttempt;
|
|
1253
|
+
for (;;) {
|
|
1254
|
+
params.observePrompt?.(attempt.request, {
|
|
1255
|
+
egress: "responses-sdk",
|
|
1256
|
+
payloadVariant: attempt.kind
|
|
1257
|
+
});
|
|
1258
|
+
try {
|
|
1259
|
+
const { data, response } = await params.client.responses.create(attempt.request, params.requestOptions).withResponse();
|
|
1260
|
+
commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => {
|
|
1261
|
+
if (checkpoint) params.onCompactionRejected?.(checkpoint);
|
|
1262
|
+
});
|
|
1263
|
+
if (!isAsyncIterable(data)) throw new Error("OpenAI Responses streaming request returned a non-stream response");
|
|
1264
|
+
return {
|
|
1265
|
+
stream: data,
|
|
1266
|
+
response,
|
|
1267
|
+
attempt
|
|
1268
|
+
};
|
|
1269
|
+
} catch (error) {
|
|
1270
|
+
let nextAttempt = await resolveNextResponsesEncryptedContentAttempt(attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest });
|
|
1271
|
+
if (!nextAttempt && attempt.request.previous_response_id && error && typeof error === "object" && typeof error.status === "number" && isPreviousResponseRejection(error)) {
|
|
1272
|
+
const request = { ...params.buildFullHistoryRequest ? await params.buildFullHistoryRequest() : attempt.request };
|
|
1273
|
+
delete request.previous_response_id;
|
|
1274
|
+
nextAttempt = {
|
|
1275
|
+
kind: "continuation-rejected",
|
|
1276
|
+
request
|
|
1277
|
+
};
|
|
1278
|
+
}
|
|
1279
|
+
if (!nextAttempt) throw error;
|
|
1280
|
+
const retryDescription = nextAttempt.kind === "reasoning-stripped" ? "without encrypted reasoning content" : nextAttempt.kind === "compaction-stripped" ? "without encrypted compaction content" : "full history after rejected previous_response_id";
|
|
1281
|
+
log.warn(`[responses] retrying ${retryDescription} provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
|
|
1282
|
+
attempt = nextAttempt;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
};
|
|
1286
|
+
const result = await send({
|
|
1287
|
+
kind: params.initialAttemptKind ?? "initial",
|
|
1288
|
+
request: params.request,
|
|
1289
|
+
...params.initialRejectedCompaction ? { rejectedCompaction: params.initialRejectedCompaction } : {}
|
|
1290
|
+
});
|
|
1291
|
+
return { stream: { async *[Symbol.asyncIterator]() {
|
|
1292
|
+
let current = result;
|
|
1293
|
+
for (;;) {
|
|
1294
|
+
let rejectedEvent;
|
|
1295
|
+
try {
|
|
1296
|
+
for await (const event of params.wrapStream?.(current) ?? current.stream) {
|
|
1297
|
+
if (isRecord(event)) {
|
|
1298
|
+
const failure = event.type === "response.failed" && isRecord(event.response) ? event.response.error : event.type === "error" ? event.error ?? event : void 0;
|
|
1299
|
+
if (isRecord(failure) && params.canRetryStream?.() === true && isInvalidEncryptedContentError(failure)) {
|
|
1300
|
+
rejectedEvent = event;
|
|
1301
|
+
const message = typeof failure.message === "string" ? failure.message : "";
|
|
1302
|
+
throw Object.assign(new Error(message), {
|
|
1303
|
+
code: failure.code,
|
|
1304
|
+
status: failure.status
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
yield event;
|
|
1309
|
+
}
|
|
1310
|
+
return;
|
|
1311
|
+
} catch (error) {
|
|
1312
|
+
const nextAttempt = params.canRetryStream?.() === true && !params.requestOptions?.signal?.aborted ? await resolveNextResponsesEncryptedContentAttempt(current.attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest }) : void 0;
|
|
1313
|
+
if (!nextAttempt) {
|
|
1314
|
+
if (rejectedEvent !== void 0) {
|
|
1315
|
+
yield rejectedEvent;
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
throw error;
|
|
1319
|
+
}
|
|
1320
|
+
log.warn(`[responses] retrying streamed encrypted content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
|
|
1321
|
+
current = await send(nextAttempt);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
} } };
|
|
1307
1325
|
}
|
|
1308
|
-
function
|
|
1309
|
-
|
|
1310
|
-
const depth = opts.depth ?? 0;
|
|
1311
|
-
if (typeof value === "string" || typeof value === "number") return key && isResponseFailedIdentifierKey(key) ? redactIdentifier(String(value), { len: 12 }) : value;
|
|
1312
|
-
if (depth > 6 || !value || typeof value !== "object") return value;
|
|
1313
|
-
const seen = opts.seen ?? /* @__PURE__ */ new WeakSet();
|
|
1314
|
-
if (seen.has(value)) return "<circular>";
|
|
1315
|
-
seen.add(value);
|
|
1316
|
-
if (Array.isArray(value)) return value.slice(0, 16).map((item) => redactResponseFailedDiagnosticValue(item, {
|
|
1317
|
-
key,
|
|
1318
|
-
depth: depth + 1,
|
|
1319
|
-
seen
|
|
1320
|
-
}));
|
|
1321
|
-
const out = {};
|
|
1322
|
-
for (const [childKey, child] of Object.entries(value)) out[childKey] = redactResponseFailedDiagnosticValue(child, {
|
|
1323
|
-
key: childKey,
|
|
1324
|
-
depth: depth + 1,
|
|
1325
|
-
seen
|
|
1326
|
-
});
|
|
1327
|
-
return out;
|
|
1326
|
+
function resolveAzureOpenAIApiVersion(env = process.env) {
|
|
1327
|
+
return env.AZURE_OPENAI_API_VERSION?.trim() || "preview";
|
|
1328
1328
|
}
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1329
|
+
//#endregion
|
|
1330
|
+
//#region packages/ai/src/providers/openai-responses-stream-compat.ts
|
|
1331
|
+
const OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE = "output_text";
|
|
1332
|
+
const AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE = "text";
|
|
1333
|
+
const OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE = "response.output_text.delta";
|
|
1334
|
+
const AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE = "response.text.delta";
|
|
1335
|
+
function isResponsesTextContentPartType(type) {
|
|
1336
|
+
return type === "output_text" || type === "text";
|
|
1334
1337
|
}
|
|
1335
|
-
function
|
|
1336
|
-
|
|
1337
|
-
const metadataKeys = isRecord(response?.metadata) ? Object.keys(response.metadata).toSorted() : [];
|
|
1338
|
-
const responsePreview = {
|
|
1339
|
-
id: readResponseFailedString(response, "id"),
|
|
1340
|
-
status: readResponseFailedString(response, "status"),
|
|
1341
|
-
model: readResponseFailedString(response, "model"),
|
|
1342
|
-
object: readResponseFailedString(response, "object"),
|
|
1343
|
-
failureFields,
|
|
1344
|
-
metadataKeys
|
|
1345
|
-
};
|
|
1346
|
-
return {
|
|
1347
|
-
event: "openai_responses_response_failed_without_details",
|
|
1348
|
-
provider: model.provider,
|
|
1349
|
-
api: model.api,
|
|
1350
|
-
transportModel: model.id,
|
|
1351
|
-
providerRuntimeFailureKind: "no_error_details",
|
|
1352
|
-
responseId: responsePreview.id,
|
|
1353
|
-
responseStatus: responsePreview.status,
|
|
1354
|
-
responseModel: responsePreview.model,
|
|
1355
|
-
responseObject: responsePreview.object,
|
|
1356
|
-
metadataKeys,
|
|
1357
|
-
requestIdHashes: collectResponseFailedIdentifierHashes(event),
|
|
1358
|
-
failureFieldsPreview: stringifyRedactedEvent(failureFields),
|
|
1359
|
-
responsePreview: stringifyRedactedEvent(responsePreview)
|
|
1360
|
-
};
|
|
1338
|
+
function isResponsesTextDeltaEventType(type) {
|
|
1339
|
+
return type === "response.output_text.delta" || type === "response.text.delta";
|
|
1361
1340
|
}
|
|
1362
|
-
function
|
|
1363
|
-
|
|
1364
|
-
const metadataKeys = observation.metadataKeys.join(",");
|
|
1365
|
-
return `responseId=${safeDebugValue(observation.responseId || void 0)} responseStatus=${safeDebugValue(observation.responseStatus || void 0)} responseModel=${safeDebugValue(observation.responseModel || void 0)} requestIds=${requestIds || "none"} metadataKeys=${metadataKeys || "none"} failureFields=${observation.failureFieldsPreview}`;
|
|
1341
|
+
function isAzureResponsesTextDeltaEventType(type) {
|
|
1342
|
+
return type === AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE;
|
|
1366
1343
|
}
|
|
1367
|
-
function
|
|
1368
|
-
|
|
1369
|
-
const responseId = readResponseFailedString(response, "id") || void 0;
|
|
1370
|
-
const error = isRecord(response?.error) ? response.error : void 0;
|
|
1371
|
-
if (error) {
|
|
1372
|
-
const code = readResponseFailedString(error, "code").trim();
|
|
1373
|
-
const message = readResponseFailedString(error, "message").trim();
|
|
1374
|
-
if (code || message) return buildResponsesFailedEventSummary(`${code || "unknown"}: ${message || "no message"}`, responseId, code || void 0);
|
|
1375
|
-
}
|
|
1376
|
-
const incompleteReason = readResponseFailedString(isRecord(response?.incomplete_details) ? response.incomplete_details : void 0, "reason");
|
|
1377
|
-
if (incompleteReason) return buildResponsesFailedEventSummary(`incomplete: ${incompleteReason}`, responseId);
|
|
1378
|
-
return buildResponsesFailedEventSummary(RESPONSE_FAILED_NO_DETAILS_MESSAGE, responseId, void 0, buildResponsesFailedNoDetailsObservation(event, model, response));
|
|
1344
|
+
function isAzureResponsesTextDeltaEvent(event) {
|
|
1345
|
+
return isAzureResponsesTextDeltaEventType(event.type) && typeof event.delta === "string";
|
|
1379
1346
|
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
}
|
|
1389
|
-
};
|
|
1390
|
-
function logResponsesFailedNoDetails(observation) {
|
|
1391
|
-
log.warn(`[responses] response.failed missing error details provider=${observation.provider} api=${observation.api} model=${observation.transportModel} ` + summarizeResponsesFailedNoDetailsObservation(observation), observation);
|
|
1347
|
+
function resolveResponsesMessageSnapshotCollapse(params) {
|
|
1348
|
+
const { prior, nextText } = params;
|
|
1349
|
+
if (!prior?.text || !nextText || prior.phase !== params.nextPhase) return { kind: "keep" };
|
|
1350
|
+
if (nextText.length > prior.text.length && nextText.startsWith(prior.text)) return {
|
|
1351
|
+
kind: "extend",
|
|
1352
|
+
text: nextText
|
|
1353
|
+
};
|
|
1354
|
+
return { kind: "keep" };
|
|
1392
1355
|
}
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
const reasoning = record.reasoning && typeof record.reasoning === "object" ? record.reasoning : void 0;
|
|
1398
|
-
const text = record.text && typeof record.text === "object" ? record.text : void 0;
|
|
1399
|
-
const parts = [
|
|
1400
|
-
`fields=${Object.keys(record).toSorted().join(",")}`,
|
|
1401
|
-
`model=${safeDebugValue(record.model)}`,
|
|
1402
|
-
`stream=${safeDebugValue(record.stream)}`,
|
|
1403
|
-
`inputItems=${Array.isArray(input) ? input.length : typeof input}`,
|
|
1404
|
-
`inputItemShape=${responseInputItemShape(input)}`,
|
|
1405
|
-
`inputRoles=${responseInputRoles(input) || "none"}`,
|
|
1406
|
-
`inputTextChars=${responseInputTextChars(input)}`,
|
|
1407
|
-
`tools=${summarizeResponsesTools(record.tools)}`,
|
|
1408
|
-
`reasoningEffort=${safeDebugValue(reasoning?.effort)}`,
|
|
1409
|
-
`reasoningSummary=${safeDebugValue(reasoning?.summary)}`,
|
|
1410
|
-
`textVerbosity=${safeDebugValue(text?.verbosity)}`,
|
|
1411
|
-
`serviceTier=${safeDebugValue(record.service_tier)}`,
|
|
1412
|
-
...summarizeResponsesCompactionItems(input),
|
|
1413
|
-
`store=${safeDebugValue(record.store)}`,
|
|
1414
|
-
`promptCacheKey=${record.prompt_cache_key === void 0 ? "absent" : "present"}`,
|
|
1415
|
-
`metadataKeys=${record.metadata && typeof record.metadata === "object" ? Object.keys(record.metadata).toSorted().join(",") : "none"}`
|
|
1416
|
-
];
|
|
1417
|
-
if (resolveModelPayloadDebugMode() === "full-redacted") parts.push(`payload=${stringifyRedactedPayload(record)}`);
|
|
1418
|
-
return parts.join(" ");
|
|
1356
|
+
//#endregion
|
|
1357
|
+
//#region packages/ai/src/providers/openai-responses-tool-call-tracker.ts
|
|
1358
|
+
function readOutputIndex(event) {
|
|
1359
|
+
return typeof event.output_index === "number" && Number.isInteger(event.output_index) && event.output_index >= 0 ? event.output_index : void 0;
|
|
1419
1360
|
}
|
|
1420
|
-
function
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
return
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1361
|
+
function readEventIdentity(event) {
|
|
1362
|
+
return { itemId: normalizeOptionalString(event.item_id) };
|
|
1363
|
+
}
|
|
1364
|
+
function readResponsesToolCallItemIdentity(item) {
|
|
1365
|
+
return {
|
|
1366
|
+
itemId: normalizeOptionalString(item.id),
|
|
1367
|
+
callId: normalizeOptionalString(item.call_id)
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
function createResponsesToolCallTracker() {
|
|
1371
|
+
const indexedCalls = /* @__PURE__ */ new Map();
|
|
1372
|
+
const unindexedCalls = /* @__PURE__ */ new Set();
|
|
1373
|
+
const identitiesConflict = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId !== identity.itemId || state.callId && identity.callId && state.callId !== identity.callId);
|
|
1374
|
+
const sharesIdentity = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId === identity.itemId || state.callId && identity.callId && state.callId === identity.callId);
|
|
1375
|
+
const adoptIdentity = (state, identity) => {
|
|
1376
|
+
state.itemId ??= identity.itemId;
|
|
1377
|
+
state.callId ??= identity.callId;
|
|
1378
|
+
return state;
|
|
1379
|
+
};
|
|
1380
|
+
const resolveCompatible = (candidates, identity, allowUnmatchedIdentity) => {
|
|
1381
|
+
const uniqueCandidates = [...new Set(candidates)];
|
|
1382
|
+
if (!identity.itemId && !identity.callId) return allowUnmatchedIdentity && uniqueCandidates.length === 1 ? uniqueCandidates.at(0) : void 0;
|
|
1383
|
+
const compatible = uniqueCandidates.filter((state) => !identitiesConflict(state, identity));
|
|
1384
|
+
const matches = compatible.filter((state) => sharesIdentity(state, identity));
|
|
1385
|
+
const matched = matches.length === 1 ? matches.at(0) : void 0;
|
|
1386
|
+
if (matched) return adoptIdentity(matched, identity);
|
|
1387
|
+
const soleCompatible = allowUnmatchedIdentity && uniqueCandidates.length === 1 && compatible.length === 1 && matches.length === 0 ? compatible.at(0) : void 0;
|
|
1388
|
+
return soleCompatible ? adoptIdentity(soleCompatible, identity) : void 0;
|
|
1389
|
+
};
|
|
1390
|
+
return {
|
|
1391
|
+
register(event, state) {
|
|
1392
|
+
const outputIndex = readOutputIndex(event);
|
|
1393
|
+
if (outputIndex === void 0) {
|
|
1394
|
+
unindexedCalls.add(state);
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1397
|
+
if (indexedCalls.has(outputIndex)) throw new Error(`Responses stream reused active tool-call output index ${outputIndex}`);
|
|
1398
|
+
state.outputIndex = outputIndex;
|
|
1399
|
+
indexedCalls.set(outputIndex, state);
|
|
1400
|
+
},
|
|
1401
|
+
resolve(event, identity = readEventIdentity(event), allowUnmatchedIdentity = true) {
|
|
1402
|
+
const outputIndex = readOutputIndex(event);
|
|
1403
|
+
if (outputIndex !== void 0) {
|
|
1404
|
+
const indexed = indexedCalls.get(outputIndex);
|
|
1405
|
+
if (indexed) {
|
|
1406
|
+
if (indexed.callId && identity.callId && indexed.callId !== identity.callId) return;
|
|
1407
|
+
return adoptIdentity(indexed, identity);
|
|
1408
|
+
}
|
|
1409
|
+
const unindexed = resolveCompatible(unindexedCalls, identity, allowUnmatchedIdentity);
|
|
1410
|
+
if (unindexed) {
|
|
1411
|
+
unindexedCalls.delete(unindexed);
|
|
1412
|
+
unindexed.outputIndex = outputIndex;
|
|
1413
|
+
indexedCalls.set(outputIndex, unindexed);
|
|
1414
|
+
}
|
|
1415
|
+
return unindexed;
|
|
1416
|
+
}
|
|
1417
|
+
return resolveCompatible([...indexedCalls.values(), ...unindexedCalls], identity, allowUnmatchedIdentity);
|
|
1418
|
+
},
|
|
1419
|
+
forget(toolCall) {
|
|
1420
|
+
for (const [outputIndex, tracked] of indexedCalls) if (tracked === toolCall) indexedCalls.delete(outputIndex);
|
|
1421
|
+
unindexedCalls.delete(toolCall);
|
|
1422
|
+
},
|
|
1423
|
+
markArgumentsUnreliable() {
|
|
1424
|
+
for (const toolCall of /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls])) toolCall.argumentStreamReliable = false;
|
|
1425
|
+
},
|
|
1426
|
+
hasActive() {
|
|
1427
|
+
return indexedCalls.size > 0 || unindexedCalls.size > 0;
|
|
1428
|
+
},
|
|
1429
|
+
hasExactlyActive(expected) {
|
|
1430
|
+
const active = /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls]);
|
|
1431
|
+
return active.size === expected.length && expected.every((state) => active.has(state));
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1433
1434
|
}
|
|
1434
1435
|
//#endregion
|
|
1435
1436
|
//#region packages/ai/src/transports/openai-responses-stream-observer-internal.ts
|
|
@@ -1474,8 +1475,12 @@ async function* observeResponsesStream(stream, model, requestStartedAt) {
|
|
|
1474
1475
|
}
|
|
1475
1476
|
//#endregion
|
|
1476
1477
|
//#region packages/ai/src/transports/openai-responses-stream-slots-internal.ts
|
|
1477
|
-
function createResponsesOutputTracker() {
|
|
1478
|
+
function createResponsesOutputTracker(params) {
|
|
1478
1479
|
const outputs = /* @__PURE__ */ new Map();
|
|
1480
|
+
let currentEventType = "unknown";
|
|
1481
|
+
let providerToolObserved = false;
|
|
1482
|
+
let visibleTextEmitted = false;
|
|
1483
|
+
let terminalAllowsRetry = false;
|
|
1479
1484
|
const identity = (item) => {
|
|
1480
1485
|
if ((item.type === "reasoning" || item.type === "message") && item.id) return `${item.type}:${item.id}`;
|
|
1481
1486
|
const callId = item.call_id ?? item.id;
|
|
@@ -1485,10 +1490,37 @@ function createResponsesOutputTracker() {
|
|
|
1485
1490
|
const key = identity(item);
|
|
1486
1491
|
const output = (outputIndex === void 0 ? void 0 : outputs.get(outputIndex)) ?? (key === void 0 ? void 0 : outputs.get(key));
|
|
1487
1492
|
if (!output || outputIndex !== void 0 && output.outputIndex !== void 0 && output.outputIndex !== outputIndex) return;
|
|
1488
|
-
if (output.type !== item.type || output.callId && item.call_id && output.callId !== item.call_id) throw new
|
|
1493
|
+
if (output.type !== item.type || output.callId && item.call_id && output.callId !== item.call_id) throw new ResponsesOutputIdentityError({
|
|
1494
|
+
outputIndex,
|
|
1495
|
+
expectedType: output.type,
|
|
1496
|
+
actualType: item.type,
|
|
1497
|
+
completed: output.completed,
|
|
1498
|
+
completedToolCall: [...outputs.values()].some((candidate) => candidate.type === "function_call" && candidate.completed),
|
|
1499
|
+
eventType: currentEventType,
|
|
1500
|
+
retrySafe: params.canRetryIdentityConflict?.() === true && !providerToolObserved && !visibleTextEmitted && terminalAllowsRetry && !params.output.content.some((block) => block.type === "text" && block.text.length > 0)
|
|
1501
|
+
});
|
|
1489
1502
|
return output;
|
|
1490
1503
|
};
|
|
1491
1504
|
return {
|
|
1505
|
+
trackStream(sink) {
|
|
1506
|
+
return { push(event) {
|
|
1507
|
+
visibleTextEmitted ||= event.type === "text_delta" && event.delta.length > 0 || event.type === "text_end" && event.content.length > 0;
|
|
1508
|
+
sink.push(event);
|
|
1509
|
+
} };
|
|
1510
|
+
},
|
|
1511
|
+
observeEvent(event) {
|
|
1512
|
+
currentEventType = event.type;
|
|
1513
|
+
terminalAllowsRetry = false;
|
|
1514
|
+
if (event.type === "response.output_item.added" || event.type === "response.output_item.done") providerToolObserved ||= isResponsesProviderTool(event.item);
|
|
1515
|
+
else if (event.type === "response.completed" || event.type === "response.incomplete") {
|
|
1516
|
+
let terminalHasRefusal = false;
|
|
1517
|
+
for (const item of event.response.output ?? []) {
|
|
1518
|
+
providerToolObserved ||= isResponsesProviderTool(item);
|
|
1519
|
+
terminalHasRefusal ||= item.type === "message" && (item.content ?? []).some((part) => part.type === "refusal");
|
|
1520
|
+
}
|
|
1521
|
+
terminalAllowsRetry = event.type === "response.completed" && event.response.status === "completed" && event.response.error == null && event.response.incomplete_details == null && !terminalHasRefusal;
|
|
1522
|
+
}
|
|
1523
|
+
},
|
|
1492
1524
|
get,
|
|
1493
1525
|
set(item, contentIndex, outputIndex, completed = false) {
|
|
1494
1526
|
const output = get(item, outputIndex) ?? {
|
|
@@ -1547,6 +1579,11 @@ function createResponsesOutputSlotTracker() {
|
|
|
1547
1579
|
const outputIndex = readResponsesOutputIndex(event);
|
|
1548
1580
|
return outputIndex === void 0 ? unindexed : indexed.get(outputIndex);
|
|
1549
1581
|
},
|
|
1582
|
+
resolveOutputItem(event, item) {
|
|
1583
|
+
if (item.type === "reasoning") return this.resolve(event, "thinking");
|
|
1584
|
+
if (item.type === "message") return this.resolve(event, "text");
|
|
1585
|
+
return readResponsesOutputIndex(event) === void 0 ? void 0 : this.get(event);
|
|
1586
|
+
},
|
|
1550
1587
|
values() {
|
|
1551
1588
|
return [.../* @__PURE__ */ new Set([...indexed.values(), ...unindexed ? [unindexed] : []])];
|
|
1552
1589
|
},
|
|
@@ -1788,6 +1825,7 @@ function createResponsesTerminalController(params) {
|
|
|
1788
1825
|
timestamp: Date.now(),
|
|
1789
1826
|
details: {
|
|
1790
1827
|
eventType: terminalEventType,
|
|
1828
|
+
stopReason: terminal.stopReason,
|
|
1791
1829
|
...terminalEventType === "response.incomplete" ? { incompleteReason: incompleteReason === "max_output_tokens" || incompleteReason === "max_messages" || incompleteReason === "content_filter" || incompleteReason === "steered" ? incompleteReason : "unknown" } : {},
|
|
1792
1830
|
endTurn: typeof response.end_turn === "boolean" ? response.end_turn : response.end_turn === void 0 ? "absent" : "invalid"
|
|
1793
1831
|
}
|
|
@@ -1802,10 +1840,14 @@ function createResponsesTerminalController(params) {
|
|
|
1802
1840
|
}
|
|
1803
1841
|
//#endregion
|
|
1804
1842
|
//#region packages/ai/src/transports/openai-responses-stream-internal.ts
|
|
1805
|
-
async function processResponsesStream(openaiStream, output,
|
|
1843
|
+
async function processResponsesStream(openaiStream, output, sink, model, options) {
|
|
1806
1844
|
const streamingToolCalls = createResponsesToolCallTracker();
|
|
1807
1845
|
const outputSlots = createResponsesOutputSlotTracker();
|
|
1808
|
-
const outputs = createResponsesOutputTracker(
|
|
1846
|
+
const outputs = createResponsesOutputTracker({
|
|
1847
|
+
output,
|
|
1848
|
+
canRetryIdentityConflict: options?.canRetryIdentityConflict
|
|
1849
|
+
});
|
|
1850
|
+
const stream = outputs.trackStream(sink);
|
|
1809
1851
|
let terminalResponse;
|
|
1810
1852
|
let incompleteToolCall;
|
|
1811
1853
|
let lastTextBlock = null;
|
|
@@ -1864,11 +1906,6 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
1864
1906
|
return slot;
|
|
1865
1907
|
}
|
|
1866
1908
|
};
|
|
1867
|
-
const resolveOutputItemSlot = (event, item) => {
|
|
1868
|
-
if (item.type === "reasoning") return outputSlots.resolve(event, "thinking");
|
|
1869
|
-
if (item.type === "message") return outputSlots.resolve(event, "text");
|
|
1870
|
-
return readResponsesOutputIndex(event) === void 0 ? void 0 : outputSlots.get(event);
|
|
1871
|
-
};
|
|
1872
1909
|
const materializeDeferredTextSlot = (slot) => {
|
|
1873
1910
|
if (slot.block || slot.pendingText === null) return;
|
|
1874
1911
|
const text = slot.pendingText;
|
|
@@ -1984,6 +2021,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
1984
2021
|
}), options?.signal);
|
|
1985
2022
|
try {
|
|
1986
2023
|
for await (const event of guardedStream) {
|
|
2024
|
+
outputs.observeEvent(event);
|
|
1987
2025
|
notifyLlmRequestActivity(options?.signal);
|
|
1988
2026
|
if (event.type === "response.output_item.done" && event.item.type === "function_call" && event.item.status === "incomplete") incompleteToolCall ??= event.item;
|
|
1989
2027
|
if (incompleteToolCall && event.type !== "response.completed" && event.type !== "response.incomplete" && event.type !== "response.failed" && event.type !== "error") continue;
|
|
@@ -2134,7 +2172,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2134
2172
|
} else if (event.type === "response.output_item.done") {
|
|
2135
2173
|
const item = event.item;
|
|
2136
2174
|
if (item.type !== "message") lastTextBlock = null;
|
|
2137
|
-
const existingOutputSlot =
|
|
2175
|
+
const existingOutputSlot = outputSlots.resolveOutputItem(event, item);
|
|
2138
2176
|
materializeDeferredTextSlots(existingOutputSlot);
|
|
2139
2177
|
const outputSlot = existingOutputSlot ?? createOutputSlot(event, item);
|
|
2140
2178
|
compactionTracker.completed(item, blocks.length);
|
|
@@ -2216,10 +2254,10 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2216
2254
|
const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
|
|
2217
2255
|
if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
|
|
2218
2256
|
const streamedArguments = streamingToolCall?.block.partialJson || "";
|
|
2219
|
-
const
|
|
2257
|
+
const parsedStreamedArguments = streamingToolCall?.argumentStreamReliable && streamingToolCall?.argumentsStreamed && streamedArguments.length > 0 && completedArguments !== void 0 && streamedArguments !== completedArguments ? parseJsonObjectPreservingUnsafeIntegers(streamedArguments) : null;
|
|
2220
2258
|
const validated = resolveCompletedResponsesToolCall(item, {
|
|
2221
2259
|
name: streamingToolCall?.block.name,
|
|
2222
|
-
arguments:
|
|
2260
|
+
arguments: parsedStreamedArguments ?? (completedArguments || streamedArguments)
|
|
2223
2261
|
});
|
|
2224
2262
|
finalizeToolCall(item, readResponsesOutputIndex(event), streamingToolCall, validated);
|
|
2225
2263
|
}
|
|
@@ -2241,8 +2279,15 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2241
2279
|
terminalResponse = event.type === "response.completed" ? event.response : null;
|
|
2242
2280
|
if (output.stopReason === "stop" && output.content.some((block) => block.type === "toolCall")) output.stopReason = "toolUse";
|
|
2243
2281
|
break;
|
|
2244
|
-
} else if (event.type === "error")
|
|
2245
|
-
|
|
2282
|
+
} else if (event.type === "error") {
|
|
2283
|
+
const details = isRecord(event) && isRecord(event.error) ? event.error : event;
|
|
2284
|
+
const message = readStringValue(details.message);
|
|
2285
|
+
const code = normalizeStringifiedOptionalString(details.code);
|
|
2286
|
+
throw Object.assign(new Error(message ? code ? `Error Code ${code}: ${message}` : message : "Unknown error"), {
|
|
2287
|
+
code: details.code,
|
|
2288
|
+
error: details
|
|
2289
|
+
});
|
|
2290
|
+
} else if (event.type === "response.failed") {
|
|
2246
2291
|
const failure = normalizeResponsesFailedEvent(isRecord(event) ? event : {}, model);
|
|
2247
2292
|
terminal.finalizeFailedResponse(event.response, failure.responseId);
|
|
2248
2293
|
throw new ResponsesStreamFailure(failure, event.response);
|
|
@@ -2257,6 +2302,17 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2257
2302
|
}
|
|
2258
2303
|
}
|
|
2259
2304
|
//#endregion
|
|
2305
|
+
//#region packages/ai/src/providers/openai-provider-refusal.ts
|
|
2306
|
+
/** Responses uses snake_case; the ChatGPT app-server error envelope uses camelCase. */
|
|
2307
|
+
function readOpenAIMisalignmentReview(value, continuationSupported) {
|
|
2308
|
+
if (!isRecord(value)) return;
|
|
2309
|
+
return readProviderRefusalReview({
|
|
2310
|
+
explanation: value.detailed_explanation ?? value.detailedExplanation,
|
|
2311
|
+
errorType: value.error_type ?? value.errorType,
|
|
2312
|
+
...continuationSupported ? { continuation: value.steer } : {}
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
//#endregion
|
|
2260
2316
|
//#region packages/ai/src/providers/openai-responses-tools.ts
|
|
2261
2317
|
/** Projects direct provider descriptors before resolving their strict policy. */
|
|
2262
2318
|
function convertResponsesToolPayload(tools, options) {
|
|
@@ -2293,7 +2349,7 @@ function resolveResponsesStrictToolSetting(options) {
|
|
|
2293
2349
|
if (options?.strict !== void 0) return options.strict;
|
|
2294
2350
|
if (options?.model) return getAiTransportHost().resolveOpenAIStrictToolSetting(options.model, {
|
|
2295
2351
|
transport: "stream",
|
|
2296
|
-
supportsStrictMode: options.supportsStrictMode
|
|
2352
|
+
supportsStrictMode: options.supportsStrictMode ?? resolveOpenAICompletionsCompat(options.model).supportsStrictMode
|
|
2297
2353
|
});
|
|
2298
2354
|
return false;
|
|
2299
2355
|
}
|
|
@@ -2401,6 +2457,7 @@ async function runResponsesStreamLifecycle(params) {
|
|
|
2401
2457
|
onFirstEventTimeout: params.processStreamOptions?.onFirstEventTimeout ?? onFirstEventTimeout,
|
|
2402
2458
|
signal: params.processStreamOptions?.signal ?? options?.signal
|
|
2403
2459
|
} : void 0,
|
|
2460
|
+
canRetryIdentityConflict: () => hasOnlyResponsesFunctionTools(admittedRequest),
|
|
2404
2461
|
reasoningReplayMetadata: buildOpenAIResponsesReasoningReplayMetadata(model, {
|
|
2405
2462
|
sessionId: options?.sessionId,
|
|
2406
2463
|
authProfileId: options?.authProfileId
|
|
@@ -2413,6 +2470,20 @@ async function runResponsesStreamLifecycle(params) {
|
|
|
2413
2470
|
signal: options?.signal
|
|
2414
2471
|
});
|
|
2415
2472
|
} catch (error) {
|
|
2473
|
+
const response = error instanceof ResponsesStreamFailure ? error.response : error;
|
|
2474
|
+
const rawError = isRecord(response) && isRecord(response.error) ? response.error : response;
|
|
2475
|
+
if (params.model.provider === "openai" && params.model.api === "openai-responses" && isRecord(rawError) && rawError.code === "misalignment_policy_violation") {
|
|
2476
|
+
const review = readOpenAIMisalignmentReview(rawError.misalignment, false);
|
|
2477
|
+
appendAssistantMessageDiagnostic(output, {
|
|
2478
|
+
type: "provider_refusal",
|
|
2479
|
+
timestamp: Date.now(),
|
|
2480
|
+
details: {
|
|
2481
|
+
provider: "openai",
|
|
2482
|
+
category: "misalignment",
|
|
2483
|
+
...review ? { review } : {}
|
|
2484
|
+
}
|
|
2485
|
+
});
|
|
2486
|
+
}
|
|
2416
2487
|
failTransportStream({
|
|
2417
2488
|
stream,
|
|
2418
2489
|
output,
|
|
@@ -2425,4 +2496,4 @@ async function runResponsesStreamLifecycle(params) {
|
|
|
2425
2496
|
}
|
|
2426
2497
|
}
|
|
2427
2498
|
//#endregion
|
|
2428
|
-
export {
|
|
2499
|
+
export { summarizeOpenAITransportError as A, resolveResponsesContinuationRequest as B, createResponsesStreamWithEncryptedContentRetry as C, ResponsesStreamFailure as D, resolveNextResponsesEncryptedContentAttempt as E, convertResponsesMessages$1 as F, supportsResponsesReasoningUpdate as G, responsesContinuationRequestFingerprint as H, createOpenAIResponsesAssistantOutput as I, captureOpenAIResponsesCompaction as J, CompactionReplayRefreshRequiredError as K, recordResponsesInputReplay as L, recordResponsesContextUsage as M, resolveResponsesContextUsageBoundary as N, logResponsesFailedNoDetails as O, buildResponsesInputMessage as P, resolveReplayableResponsesMessageId as Q, responsesInputFingerprint as R, commitResponsesEncryptedContentAttempt as S, resolveAzureOpenAIApiVersion as T, isConfigurationUpdate as U, responsesContinuationPrefixFingerprint as V, replayResponsesReasoningUpdates as W, resolveNewestOpenAIResponsesCompactionReplay as X, isOpenAIResponsesReplayContext as Y, suppressOpenAIResponsesCompaction as Z, isAzureResponsesTextDeltaEvent as _, runResponsesStreamLifecycle as a, isResponsesTextDeltaEventType as b, readOpenAIMisalignmentReview as c, createResponsesToolCallTracker as d, readResponsesToolCallItemIdentity as f, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as g, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as h, createResponsesAssistantOutput as i, summarizeResponsesPayload as j, safeDebugValue as k, processResponsesStream as l, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as m, applyResponsesServiceTierPricing as n, convertResponsesToolPayload as o, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as p, buildOpenAIResponsesReasoningReplayMetadata as q, convertResponsesMessages as r, prepareResponsesTools as s, applyCommonResponsesParams as t, observeResponsesStream as u, isAzureResponsesTextDeltaEventType as v, isInvalidEncryptedContentError as w, resolveResponsesMessageSnapshotCollapse as x, isResponsesTextContentPartType as y, claimOpenAIResponsesHttpContinuation as z };
|