@earendil-works/pi-ai 0.80.6 → 0.80.7
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/README.md +3 -2
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +95 -46
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +14 -7
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts +1 -0
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +6 -3
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +12 -3
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts +3 -1
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +51 -0
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts +1 -0
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +24 -8
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/pi-messages.d.ts +97 -0
- package/dist/api/pi-messages.d.ts.map +1 -0
- package/dist/api/pi-messages.js +309 -0
- package/dist/api/pi-messages.js.map +1 -0
- package/dist/api/pi-messages.lazy.d.ts +3 -0
- package/dist/api/pi-messages.lazy.d.ts.map +1 -0
- package/dist/api/pi-messages.lazy.js +3 -0
- package/dist/api/pi-messages.lazy.js.map +1 -0
- package/dist/compat.d.ts +2 -0
- package/dist/compat.d.ts.map +1 -1
- package/dist/compat.js +5 -1
- package/dist/compat.js.map +1 -1
- package/dist/env-api-keys.d.ts.map +1 -1
- package/dist/env-api-keys.js +1 -0
- package/dist/env-api-keys.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/models.generated.d.ts +498 -180
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/providers/all.d.ts +9 -5
- package/dist/providers/all.d.ts.map +1 -1
- package/dist/providers/all.js.map +1 -1
- package/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/dist/providers/amazon-bedrock.js +5 -1
- package/dist/providers/amazon-bedrock.js.map +1 -1
- package/dist/providers/amazon-bedrock.models.d.ts +60 -0
- package/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
- package/dist/providers/amazon-bedrock.models.js +54 -0
- package/dist/providers/amazon-bedrock.models.js.map +1 -1
- package/dist/providers/azure-openai-responses.models.d.ts +17 -0
- package/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
- package/dist/providers/azure-openai-responses.models.js +17 -0
- package/dist/providers/azure-openai-responses.models.js.map +1 -1
- package/dist/providers/cerebras.models.d.ts.map +1 -1
- package/dist/providers/cerebras.models.js +1 -1
- package/dist/providers/cerebras.models.js.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.d.ts +92 -0
- package/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
- package/dist/providers/cloudflare-ai-gateway.models.js +72 -0
- package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
- package/dist/providers/cloudflare-auth.d.ts.map +1 -1
- package/dist/providers/cloudflare-auth.js +9 -6
- package/dist/providers/cloudflare-auth.js.map +1 -1
- package/dist/providers/github-copilot.models.d.ts +93 -6
- package/dist/providers/github-copilot.models.d.ts.map +1 -1
- package/dist/providers/github-copilot.models.js +60 -3
- package/dist/providers/github-copilot.models.js.map +1 -1
- package/dist/providers/openai-codex.models.d.ts +18 -0
- package/dist/providers/openai-codex.models.d.ts.map +1 -1
- package/dist/providers/openai-codex.models.js +6 -0
- package/dist/providers/openai-codex.models.js.map +1 -1
- package/dist/providers/openai.models.d.ts +38 -0
- package/dist/providers/openai.models.d.ts.map +1 -1
- package/dist/providers/openai.models.js +24 -0
- package/dist/providers/openai.models.js.map +1 -1
- package/dist/providers/opencode.models.d.ts +123 -0
- package/dist/providers/opencode.models.d.ts.map +1 -1
- package/dist/providers/opencode.models.js +74 -1
- package/dist/providers/opencode.models.js.map +1 -1
- package/dist/providers/openrouter.models.d.ts +28 -43
- package/dist/providers/openrouter.models.d.ts.map +1 -1
- package/dist/providers/openrouter.models.js +92 -109
- package/dist/providers/openrouter.models.js.map +1 -1
- package/dist/providers/vercel-ai-gateway.models.d.ts +7 -109
- package/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
- package/dist/providers/vercel-ai-gateway.models.js +34 -136
- package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
- package/dist/types.d.ts +25 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/deferred-tools.d.ts +9 -0
- package/dist/utils/deferred-tools.d.ts.map +1 -0
- package/dist/utils/deferred-tools.js +36 -0
- package/dist/utils/deferred-tools.js.map +1 -0
- package/dist/utils/estimate.d.ts.map +1 -1
- package/dist/utils/estimate.js +18 -5
- package/dist/utils/estimate.js.map +1 -1
- package/dist/utils/oauth/index.d.ts +1 -0
- package/dist/utils/oauth/index.d.ts.map +1 -1
- package/dist/utils/oauth/index.js +9 -0
- package/dist/utils/oauth/index.js.map +1 -1
- package/dist/utils/oauth/radius.d.ts +39 -0
- package/dist/utils/oauth/radius.d.ts.map +1 -0
- package/dist/utils/oauth/radius.js +415 -0
- package/dist/utils/oauth/radius.js.map +1 -0
- package/package.json +1 -1
|
@@ -36,6 +36,7 @@ function parseTextSignature(signature) {
|
|
|
36
36
|
// =============================================================================
|
|
37
37
|
export function convertResponsesMessages(model, context, allowedToolCallProviders, options) {
|
|
38
38
|
const messages = [];
|
|
39
|
+
const loadedToolNames = new Set();
|
|
39
40
|
const normalizeIdPart = (part) => {
|
|
40
41
|
const sanitized = part.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
41
42
|
const normalized = sanitized.length > 64 ? sanitized.slice(0, 64) : sanitized;
|
|
@@ -196,6 +197,32 @@ export function convertResponsesMessages(model, context, allowedToolCallProvider
|
|
|
196
197
|
call_id: callId,
|
|
197
198
|
output,
|
|
198
199
|
});
|
|
200
|
+
const deferredTools = [];
|
|
201
|
+
for (const name of msg.addedToolNames ?? []) {
|
|
202
|
+
const tool = options?.deferredTools?.get(name);
|
|
203
|
+
if (!tool || loadedToolNames.has(name))
|
|
204
|
+
continue;
|
|
205
|
+
loadedToolNames.add(name);
|
|
206
|
+
deferredTools.push(tool);
|
|
207
|
+
}
|
|
208
|
+
if (deferredTools.length > 0) {
|
|
209
|
+
const names = deferredTools.map((tool) => tool.name);
|
|
210
|
+
const searchCallId = `pi_tool_load_${shortHash(`${msg.toolCallId}:${names.join(",")}`)}`;
|
|
211
|
+
messages.push({
|
|
212
|
+
type: "tool_search_call",
|
|
213
|
+
call_id: searchCallId,
|
|
214
|
+
execution: "client",
|
|
215
|
+
status: "completed",
|
|
216
|
+
arguments: { query: names.join(" "), limit: names.length },
|
|
217
|
+
});
|
|
218
|
+
messages.push({
|
|
219
|
+
type: "tool_search_output",
|
|
220
|
+
call_id: searchCallId,
|
|
221
|
+
execution: "client",
|
|
222
|
+
status: "completed",
|
|
223
|
+
tools: convertResponsesTools(deferredTools, { deferLoading: true }),
|
|
224
|
+
});
|
|
225
|
+
}
|
|
199
226
|
}
|
|
200
227
|
msgIndex++;
|
|
201
228
|
}
|
|
@@ -212,11 +239,13 @@ export function convertResponsesTools(tools, options) {
|
|
|
212
239
|
description: tool.description,
|
|
213
240
|
parameters: tool.parameters, // TypeBox already generates JSON Schema
|
|
214
241
|
strict,
|
|
242
|
+
...(options?.deferLoading ? { defer_loading: true } : {}),
|
|
215
243
|
}));
|
|
216
244
|
}
|
|
217
245
|
export async function processResponsesStream(openaiStream, output, stream, model, options) {
|
|
218
246
|
let sawTerminalResponseEvent = false;
|
|
219
247
|
const outputSlots = new Map();
|
|
248
|
+
const reasoningBlocksById = new Map();
|
|
220
249
|
const getSlot = (outputIndex, type) => {
|
|
221
250
|
const slot = outputSlots.get(outputIndex);
|
|
222
251
|
return slot?.type === type ? slot : undefined;
|
|
@@ -265,8 +294,29 @@ export async function processResponsesStream(openaiStream, output, stream, model
|
|
|
265
294
|
const getOrCreateSlot = (outputIndex, item) => {
|
|
266
295
|
return outputSlots.get(outputIndex) ?? createSlot(outputIndex, item);
|
|
267
296
|
};
|
|
297
|
+
// Azure OpenAI can omit reasoning.encrypted_content from response.output_item.done
|
|
298
|
+
// and provide it only in response.completed.response.output. Backfill the
|
|
299
|
+
// persisted reasoning signature from the terminal response to keep store:false
|
|
300
|
+
// multi-turn replay stateless. See https://github.com/earendil-works/pi/issues/6409.
|
|
301
|
+
const backfillReasoningSignatures = (responseOutput) => {
|
|
302
|
+
for (const item of responseOutput) {
|
|
303
|
+
if (item.type !== "reasoning" || !item.encrypted_content)
|
|
304
|
+
continue;
|
|
305
|
+
const block = reasoningBlocksById.get(item.id);
|
|
306
|
+
if (!block?.thinkingSignature)
|
|
307
|
+
continue;
|
|
308
|
+
const storedItem = JSON.parse(block.thinkingSignature);
|
|
309
|
+
if (storedItem.encrypted_content)
|
|
310
|
+
continue;
|
|
311
|
+
block.thinkingSignature = JSON.stringify({
|
|
312
|
+
...storedItem,
|
|
313
|
+
encrypted_content: item.encrypted_content,
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
};
|
|
268
317
|
const finalizeResponse = (response) => {
|
|
269
318
|
sawTerminalResponseEvent = true;
|
|
319
|
+
backfillReasoningSignatures(response.output ?? []);
|
|
270
320
|
if (response?.id) {
|
|
271
321
|
output.responseId = response.id;
|
|
272
322
|
}
|
|
@@ -405,6 +455,7 @@ export async function processResponsesStream(openaiStream, output, stream, model
|
|
|
405
455
|
const contentText = item.content?.map((c) => c.text).join("\n\n") || "";
|
|
406
456
|
slot.block.thinking = summaryText || contentText || slot.block.thinking;
|
|
407
457
|
slot.block.thinkingSignature = JSON.stringify(item);
|
|
458
|
+
reasoningBlocksById.set(item.id, slot.block);
|
|
408
459
|
stream.push({
|
|
409
460
|
type: "thinking_end",
|
|
410
461
|
contentIndex: slot.contentIndex,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-responses-shared.js","sourceRoot":"","sources":["../../src/api/openai-responses-shared.ts"],"names":[],"mappings":"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","sourcesContent":["import type OpenAI from \"openai\";\nimport type {\n\tTool as OpenAITool,\n\tResponseCreateParamsStreaming,\n\tResponseFunctionCallOutputItemList,\n\tResponseInput,\n\tResponseInputContent,\n\tResponseInputImage,\n\tResponseInputText,\n\tResponseOutputItem,\n\tResponseOutputMessage,\n\tResponseReasoningItem,\n\tResponseStreamEvent,\n} from \"openai/resources/responses/responses.js\";\nimport { calculateCost } from \"../models.ts\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tContext,\n\tImageContent,\n\tModel,\n\tStopReason,\n\tTextContent,\n\tTextSignatureV1,\n\tThinkingContent,\n\tTool,\n\tToolCall,\n\tUsage,\n} from \"../types.ts\";\nimport type { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { shortHash } from \"../utils/hash.ts\";\nimport { parseStreamingJson } from \"../utils/json-parse.ts\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.ts\";\nimport { transformMessages } from \"./transform-messages.ts\";\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\nfunction encodeTextSignatureV1(id: string, phase?: TextSignatureV1[\"phase\"]): string {\n\tconst payload: TextSignatureV1 = { v: 1, id };\n\tif (phase) payload.phase = phase;\n\treturn JSON.stringify(payload);\n}\n\nfunction parseTextSignature(\n\tsignature: string | undefined,\n): { id: string; phase?: TextSignatureV1[\"phase\"] } | undefined {\n\tif (!signature) return undefined;\n\tif (signature.startsWith(\"{\")) {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(signature) as Partial<TextSignatureV1>;\n\t\t\tif (parsed.v === 1 && typeof parsed.id === \"string\") {\n\t\t\t\tif (parsed.phase === \"commentary\" || parsed.phase === \"final_answer\") {\n\t\t\t\t\treturn { id: parsed.id, phase: parsed.phase };\n\t\t\t\t}\n\t\t\t\treturn { id: parsed.id };\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to legacy plain-string handling.\n\t\t}\n\t}\n\treturn { id: signature };\n}\n\nexport interface OpenAIResponsesStreamOptions {\n\tserviceTier?: ResponseCreateParamsStreaming[\"service_tier\"];\n\tresolveServiceTier?: (\n\t\tresponseServiceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\t\trequestServiceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\t) => ResponseCreateParamsStreaming[\"service_tier\"] | undefined;\n\tapplyServiceTierPricing?: (\n\t\tusage: Usage,\n\t\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\t) => void;\n}\n\nexport interface ConvertResponsesMessagesOptions {\n\tincludeSystemPrompt?: boolean;\n}\n\nexport interface ConvertResponsesToolsOptions {\n\tstrict?: boolean | null;\n}\n\n// =============================================================================\n// Message conversion\n// =============================================================================\n\nexport function convertResponsesMessages<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\tallowedToolCallProviders: ReadonlySet<string>,\n\toptions?: ConvertResponsesMessagesOptions,\n): ResponseInput {\n\tconst messages: ResponseInput = [];\n\n\tconst normalizeIdPart = (part: string): string => {\n\t\tconst sanitized = part.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n\t\tconst normalized = sanitized.length > 64 ? sanitized.slice(0, 64) : sanitized;\n\t\treturn normalized.replace(/_+$/, \"\");\n\t};\n\n\tconst buildForeignResponsesItemId = (itemId: string): string => {\n\t\tconst normalized = `fc_${shortHash(itemId)}`;\n\t\treturn normalized.length > 64 ? normalized.slice(0, 64) : normalized;\n\t};\n\n\tconst normalizeToolCallId = (id: string, _targetModel: Model<TApi>, source: AssistantMessage): string => {\n\t\tif (!allowedToolCallProviders.has(model.provider)) return normalizeIdPart(id);\n\t\tif (!id.includes(\"|\")) return normalizeIdPart(id);\n\t\tconst [callId, itemId] = id.split(\"|\");\n\t\tconst normalizedCallId = normalizeIdPart(callId);\n\t\tconst isForeignToolCall = source.provider !== model.provider || source.api !== model.api;\n\t\tlet normalizedItemId = isForeignToolCall ? buildForeignResponsesItemId(itemId) : normalizeIdPart(itemId);\n\t\t// OpenAI Responses API requires item id to start with \"fc\"\n\t\tif (!normalizedItemId.startsWith(\"fc_\")) {\n\t\t\tnormalizedItemId = normalizeIdPart(`fc_${normalizedItemId}`);\n\t\t}\n\t\treturn `${normalizedCallId}|${normalizedItemId}`;\n\t};\n\n\tconst transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);\n\n\tconst includeSystemPrompt = options?.includeSystemPrompt ?? true;\n\tif (includeSystemPrompt && context.systemPrompt) {\n\t\tconst compat = model.compat as { supportsDeveloperRole?: boolean } | undefined;\n\t\tconst role = model.reasoning && compat?.supportsDeveloperRole !== false ? \"developer\" : \"system\";\n\t\tmessages.push({\n\t\t\trole,\n\t\t\tcontent: sanitizeSurrogates(context.systemPrompt),\n\t\t});\n\t}\n\n\tlet msgIndex = 0;\n\tfor (const msg of transformedMessages) {\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tmessages.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [{ type: \"input_text\", text: sanitizeSurrogates(msg.content) }],\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst content: ResponseInputContent[] = msg.content.map((item): ResponseInputContent => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"input_text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(item.text),\n\t\t\t\t\t\t} satisfies ResponseInputText;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"input_image\",\n\t\t\t\t\t\tdetail: \"auto\",\n\t\t\t\t\t\timage_url: `data:${item.mimeType};base64,${item.data}`,\n\t\t\t\t\t} satisfies ResponseInputImage;\n\t\t\t\t});\n\t\t\t\tif (content.length === 0) continue;\n\t\t\t\tmessages.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst output: ResponseInput = [];\n\t\t\tconst assistantMsg = msg as AssistantMessage;\n\t\t\tconst isDifferentModel =\n\t\t\t\tassistantMsg.model !== model.id &&\n\t\t\t\tassistantMsg.provider === model.provider &&\n\t\t\t\tassistantMsg.api === model.api;\n\t\t\tlet textBlockIndex = 0;\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"thinking\") {\n\t\t\t\t\tif (block.thinkingSignature) {\n\t\t\t\t\t\tconst reasoningItem = JSON.parse(block.thinkingSignature) as ResponseReasoningItem;\n\t\t\t\t\t\toutput.push(reasoningItem);\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"text\") {\n\t\t\t\t\tconst textBlock = block as TextContent;\n\t\t\t\t\tconst parsedSignature = parseTextSignature(textBlock.textSignature);\n\t\t\t\t\tconst fallbackMessageId =\n\t\t\t\t\t\ttextBlockIndex === 0 ? `msg_pi_${msgIndex}` : `msg_pi_${msgIndex}_${textBlockIndex}`;\n\t\t\t\t\ttextBlockIndex++;\n\t\t\t\t\t// OpenAI requires id to be max 64 characters\n\t\t\t\t\tlet msgId = parsedSignature?.id;\n\t\t\t\t\tif (!msgId) {\n\t\t\t\t\t\tmsgId = fallbackMessageId;\n\t\t\t\t\t} else if (msgId.length > 64) {\n\t\t\t\t\t\tmsgId = `msg_${shortHash(msgId)}`;\n\t\t\t\t\t}\n\t\t\t\t\toutput.push({\n\t\t\t\t\t\ttype: \"message\",\n\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\tcontent: [{ type: \"output_text\", text: sanitizeSurrogates(textBlock.text), annotations: [] }],\n\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\tid: msgId,\n\t\t\t\t\t\tphase: parsedSignature?.phase,\n\t\t\t\t\t} satisfies ResponseOutputMessage);\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tconst toolCall = block as ToolCall;\n\t\t\t\t\tconst [callId, itemIdRaw] = toolCall.id.split(\"|\");\n\t\t\t\t\tlet itemId: string | undefined = itemIdRaw;\n\n\t\t\t\t\t// For different-model messages, set id to undefined to avoid pairing validation.\n\t\t\t\t\t// OpenAI tracks which fc_xxx IDs were paired with rs_xxx reasoning items.\n\t\t\t\t\t// By omitting the id, we avoid triggering that validation (like cross-provider does).\n\t\t\t\t\tif (isDifferentModel && itemId?.startsWith(\"fc_\")) {\n\t\t\t\t\t\titemId = undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push({\n\t\t\t\t\t\ttype: \"function_call\",\n\t\t\t\t\t\tid: itemId,\n\t\t\t\t\t\tcall_id: callId,\n\t\t\t\t\t\tname: toolCall.name,\n\t\t\t\t\t\targuments: JSON.stringify(toolCall.arguments),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (output.length === 0) continue;\n\t\t\tmessages.push(...output);\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\tconst textResult = msg.content\n\t\t\t\t.filter((c): c is TextContent => c.type === \"text\")\n\t\t\t\t.map((c) => c.text)\n\t\t\t\t.join(\"\\n\");\n\t\t\tconst hasImages = msg.content.some((c): c is ImageContent => c.type === \"image\");\n\t\t\tconst hasText = textResult.length > 0;\n\t\t\tconst [callId] = msg.toolCallId.split(\"|\");\n\n\t\t\tlet output: string | ResponseFunctionCallOutputItemList;\n\t\t\tif (hasImages && model.input.includes(\"image\")) {\n\t\t\t\tconst contentParts: ResponseFunctionCallOutputItemList = [];\n\n\t\t\t\tif (hasText) {\n\t\t\t\t\tcontentParts.push({\n\t\t\t\t\t\ttype: \"input_text\",\n\t\t\t\t\t\ttext: sanitizeSurrogates(textResult),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tfor (const block of msg.content) {\n\t\t\t\t\tif (block.type === \"image\") {\n\t\t\t\t\t\tcontentParts.push({\n\t\t\t\t\t\t\ttype: \"input_image\",\n\t\t\t\t\t\t\tdetail: \"auto\",\n\t\t\t\t\t\t\timage_url: `data:${block.mimeType};base64,${block.data}`,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\toutput = contentParts;\n\t\t\t} else {\n\t\t\t\toutput = sanitizeSurrogates(hasText ? textResult : hasImages ? \"(see attached image)\" : \"(no tool output)\");\n\t\t\t}\n\n\t\t\tmessages.push({\n\t\t\t\ttype: \"function_call_output\",\n\t\t\t\tcall_id: callId,\n\t\t\t\toutput,\n\t\t\t});\n\t\t}\n\t\tmsgIndex++;\n\t}\n\n\treturn messages;\n}\n\n// =============================================================================\n// Tool conversion\n// =============================================================================\n\nexport function convertResponsesTools(tools: Tool[], options?: ConvertResponsesToolsOptions): OpenAITool[] {\n\tconst strict = options?.strict === undefined ? false : options.strict;\n\treturn tools.map((tool) => ({\n\t\ttype: \"function\",\n\t\tname: tool.name,\n\t\tdescription: tool.description,\n\t\tparameters: tool.parameters as any, // TypeBox already generates JSON Schema\n\t\tstrict,\n\t}));\n}\n\n// =============================================================================\n// Stream processing\n// =============================================================================\n\ntype StreamingToolCall = ToolCall & { partialJson: string };\n\ntype ResponsesOutputSlot =\n\t| { type: \"thinking\"; block: ThinkingContent; contentIndex: number }\n\t| { type: \"text\"; block: TextContent; contentIndex: number }\n\t| { type: \"toolCall\"; block: StreamingToolCall; contentIndex: number };\n\nexport async function processResponsesStream<TApi extends Api>(\n\topenaiStream: AsyncIterable<ResponseStreamEvent>,\n\toutput: AssistantMessage,\n\tstream: AssistantMessageEventStream,\n\tmodel: Model<TApi>,\n\toptions?: OpenAIResponsesStreamOptions,\n): Promise<void> {\n\tlet sawTerminalResponseEvent = false;\n\tconst outputSlots = new Map<number, ResponsesOutputSlot>();\n\tconst getSlot = <TType extends ResponsesOutputSlot[\"type\"]>(\n\t\toutputIndex: number,\n\t\ttype: TType,\n\t): Extract<ResponsesOutputSlot, { type: TType }> | undefined => {\n\t\tconst slot = outputSlots.get(outputIndex);\n\t\treturn slot?.type === type ? (slot as Extract<ResponsesOutputSlot, { type: TType }>) : undefined;\n\t};\n\tconst createSlot = (outputIndex: number, item: ResponseOutputItem): ResponsesOutputSlot | undefined => {\n\t\tif (item.type === \"reasoning\") {\n\t\t\tconst block: ThinkingContent = { type: \"thinking\", thinking: \"\" };\n\t\t\toutput.content.push(block);\n\t\t\tconst slot = {\n\t\t\t\ttype: \"thinking\",\n\t\t\t\tblock,\n\t\t\t\tcontentIndex: output.content.length - 1,\n\t\t\t} satisfies ResponsesOutputSlot;\n\t\t\toutputSlots.set(outputIndex, slot);\n\t\t\tstream.push({ type: \"thinking_start\", contentIndex: slot.contentIndex, partial: output });\n\t\t\treturn slot;\n\t\t}\n\t\tif (item.type === \"message\") {\n\t\t\tconst block: TextContent = { type: \"text\", text: \"\" };\n\t\t\toutput.content.push(block);\n\t\t\tconst slot = { type: \"text\", block, contentIndex: output.content.length - 1 } satisfies ResponsesOutputSlot;\n\t\t\toutputSlots.set(outputIndex, slot);\n\t\t\tstream.push({ type: \"text_start\", contentIndex: slot.contentIndex, partial: output });\n\t\t\treturn slot;\n\t\t}\n\t\tif (item.type === \"function_call\") {\n\t\t\tconst block: StreamingToolCall = {\n\t\t\t\ttype: \"toolCall\",\n\t\t\t\tid: `${item.call_id}|${item.id}`,\n\t\t\t\tname: item.name,\n\t\t\t\targuments: {},\n\t\t\t\tpartialJson: item.arguments || \"\",\n\t\t\t};\n\t\t\toutput.content.push(block);\n\t\t\tconst slot = {\n\t\t\t\ttype: \"toolCall\",\n\t\t\t\tblock,\n\t\t\t\tcontentIndex: output.content.length - 1,\n\t\t\t} satisfies ResponsesOutputSlot;\n\t\t\toutputSlots.set(outputIndex, slot);\n\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: slot.contentIndex, partial: output });\n\t\t\treturn slot;\n\t\t}\n\t\treturn undefined;\n\t};\n\tconst getOrCreateSlot = (outputIndex: number, item: ResponseOutputItem): ResponsesOutputSlot | undefined => {\n\t\treturn outputSlots.get(outputIndex) ?? createSlot(outputIndex, item);\n\t};\n\tconst finalizeResponse = (\n\t\tresponse: Extract<ResponseStreamEvent, { type: \"response.completed\" | \"response.incomplete\" }>[\"response\"],\n\t): void => {\n\t\tsawTerminalResponseEvent = true;\n\t\tif (response?.id) {\n\t\t\toutput.responseId = response.id;\n\t\t}\n\t\tif (response?.usage) {\n\t\t\tconst inputDetails = response.usage.input_tokens_details as\n\t\t\t\t| { cached_tokens?: number; cache_write_tokens?: number }\n\t\t\t\t| undefined;\n\t\t\tconst cachedTokens = inputDetails?.cached_tokens || 0;\n\t\t\tconst cacheWriteTokens = inputDetails?.cache_write_tokens || 0;\n\t\t\toutput.usage = {\n\t\t\t\t// OpenAI includes cached and cache-write tokens in input_tokens, so subtract both.\n\t\t\t\tinput: Math.max(0, (response.usage.input_tokens || 0) - cachedTokens - cacheWriteTokens),\n\t\t\t\toutput: response.usage.output_tokens || 0,\n\t\t\t\tcacheRead: cachedTokens,\n\t\t\t\tcacheWrite: cacheWriteTokens,\n\t\t\t\treasoning: response.usage.output_tokens_details?.reasoning_tokens || 0,\n\t\t\t\ttotalTokens: response.usage.total_tokens || 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t};\n\t\t}\n\t\tcalculateCost(model, output.usage);\n\t\tif (options?.applyServiceTierPricing) {\n\t\t\tconst serviceTier = options.resolveServiceTier\n\t\t\t\t? options.resolveServiceTier(response?.service_tier, options.serviceTier)\n\t\t\t\t: (response?.service_tier ?? options.serviceTier);\n\t\t\toptions.applyServiceTierPricing(output.usage, serviceTier);\n\t\t}\n\t\t// Map status to stop reason\n\t\toutput.stopReason = mapStopReason(response?.status);\n\t\tif (output.content.some((b) => b.type === \"toolCall\") && output.stopReason === \"stop\") {\n\t\t\toutput.stopReason = \"toolUse\";\n\t\t}\n\t};\n\n\tfor await (const event of openaiStream) {\n\t\tif (event.type === \"response.created\") {\n\t\t\toutput.responseId = event.response.id;\n\t\t} else if (event.type === \"response.output_item.added\") {\n\t\t\tcreateSlot(event.output_index, event.item);\n\t\t} else if (event.type === \"response.reasoning_summary_text.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"thinking\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.thinking += event.delta;\n\t\t\tstream.push({\n\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.reasoning_summary_part.done\") {\n\t\t\tconst slot = getSlot(event.output_index, \"thinking\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.thinking += \"\\n\\n\";\n\t\t\tstream.push({\n\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: \"\\n\\n\",\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.reasoning_text.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"thinking\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.thinking += event.delta;\n\t\t\tstream.push({\n\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.output_text.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"text\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.text += event.delta;\n\t\t\tstream.push({\n\t\t\t\ttype: \"text_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.refusal.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"text\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.text += event.delta;\n\t\t\tstream.push({\n\t\t\t\ttype: \"text_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.function_call_arguments.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"toolCall\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.partialJson += event.delta;\n\t\t\tslot.block.arguments = parseStreamingJson(slot.block.partialJson);\n\t\t\tstream.push({\n\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.function_call_arguments.done\") {\n\t\t\tconst slot = getSlot(event.output_index, \"toolCall\");\n\t\t\tif (!slot) continue;\n\t\t\tconst previousPartialJson = slot.block.partialJson;\n\t\t\tslot.block.partialJson = event.arguments;\n\t\t\tslot.block.arguments = parseStreamingJson(slot.block.partialJson);\n\n\t\t\tif (event.arguments.startsWith(previousPartialJson)) {\n\t\t\t\tconst delta = event.arguments.slice(previousPartialJson.length);\n\t\t\t\tif (delta.length > 0) {\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\t\t\tdelta,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (event.type === \"response.output_item.done\") {\n\t\t\tconst item = event.item;\n\t\t\tconst slot = getOrCreateSlot(event.output_index, item);\n\n\t\t\tif (item.type === \"reasoning\" && slot?.type === \"thinking\") {\n\t\t\t\tconst summaryText = item.summary?.map((s) => s.text).join(\"\\n\\n\") || \"\";\n\t\t\t\tconst contentText = item.content?.map((c) => c.text).join(\"\\n\\n\") || \"\";\n\t\t\t\tslot.block.thinking = summaryText || contentText || slot.block.thinking;\n\t\t\t\tslot.block.thinkingSignature = JSON.stringify(item);\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\t\tcontent: slot.block.thinking,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\toutputSlots.delete(event.output_index);\n\t\t\t} else if (item.type === \"message\" && slot?.type === \"text\") {\n\t\t\t\tslot.block.text = item.content?.map((c) => (c.type === \"output_text\" ? c.text : c.refusal)).join(\"\") || \"\";\n\t\t\t\tslot.block.textSignature = encodeTextSignatureV1(item.id, item.phase ?? undefined);\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\t\tcontent: slot.block.text,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\toutputSlots.delete(event.output_index);\n\t\t\t} else if (item.type === \"function_call\" && slot?.type === \"toolCall\") {\n\t\t\t\tslot.block.arguments = parseStreamingJson(item.arguments || slot.block.partialJson || \"{}\");\n\t\t\t\t// Finalize in-place and strip the scratch buffer so replay only\n\t\t\t\t// carries parsed arguments.\n\t\t\t\tdelete (slot.block as { partialJson?: string }).partialJson;\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"toolcall_end\",\n\t\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\t\ttoolCall: slot.block,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\toutputSlots.delete(event.output_index);\n\t\t\t}\n\t\t} else if (event.type === \"response.completed\" || event.type === \"response.incomplete\") {\n\t\t\tfinalizeResponse(event.response);\n\t\t} else if (event.type === \"error\") {\n\t\t\tthrow new Error(`Error Code ${event.code}: ${event.message}` || \"Unknown error\");\n\t\t} else if (event.type === \"response.failed\") {\n\t\t\tsawTerminalResponseEvent = true;\n\t\t\tconst error = event.response?.error;\n\t\t\tconst details = event.response?.incomplete_details;\n\t\t\tconst msg = error\n\t\t\t\t? `${error.code || \"unknown\"}: ${error.message || \"no message\"}`\n\t\t\t\t: details?.reason\n\t\t\t\t\t? `incomplete: ${details.reason}`\n\t\t\t\t\t: \"Unknown error (no error details in response)\";\n\t\t\tthrow new Error(msg);\n\t\t}\n\t}\n\tif (!sawTerminalResponseEvent) {\n\t\tthrow new Error(\"OpenAI Responses stream ended before a terminal response event\");\n\t}\n}\n\nfunction mapStopReason(status: OpenAI.Responses.ResponseStatus | undefined): StopReason {\n\tif (!status) return \"stop\";\n\tswitch (status) {\n\t\tcase \"completed\":\n\t\t\treturn \"stop\";\n\t\tcase \"incomplete\":\n\t\t\treturn \"length\";\n\t\tcase \"failed\":\n\t\tcase \"cancelled\":\n\t\t\treturn \"error\";\n\t\t// These two are wonky ...\n\t\tcase \"in_progress\":\n\t\tcase \"queued\":\n\t\t\treturn \"stop\";\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = status;\n\t\t\tthrow new Error(`Unhandled stop reason: ${_exhaustive}`);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"openai-responses-shared.js","sourceRoot":"","sources":["../../src/api/openai-responses-shared.ts"],"names":[],"mappings":"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","sourcesContent":["import type OpenAI from \"openai\";\nimport type {\n\tTool as OpenAITool,\n\tResponseCreateParamsStreaming,\n\tResponseFunctionCallOutputItemList,\n\tResponseInput,\n\tResponseInputContent,\n\tResponseInputImage,\n\tResponseInputItem,\n\tResponseInputText,\n\tResponseOutputItem,\n\tResponseOutputMessage,\n\tResponseReasoningItem,\n\tResponseStreamEvent,\n\tResponseToolSearchOutputItemParam,\n} from \"openai/resources/responses/responses.js\";\nimport { calculateCost } from \"../models.ts\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tContext,\n\tImageContent,\n\tModel,\n\tStopReason,\n\tTextContent,\n\tTextSignatureV1,\n\tThinkingContent,\n\tTool,\n\tToolCall,\n\tUsage,\n} from \"../types.ts\";\nimport type { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { shortHash } from \"../utils/hash.ts\";\nimport { parseStreamingJson } from \"../utils/json-parse.ts\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.ts\";\nimport { transformMessages } from \"./transform-messages.ts\";\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\nfunction encodeTextSignatureV1(id: string, phase?: TextSignatureV1[\"phase\"]): string {\n\tconst payload: TextSignatureV1 = { v: 1, id };\n\tif (phase) payload.phase = phase;\n\treturn JSON.stringify(payload);\n}\n\nfunction parseTextSignature(\n\tsignature: string | undefined,\n): { id: string; phase?: TextSignatureV1[\"phase\"] } | undefined {\n\tif (!signature) return undefined;\n\tif (signature.startsWith(\"{\")) {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(signature) as Partial<TextSignatureV1>;\n\t\t\tif (parsed.v === 1 && typeof parsed.id === \"string\") {\n\t\t\t\tif (parsed.phase === \"commentary\" || parsed.phase === \"final_answer\") {\n\t\t\t\t\treturn { id: parsed.id, phase: parsed.phase };\n\t\t\t\t}\n\t\t\t\treturn { id: parsed.id };\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to legacy plain-string handling.\n\t\t}\n\t}\n\treturn { id: signature };\n}\n\nexport interface OpenAIResponsesStreamOptions {\n\tserviceTier?: ResponseCreateParamsStreaming[\"service_tier\"];\n\tresolveServiceTier?: (\n\t\tresponseServiceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\t\trequestServiceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\t) => ResponseCreateParamsStreaming[\"service_tier\"] | undefined;\n\tapplyServiceTierPricing?: (\n\t\tusage: Usage,\n\t\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\t) => void;\n}\n\nexport interface ConvertResponsesMessagesOptions {\n\tincludeSystemPrompt?: boolean;\n\tdeferredTools?: ReadonlyMap<string, Tool>;\n}\n\nexport interface ConvertResponsesToolsOptions {\n\tstrict?: boolean | null;\n\tdeferLoading?: boolean;\n}\n\ntype OpenAIFunctionTool = Extract<OpenAITool, { type: \"function\" }>;\n\n// =============================================================================\n// Message conversion\n// =============================================================================\n\nexport function convertResponsesMessages<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\tallowedToolCallProviders: ReadonlySet<string>,\n\toptions?: ConvertResponsesMessagesOptions,\n): ResponseInput {\n\tconst messages: ResponseInput = [];\n\tconst loadedToolNames = new Set<string>();\n\n\tconst normalizeIdPart = (part: string): string => {\n\t\tconst sanitized = part.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n\t\tconst normalized = sanitized.length > 64 ? sanitized.slice(0, 64) : sanitized;\n\t\treturn normalized.replace(/_+$/, \"\");\n\t};\n\n\tconst buildForeignResponsesItemId = (itemId: string): string => {\n\t\tconst normalized = `fc_${shortHash(itemId)}`;\n\t\treturn normalized.length > 64 ? normalized.slice(0, 64) : normalized;\n\t};\n\n\tconst normalizeToolCallId = (id: string, _targetModel: Model<TApi>, source: AssistantMessage): string => {\n\t\tif (!allowedToolCallProviders.has(model.provider)) return normalizeIdPart(id);\n\t\tif (!id.includes(\"|\")) return normalizeIdPart(id);\n\t\tconst [callId, itemId] = id.split(\"|\");\n\t\tconst normalizedCallId = normalizeIdPart(callId);\n\t\tconst isForeignToolCall = source.provider !== model.provider || source.api !== model.api;\n\t\tlet normalizedItemId = isForeignToolCall ? buildForeignResponsesItemId(itemId) : normalizeIdPart(itemId);\n\t\t// OpenAI Responses API requires item id to start with \"fc\"\n\t\tif (!normalizedItemId.startsWith(\"fc_\")) {\n\t\t\tnormalizedItemId = normalizeIdPart(`fc_${normalizedItemId}`);\n\t\t}\n\t\treturn `${normalizedCallId}|${normalizedItemId}`;\n\t};\n\n\tconst transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);\n\n\tconst includeSystemPrompt = options?.includeSystemPrompt ?? true;\n\tif (includeSystemPrompt && context.systemPrompt) {\n\t\tconst compat = model.compat as { supportsDeveloperRole?: boolean } | undefined;\n\t\tconst role = model.reasoning && compat?.supportsDeveloperRole !== false ? \"developer\" : \"system\";\n\t\tmessages.push({\n\t\t\trole,\n\t\t\tcontent: sanitizeSurrogates(context.systemPrompt),\n\t\t});\n\t}\n\n\tlet msgIndex = 0;\n\tfor (const msg of transformedMessages) {\n\t\tif (msg.role === \"user\") {\n\t\t\tif (typeof msg.content === \"string\") {\n\t\t\t\tmessages.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [{ type: \"input_text\", text: sanitizeSurrogates(msg.content) }],\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst content: ResponseInputContent[] = msg.content.map((item): ResponseInputContent => {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"input_text\",\n\t\t\t\t\t\t\ttext: sanitizeSurrogates(item.text),\n\t\t\t\t\t\t} satisfies ResponseInputText;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"input_image\",\n\t\t\t\t\t\tdetail: \"auto\",\n\t\t\t\t\t\timage_url: `data:${item.mimeType};base64,${item.data}`,\n\t\t\t\t\t} satisfies ResponseInputImage;\n\t\t\t\t});\n\t\t\t\tif (content.length === 0) continue;\n\t\t\t\tmessages.push({\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst output: ResponseInput = [];\n\t\t\tconst assistantMsg = msg as AssistantMessage;\n\t\t\tconst isDifferentModel =\n\t\t\t\tassistantMsg.model !== model.id &&\n\t\t\t\tassistantMsg.provider === model.provider &&\n\t\t\t\tassistantMsg.api === model.api;\n\t\t\tlet textBlockIndex = 0;\n\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"thinking\") {\n\t\t\t\t\tif (block.thinkingSignature) {\n\t\t\t\t\t\tconst reasoningItem = JSON.parse(block.thinkingSignature) as ResponseReasoningItem;\n\t\t\t\t\t\toutput.push(reasoningItem);\n\t\t\t\t\t}\n\t\t\t\t} else if (block.type === \"text\") {\n\t\t\t\t\tconst textBlock = block as TextContent;\n\t\t\t\t\tconst parsedSignature = parseTextSignature(textBlock.textSignature);\n\t\t\t\t\tconst fallbackMessageId =\n\t\t\t\t\t\ttextBlockIndex === 0 ? `msg_pi_${msgIndex}` : `msg_pi_${msgIndex}_${textBlockIndex}`;\n\t\t\t\t\ttextBlockIndex++;\n\t\t\t\t\t// OpenAI requires id to be max 64 characters\n\t\t\t\t\tlet msgId = parsedSignature?.id;\n\t\t\t\t\tif (!msgId) {\n\t\t\t\t\t\tmsgId = fallbackMessageId;\n\t\t\t\t\t} else if (msgId.length > 64) {\n\t\t\t\t\t\tmsgId = `msg_${shortHash(msgId)}`;\n\t\t\t\t\t}\n\t\t\t\t\toutput.push({\n\t\t\t\t\t\ttype: \"message\",\n\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\tcontent: [{ type: \"output_text\", text: sanitizeSurrogates(textBlock.text), annotations: [] }],\n\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\tid: msgId,\n\t\t\t\t\t\tphase: parsedSignature?.phase,\n\t\t\t\t\t} satisfies ResponseOutputMessage);\n\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\tconst toolCall = block as ToolCall;\n\t\t\t\t\tconst [callId, itemIdRaw] = toolCall.id.split(\"|\");\n\t\t\t\t\tlet itemId: string | undefined = itemIdRaw;\n\n\t\t\t\t\t// For different-model messages, set id to undefined to avoid pairing validation.\n\t\t\t\t\t// OpenAI tracks which fc_xxx IDs were paired with rs_xxx reasoning items.\n\t\t\t\t\t// By omitting the id, we avoid triggering that validation (like cross-provider does).\n\t\t\t\t\tif (isDifferentModel && itemId?.startsWith(\"fc_\")) {\n\t\t\t\t\t\titemId = undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push({\n\t\t\t\t\t\ttype: \"function_call\",\n\t\t\t\t\t\tid: itemId,\n\t\t\t\t\t\tcall_id: callId,\n\t\t\t\t\t\tname: toolCall.name,\n\t\t\t\t\t\targuments: JSON.stringify(toolCall.arguments),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (output.length === 0) continue;\n\t\t\tmessages.push(...output);\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\tconst textResult = msg.content\n\t\t\t\t.filter((c): c is TextContent => c.type === \"text\")\n\t\t\t\t.map((c) => c.text)\n\t\t\t\t.join(\"\\n\");\n\t\t\tconst hasImages = msg.content.some((c): c is ImageContent => c.type === \"image\");\n\t\t\tconst hasText = textResult.length > 0;\n\t\t\tconst [callId] = msg.toolCallId.split(\"|\");\n\n\t\t\tlet output: string | ResponseFunctionCallOutputItemList;\n\t\t\tif (hasImages && model.input.includes(\"image\")) {\n\t\t\t\tconst contentParts: ResponseFunctionCallOutputItemList = [];\n\n\t\t\t\tif (hasText) {\n\t\t\t\t\tcontentParts.push({\n\t\t\t\t\t\ttype: \"input_text\",\n\t\t\t\t\t\ttext: sanitizeSurrogates(textResult),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tfor (const block of msg.content) {\n\t\t\t\t\tif (block.type === \"image\") {\n\t\t\t\t\t\tcontentParts.push({\n\t\t\t\t\t\t\ttype: \"input_image\",\n\t\t\t\t\t\t\tdetail: \"auto\",\n\t\t\t\t\t\t\timage_url: `data:${block.mimeType};base64,${block.data}`,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\toutput = contentParts;\n\t\t\t} else {\n\t\t\t\toutput = sanitizeSurrogates(hasText ? textResult : hasImages ? \"(see attached image)\" : \"(no tool output)\");\n\t\t\t}\n\n\t\t\tmessages.push({\n\t\t\t\ttype: \"function_call_output\",\n\t\t\t\tcall_id: callId,\n\t\t\t\toutput,\n\t\t\t});\n\n\t\t\tconst deferredTools: Tool[] = [];\n\t\t\tfor (const name of msg.addedToolNames ?? []) {\n\t\t\t\tconst tool = options?.deferredTools?.get(name);\n\t\t\t\tif (!tool || loadedToolNames.has(name)) continue;\n\t\t\t\tloadedToolNames.add(name);\n\t\t\t\tdeferredTools.push(tool);\n\t\t\t}\n\t\t\tif (deferredTools.length > 0) {\n\t\t\t\tconst names = deferredTools.map((tool) => tool.name);\n\t\t\t\tconst searchCallId = `pi_tool_load_${shortHash(`${msg.toolCallId}:${names.join(\",\")}`)}`;\n\t\t\t\tmessages.push({\n\t\t\t\t\ttype: \"tool_search_call\",\n\t\t\t\t\tcall_id: searchCallId,\n\t\t\t\t\texecution: \"client\",\n\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\targuments: { query: names.join(\" \"), limit: names.length },\n\t\t\t\t} satisfies ResponseInputItem);\n\t\t\t\tmessages.push({\n\t\t\t\t\ttype: \"tool_search_output\",\n\t\t\t\t\tcall_id: searchCallId,\n\t\t\t\t\texecution: \"client\",\n\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\ttools: convertResponsesTools(deferredTools, { deferLoading: true }),\n\t\t\t\t} satisfies ResponseToolSearchOutputItemParam);\n\t\t\t}\n\t\t}\n\t\tmsgIndex++;\n\t}\n\n\treturn messages;\n}\n\n// =============================================================================\n// Tool conversion\n// =============================================================================\n\nexport function convertResponsesTools(tools: readonly Tool[], options?: ConvertResponsesToolsOptions): OpenAITool[] {\n\tconst strict = options?.strict === undefined ? false : options.strict;\n\treturn tools.map(\n\t\t(tool): OpenAIFunctionTool => ({\n\t\t\ttype: \"function\",\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tparameters: tool.parameters as Record<string, unknown>, // TypeBox already generates JSON Schema\n\t\t\tstrict,\n\t\t\t...(options?.deferLoading ? { defer_loading: true } : {}),\n\t\t}),\n\t);\n}\n\n// =============================================================================\n// Stream processing\n// =============================================================================\n\ntype StreamingToolCall = ToolCall & { partialJson: string };\n\ntype ResponsesOutputSlot =\n\t| { type: \"thinking\"; block: ThinkingContent; contentIndex: number }\n\t| { type: \"text\"; block: TextContent; contentIndex: number }\n\t| { type: \"toolCall\"; block: StreamingToolCall; contentIndex: number };\n\nexport async function processResponsesStream<TApi extends Api>(\n\topenaiStream: AsyncIterable<ResponseStreamEvent>,\n\toutput: AssistantMessage,\n\tstream: AssistantMessageEventStream,\n\tmodel: Model<TApi>,\n\toptions?: OpenAIResponsesStreamOptions,\n): Promise<void> {\n\tlet sawTerminalResponseEvent = false;\n\tconst outputSlots = new Map<number, ResponsesOutputSlot>();\n\tconst reasoningBlocksById = new Map<string, ThinkingContent>();\n\tconst getSlot = <TType extends ResponsesOutputSlot[\"type\"]>(\n\t\toutputIndex: number,\n\t\ttype: TType,\n\t): Extract<ResponsesOutputSlot, { type: TType }> | undefined => {\n\t\tconst slot = outputSlots.get(outputIndex);\n\t\treturn slot?.type === type ? (slot as Extract<ResponsesOutputSlot, { type: TType }>) : undefined;\n\t};\n\tconst createSlot = (outputIndex: number, item: ResponseOutputItem): ResponsesOutputSlot | undefined => {\n\t\tif (item.type === \"reasoning\") {\n\t\t\tconst block: ThinkingContent = { type: \"thinking\", thinking: \"\" };\n\t\t\toutput.content.push(block);\n\t\t\tconst slot = {\n\t\t\t\ttype: \"thinking\",\n\t\t\t\tblock,\n\t\t\t\tcontentIndex: output.content.length - 1,\n\t\t\t} satisfies ResponsesOutputSlot;\n\t\t\toutputSlots.set(outputIndex, slot);\n\t\t\tstream.push({ type: \"thinking_start\", contentIndex: slot.contentIndex, partial: output });\n\t\t\treturn slot;\n\t\t}\n\t\tif (item.type === \"message\") {\n\t\t\tconst block: TextContent = { type: \"text\", text: \"\" };\n\t\t\toutput.content.push(block);\n\t\t\tconst slot = { type: \"text\", block, contentIndex: output.content.length - 1 } satisfies ResponsesOutputSlot;\n\t\t\toutputSlots.set(outputIndex, slot);\n\t\t\tstream.push({ type: \"text_start\", contentIndex: slot.contentIndex, partial: output });\n\t\t\treturn slot;\n\t\t}\n\t\tif (item.type === \"function_call\") {\n\t\t\tconst block: StreamingToolCall = {\n\t\t\t\ttype: \"toolCall\",\n\t\t\t\tid: `${item.call_id}|${item.id}`,\n\t\t\t\tname: item.name,\n\t\t\t\targuments: {},\n\t\t\t\tpartialJson: item.arguments || \"\",\n\t\t\t};\n\t\t\toutput.content.push(block);\n\t\t\tconst slot = {\n\t\t\t\ttype: \"toolCall\",\n\t\t\t\tblock,\n\t\t\t\tcontentIndex: output.content.length - 1,\n\t\t\t} satisfies ResponsesOutputSlot;\n\t\t\toutputSlots.set(outputIndex, slot);\n\t\t\tstream.push({ type: \"toolcall_start\", contentIndex: slot.contentIndex, partial: output });\n\t\t\treturn slot;\n\t\t}\n\t\treturn undefined;\n\t};\n\tconst getOrCreateSlot = (outputIndex: number, item: ResponseOutputItem): ResponsesOutputSlot | undefined => {\n\t\treturn outputSlots.get(outputIndex) ?? createSlot(outputIndex, item);\n\t};\n\t// Azure OpenAI can omit reasoning.encrypted_content from response.output_item.done\n\t// and provide it only in response.completed.response.output. Backfill the\n\t// persisted reasoning signature from the terminal response to keep store:false\n\t// multi-turn replay stateless. See https://github.com/earendil-works/pi/issues/6409.\n\tconst backfillReasoningSignatures = (responseOutput: ResponseOutputItem[]): void => {\n\t\tfor (const item of responseOutput) {\n\t\t\tif (item.type !== \"reasoning\" || !item.encrypted_content) continue;\n\t\t\tconst block = reasoningBlocksById.get(item.id);\n\t\t\tif (!block?.thinkingSignature) continue;\n\n\t\t\tconst storedItem = JSON.parse(block.thinkingSignature) as ResponseReasoningItem;\n\t\t\tif (storedItem.encrypted_content) continue;\n\t\t\tblock.thinkingSignature = JSON.stringify({\n\t\t\t\t...storedItem,\n\t\t\t\tencrypted_content: item.encrypted_content,\n\t\t\t});\n\t\t}\n\t};\n\tconst finalizeResponse = (\n\t\tresponse: Extract<ResponseStreamEvent, { type: \"response.completed\" | \"response.incomplete\" }>[\"response\"],\n\t): void => {\n\t\tsawTerminalResponseEvent = true;\n\t\tbackfillReasoningSignatures(response.output ?? []);\n\t\tif (response?.id) {\n\t\t\toutput.responseId = response.id;\n\t\t}\n\t\tif (response?.usage) {\n\t\t\tconst inputDetails = response.usage.input_tokens_details as\n\t\t\t\t| { cached_tokens?: number; cache_write_tokens?: number }\n\t\t\t\t| undefined;\n\t\t\tconst cachedTokens = inputDetails?.cached_tokens || 0;\n\t\t\tconst cacheWriteTokens = inputDetails?.cache_write_tokens || 0;\n\t\t\toutput.usage = {\n\t\t\t\t// OpenAI includes cached and cache-write tokens in input_tokens, so subtract both.\n\t\t\t\tinput: Math.max(0, (response.usage.input_tokens || 0) - cachedTokens - cacheWriteTokens),\n\t\t\t\toutput: response.usage.output_tokens || 0,\n\t\t\t\tcacheRead: cachedTokens,\n\t\t\t\tcacheWrite: cacheWriteTokens,\n\t\t\t\treasoning: response.usage.output_tokens_details?.reasoning_tokens || 0,\n\t\t\t\ttotalTokens: response.usage.total_tokens || 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t};\n\t\t}\n\t\tcalculateCost(model, output.usage);\n\t\tif (options?.applyServiceTierPricing) {\n\t\t\tconst serviceTier = options.resolveServiceTier\n\t\t\t\t? options.resolveServiceTier(response?.service_tier, options.serviceTier)\n\t\t\t\t: (response?.service_tier ?? options.serviceTier);\n\t\t\toptions.applyServiceTierPricing(output.usage, serviceTier);\n\t\t}\n\t\t// Map status to stop reason\n\t\toutput.stopReason = mapStopReason(response?.status);\n\t\tif (output.content.some((b) => b.type === \"toolCall\") && output.stopReason === \"stop\") {\n\t\t\toutput.stopReason = \"toolUse\";\n\t\t}\n\t};\n\n\tfor await (const event of openaiStream) {\n\t\tif (event.type === \"response.created\") {\n\t\t\toutput.responseId = event.response.id;\n\t\t} else if (event.type === \"response.output_item.added\") {\n\t\t\tcreateSlot(event.output_index, event.item);\n\t\t} else if (event.type === \"response.reasoning_summary_text.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"thinking\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.thinking += event.delta;\n\t\t\tstream.push({\n\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.reasoning_summary_part.done\") {\n\t\t\tconst slot = getSlot(event.output_index, \"thinking\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.thinking += \"\\n\\n\";\n\t\t\tstream.push({\n\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: \"\\n\\n\",\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.reasoning_text.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"thinking\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.thinking += event.delta;\n\t\t\tstream.push({\n\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.output_text.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"text\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.text += event.delta;\n\t\t\tstream.push({\n\t\t\t\ttype: \"text_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.refusal.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"text\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.text += event.delta;\n\t\t\tstream.push({\n\t\t\t\ttype: \"text_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.function_call_arguments.delta\") {\n\t\t\tconst slot = getSlot(event.output_index, \"toolCall\");\n\t\t\tif (!slot) continue;\n\t\t\tslot.block.partialJson += event.delta;\n\t\t\tslot.block.arguments = parseStreamingJson(slot.block.partialJson);\n\t\t\tstream.push({\n\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\tdelta: event.delta,\n\t\t\t\tpartial: output,\n\t\t\t});\n\t\t} else if (event.type === \"response.function_call_arguments.done\") {\n\t\t\tconst slot = getSlot(event.output_index, \"toolCall\");\n\t\t\tif (!slot) continue;\n\t\t\tconst previousPartialJson = slot.block.partialJson;\n\t\t\tslot.block.partialJson = event.arguments;\n\t\t\tslot.block.arguments = parseStreamingJson(slot.block.partialJson);\n\n\t\t\tif (event.arguments.startsWith(previousPartialJson)) {\n\t\t\t\tconst delta = event.arguments.slice(previousPartialJson.length);\n\t\t\t\tif (delta.length > 0) {\n\t\t\t\t\tstream.push({\n\t\t\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\t\t\tdelta,\n\t\t\t\t\t\tpartial: output,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (event.type === \"response.output_item.done\") {\n\t\t\tconst item = event.item;\n\t\t\tconst slot = getOrCreateSlot(event.output_index, item);\n\n\t\t\tif (item.type === \"reasoning\" && slot?.type === \"thinking\") {\n\t\t\t\tconst summaryText = item.summary?.map((s) => s.text).join(\"\\n\\n\") || \"\";\n\t\t\t\tconst contentText = item.content?.map((c) => c.text).join(\"\\n\\n\") || \"\";\n\t\t\t\tslot.block.thinking = summaryText || contentText || slot.block.thinking;\n\t\t\t\tslot.block.thinkingSignature = JSON.stringify(item);\n\t\t\t\treasoningBlocksById.set(item.id, slot.block);\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\t\tcontent: slot.block.thinking,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\toutputSlots.delete(event.output_index);\n\t\t\t} else if (item.type === \"message\" && slot?.type === \"text\") {\n\t\t\t\tslot.block.text = item.content?.map((c) => (c.type === \"output_text\" ? c.text : c.refusal)).join(\"\") || \"\";\n\t\t\t\tslot.block.textSignature = encodeTextSignatureV1(item.id, item.phase ?? undefined);\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\t\tcontent: slot.block.text,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\toutputSlots.delete(event.output_index);\n\t\t\t} else if (item.type === \"function_call\" && slot?.type === \"toolCall\") {\n\t\t\t\tslot.block.arguments = parseStreamingJson(item.arguments || slot.block.partialJson || \"{}\");\n\t\t\t\t// Finalize in-place and strip the scratch buffer so replay only\n\t\t\t\t// carries parsed arguments.\n\t\t\t\tdelete (slot.block as { partialJson?: string }).partialJson;\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"toolcall_end\",\n\t\t\t\t\tcontentIndex: slot.contentIndex,\n\t\t\t\t\ttoolCall: slot.block,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\toutputSlots.delete(event.output_index);\n\t\t\t}\n\t\t} else if (event.type === \"response.completed\" || event.type === \"response.incomplete\") {\n\t\t\tfinalizeResponse(event.response);\n\t\t} else if (event.type === \"error\") {\n\t\t\tthrow new Error(`Error Code ${event.code}: ${event.message}` || \"Unknown error\");\n\t\t} else if (event.type === \"response.failed\") {\n\t\t\tsawTerminalResponseEvent = true;\n\t\t\tconst error = event.response?.error;\n\t\t\tconst details = event.response?.incomplete_details;\n\t\t\tconst msg = error\n\t\t\t\t? `${error.code || \"unknown\"}: ${error.message || \"no message\"}`\n\t\t\t\t: details?.reason\n\t\t\t\t\t? `incomplete: ${details.reason}`\n\t\t\t\t\t: \"Unknown error (no error details in response)\";\n\t\t\tthrow new Error(msg);\n\t\t}\n\t}\n\tif (!sawTerminalResponseEvent) {\n\t\tthrow new Error(\"OpenAI Responses stream ended before a terminal response event\");\n\t}\n}\n\nfunction mapStopReason(status: OpenAI.Responses.ResponseStatus | undefined): StopReason {\n\tif (!status) return \"stop\";\n\tswitch (status) {\n\t\tcase \"completed\":\n\t\t\treturn \"stop\";\n\t\tcase \"incomplete\":\n\t\t\treturn \"length\";\n\t\tcase \"failed\":\n\t\tcase \"cancelled\":\n\t\t\treturn \"error\";\n\t\t// These two are wonky ...\n\t\tcase \"in_progress\":\n\t\tcase \"queued\":\n\t\t\treturn \"stop\";\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = status;\n\t\t\tthrow new Error(`Unhandled stop reason: ${_exhaustive}`);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -4,6 +4,7 @@ export interface OpenAIResponsesOptions extends StreamOptions {
|
|
|
4
4
|
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
5
5
|
reasoningSummary?: "auto" | "detailed" | "concise" | null;
|
|
6
6
|
serviceTier?: ResponseCreateParamsStreaming["service_tier"];
|
|
7
|
+
toolChoice?: ResponseCreateParamsStreaming["tool_choice"];
|
|
7
8
|
}
|
|
8
9
|
/**
|
|
9
10
|
* Generate function for OpenAI Responses API
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-responses.d.ts","sourceRoot":"","sources":["../../src/api/openai-responses.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AAE7F,OAAO,KAAK,EASX,mBAAmB,EACnB,cAAc,EACd,aAAa,EAEb,MAAM,aAAa,CAAC;AA+DrB,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC5D,eAAe,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;IAC1E,gBAAgB,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1D,WAAW,CAAC,EAAE,6BAA6B,CAAC,cAAc,CAAC,CAAC;CAC5D;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,kBAAkB,EAAE,sBAAsB,CA4E7E,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,kBAAkB,EAAE,mBAAmB,CAehF,CAAC","sourcesContent":["import OpenAI from \"openai\";\nimport type { ResponseCreateParamsStreaming } from \"openai/resources/responses/responses.js\";\nimport { clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tCacheRetention,\n\tContext,\n\tModel,\n\tOpenAIResponsesCompat,\n\tProviderEnv,\n\tProviderHeaders,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tUsage,\n} from \"../types.ts\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { headersToRecord } from \"../utils/headers.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.ts\";\nimport { clampOpenAIPromptCacheKey } from \"./openai-prompt-cache.ts\";\nimport { convertResponsesMessages, convertResponsesTools, processResponsesStream } from \"./openai-responses-shared.ts\";\nimport { buildBaseOptions } from \"./simple-options.ts\";\n\nconst OPENAI_TOOL_CALL_PROVIDERS = new Set([\"openai\", \"openai-codex\", \"opencode\"]);\n// OpenAI Responses rejects max_output_tokens below 16: https://github.com/earendil-works/pi/issues/6265\nconst OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;\n\nfunction hasHeader(headers: ProviderHeaders | undefined, name: string): boolean {\n\tif (!headers) return false;\n\tconst expected = name.toLowerCase();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (key.toLowerCase() === expected && value !== null && value.trim().length > 0) return true;\n\t}\n\treturn false;\n}\n\nfunction getClientApiKey(provider: string, apiKey: string | undefined, headers: ProviderHeaders | undefined): string {\n\tif (apiKey) return apiKey;\n\tif (hasHeader(headers, \"authorization\") || hasHeader(headers, \"cf-aig-authorization\")) return \"unused\";\n\tthrow new Error(`No API key for provider: ${provider}`);\n}\n\n/**\n * Resolve cache retention preference.\n * Defaults to \"short\" and uses PI_CACHE_RETENTION for backward compatibility.\n */\nfunction resolveCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction getCompat(model: Model<\"openai-responses\">): Required<OpenAIResponsesCompat> {\n\treturn {\n\t\tsupportsDeveloperRole: model.compat?.supportsDeveloperRole ?? true,\n\t\tsendSessionIdHeader: model.compat?.sendSessionIdHeader ?? true,\n\t\tsupportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,\n\t};\n}\n\nfunction getPromptCacheRetention(\n\tcompat: Required<OpenAIResponsesCompat>,\n\tcacheRetention: CacheRetention,\n): \"24h\" | undefined {\n\treturn cacheRetention === \"long\" && compat.supportsLongCacheRetention ? \"24h\" : undefined;\n}\n\nfunction formatOpenAIResponsesError(error: unknown): string {\n\treturn formatProviderError(normalizeProviderError(error), \"OpenAI API error\");\n}\n\n// OpenAI Responses-specific options\nexport interface OpenAIResponsesOptions extends StreamOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n\tserviceTier?: ResponseCreateParamsStreaming[\"service_tier\"];\n}\n\n/**\n * Generate function for OpenAI Responses API\n */\nexport const stream: StreamFunction<\"openai-responses\", OpenAIResponsesOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: OpenAIResponsesOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t// Start async processing\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\t// Create OpenAI client\n\t\t\tconst apiKey = getClientApiKey(model.provider, options?.apiKey, options?.headers);\n\t\t\tconst cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);\n\t\t\tconst cacheSessionId = cacheRetention === \"none\" ? undefined : options?.sessionId;\n\t\t\tconst client = createClient(model, context, apiKey, options?.headers, cacheSessionId);\n\t\t\tlet params = buildParams(model, context, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as ResponseCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst requestOptions = {\n\t\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t\t\t...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),\n\t\t\t\tmaxRetries: options?.maxRetries ?? 0,\n\t\t\t};\n\t\t\tconst { data: openaiStream, response } = await client.responses.create(params, requestOptions).withResponse();\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\tawait processResponsesStream(openaiStream, output, stream, model, {\n\t\t\t\tserviceTier: options?.serviceTier,\n\t\t\t\tapplyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model),\n\t\t\t});\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(\"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) {\n\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t// partialJson is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatOpenAIResponsesError(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\nexport const streamSimple: StreamFunction<\"openai-responses\", SimpleStreamOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tgetClientApiKey(model.provider, options?.apiKey, options?.headers);\n\n\tconst base = buildBaseOptions(model, context, options, options?.apiKey);\n\tconst clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;\n\tconst reasoningEffort = clampedReasoning === \"off\" ? undefined : clampedReasoning;\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\treasoningEffort,\n\t} satisfies OpenAIResponsesOptions);\n};\n\nfunction createClient(\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\tapiKey: string,\n\toptionsHeaders?: ProviderHeaders,\n\tsessionId?: string,\n) {\n\tconst compat = getCompat(model);\n\tconst headers: ProviderHeaders = { ...model.headers };\n\tif (model.provider === \"github-copilot\") {\n\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\tconst copilotHeaders = buildCopilotDynamicHeaders({\n\t\t\tmessages: context.messages,\n\t\t\thasImages,\n\t\t});\n\t\tObject.assign(headers, copilotHeaders);\n\t}\n\n\tif (sessionId) {\n\t\tif (compat.sendSessionIdHeader) {\n\t\t\theaders.session_id = sessionId;\n\t\t}\n\t\theaders[\"x-client-request-id\"] = sessionId;\n\t}\n\n\t// Merge options headers last so they can override defaults\n\tif (optionsHeaders) {\n\t\tObject.assign(headers, optionsHeaders);\n\t}\n\n\treturn new OpenAI({\n\t\tapiKey,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: headers,\n\t});\n}\n\nfunction buildParams(model: Model<\"openai-responses\">, context: Context, options?: OpenAIResponsesOptions) {\n\tconst messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS);\n\n\tconst cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);\n\tconst compat = getCompat(model);\n\tconst params: ResponseCreateParamsStreaming = {\n\t\tmodel: model.id,\n\t\tinput: messages,\n\t\tstream: true,\n\t\tprompt_cache_key: cacheRetention === \"none\" ? undefined : clampOpenAIPromptCacheKey(options?.sessionId),\n\t\tprompt_cache_retention: getPromptCacheRetention(compat, cacheRetention),\n\t\tstore: false,\n\t};\n\n\tif (options?.maxTokens) {\n\t\tparams.max_output_tokens = Math.max(options.maxTokens, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS);\n\t}\n\n\tif (options?.temperature !== undefined) {\n\t\tparams.temperature = options?.temperature;\n\t}\n\n\tif (options?.serviceTier !== undefined) {\n\t\tparams.service_tier = options.serviceTier;\n\t}\n\n\tif (context.tools && context.tools.length > 0) {\n\t\tparams.tools = convertResponsesTools(context.tools);\n\t}\n\n\tif (model.reasoning) {\n\t\tif (options?.reasoningEffort || options?.reasoningSummary) {\n\t\t\tconst effort = options?.reasoningEffort\n\t\t\t\t? (model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort)\n\t\t\t\t: \"medium\";\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: effort as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t\tsummary: options?.reasoningSummary || \"auto\",\n\t\t\t};\n\t\t\tparams.include = [\"reasoning.encrypted_content\"];\n\t\t} else if (model.provider !== \"github-copilot\" && model.thinkingLevelMap?.off !== null) {\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: (model.thinkingLevelMap?.off ?? \"none\") as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t};\n\t\t}\n\t}\n\n\treturn params;\n}\n\nfunction getServiceTierCostMultiplier(\n\tmodel: Pick<Model<\"openai-responses\">, \"id\">,\n\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n): number {\n\tswitch (serviceTier) {\n\t\tcase \"flex\":\n\t\t\treturn 0.5;\n\t\tcase \"priority\":\n\t\t\treturn model.id === \"gpt-5.5\" ? 2.5 : 2;\n\t\tdefault:\n\t\t\treturn 1;\n\t}\n}\n\nfunction applyServiceTierPricing(\n\tusage: Usage,\n\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\tmodel: Pick<Model<\"openai-responses\">, \"id\">,\n) {\n\tconst multiplier = getServiceTierCostMultiplier(model, serviceTier);\n\tif (multiplier === 1) return;\n\n\tusage.cost.input *= multiplier;\n\tusage.cost.output *= multiplier;\n\tusage.cost.cacheRead *= multiplier;\n\tusage.cost.cacheWrite *= multiplier;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"openai-responses.d.ts","sourceRoot":"","sources":["../../src/api/openai-responses.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AAE7F,OAAO,KAAK,EASX,mBAAmB,EACnB,cAAc,EACd,aAAa,EAEb,MAAM,aAAa,CAAC;AAqErB,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC5D,eAAe,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;IAC1E,gBAAgB,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1D,WAAW,CAAC,EAAE,6BAA6B,CAAC,cAAc,CAAC,CAAC;IAC5D,UAAU,CAAC,EAAE,6BAA6B,CAAC,aAAa,CAAC,CAAC;CAC1D;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,kBAAkB,EAAE,sBAAsB,CA4E7E,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,kBAAkB,EAAE,mBAAmB,CAehF,CAAC","sourcesContent":["import OpenAI from \"openai\";\nimport type { ResponseCreateParamsStreaming } from \"openai/resources/responses/responses.js\";\nimport { clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tCacheRetention,\n\tContext,\n\tModel,\n\tOpenAIResponsesCompat,\n\tProviderEnv,\n\tProviderHeaders,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tUsage,\n} from \"../types.ts\";\nimport { splitDeferredTools } from \"../utils/deferred-tools.ts\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { headersToRecord } from \"../utils/headers.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.ts\";\nimport { clampOpenAIPromptCacheKey } from \"./openai-prompt-cache.ts\";\nimport { convertResponsesMessages, convertResponsesTools, processResponsesStream } from \"./openai-responses-shared.ts\";\nimport { buildBaseOptions } from \"./simple-options.ts\";\n\nconst OPENAI_TOOL_CALL_PROVIDERS = new Set([\"openai\", \"openai-codex\", \"opencode\"]);\n// OpenAI Responses rejects max_output_tokens below 16: https://github.com/earendil-works/pi/issues/6265\nconst OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;\n\nfunction hasHeader(headers: ProviderHeaders | undefined, name: string): boolean {\n\tif (!headers) return false;\n\tconst expected = name.toLowerCase();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (key.toLowerCase() === expected && value !== null && value.trim().length > 0) return true;\n\t}\n\treturn false;\n}\n\nfunction getClientApiKey(provider: string, apiKey: string | undefined, headers: ProviderHeaders | undefined): string {\n\tif (apiKey) return apiKey;\n\tif (hasHeader(headers, \"authorization\") || hasHeader(headers, \"cf-aig-authorization\")) return \"unused\";\n\tthrow new Error(`No API key for provider: ${provider}`);\n}\n\nfunction detectSessionAffinityFormat(model: Pick<Model<\"openai-responses\">, \"provider\" | \"baseUrl\">) {\n\treturn model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\") ? \"openrouter\" : \"openai\";\n}\n\n/**\n * Resolve cache retention preference.\n * Defaults to \"short\" and uses PI_CACHE_RETENTION for backward compatibility.\n */\nfunction resolveCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction getCompat(model: Model<\"openai-responses\">): Required<OpenAIResponsesCompat> {\n\treturn {\n\t\tsupportsDeveloperRole: model.compat?.supportsDeveloperRole ?? true,\n\t\tsessionAffinityFormat: model.compat?.sessionAffinityFormat ?? detectSessionAffinityFormat(model),\n\t\tsupportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,\n\t\tsupportsToolSearch: model.compat?.supportsToolSearch ?? false,\n\t};\n}\n\nfunction getPromptCacheRetention(\n\tcompat: Required<OpenAIResponsesCompat>,\n\tcacheRetention: CacheRetention,\n): \"24h\" | undefined {\n\treturn cacheRetention === \"long\" && compat.supportsLongCacheRetention ? \"24h\" : undefined;\n}\n\nfunction formatOpenAIResponsesError(error: unknown): string {\n\treturn formatProviderError(normalizeProviderError(error), \"OpenAI API error\");\n}\n\n// OpenAI Responses-specific options\nexport interface OpenAIResponsesOptions extends StreamOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n\tserviceTier?: ResponseCreateParamsStreaming[\"service_tier\"];\n\ttoolChoice?: ResponseCreateParamsStreaming[\"tool_choice\"];\n}\n\n/**\n * Generate function for OpenAI Responses API\n */\nexport const stream: StreamFunction<\"openai-responses\", OpenAIResponsesOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: OpenAIResponsesOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t// Start async processing\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\t// Create OpenAI client\n\t\t\tconst apiKey = getClientApiKey(model.provider, options?.apiKey, options?.headers);\n\t\t\tconst cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);\n\t\t\tconst cacheSessionId = cacheRetention === \"none\" ? undefined : options?.sessionId;\n\t\t\tconst client = createClient(model, context, apiKey, options?.headers, cacheSessionId);\n\t\t\tlet params = buildParams(model, context, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as ResponseCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst requestOptions = {\n\t\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t\t\t...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),\n\t\t\t\tmaxRetries: options?.maxRetries ?? 0,\n\t\t\t};\n\t\t\tconst { data: openaiStream, response } = await client.responses.create(params, requestOptions).withResponse();\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\tawait processResponsesStream(openaiStream, output, stream, model, {\n\t\t\t\tserviceTier: options?.serviceTier,\n\t\t\t\tapplyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model),\n\t\t\t});\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(\"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) {\n\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t// partialJson is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatOpenAIResponsesError(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\nexport const streamSimple: StreamFunction<\"openai-responses\", SimpleStreamOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tgetClientApiKey(model.provider, options?.apiKey, options?.headers);\n\n\tconst base = buildBaseOptions(model, context, options, options?.apiKey);\n\tconst clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;\n\tconst reasoningEffort = clampedReasoning === \"off\" ? undefined : clampedReasoning;\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\treasoningEffort,\n\t} satisfies OpenAIResponsesOptions);\n};\n\nfunction createClient(\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\tapiKey: string,\n\toptionsHeaders?: ProviderHeaders,\n\tsessionId?: string,\n) {\n\tconst compat = getCompat(model);\n\tconst headers: ProviderHeaders = { ...model.headers };\n\tif (model.provider === \"github-copilot\") {\n\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\tconst copilotHeaders = buildCopilotDynamicHeaders({\n\t\t\tmessages: context.messages,\n\t\t\thasImages,\n\t\t});\n\t\tObject.assign(headers, copilotHeaders);\n\t}\n\n\tif (sessionId) {\n\t\tif (compat.sessionAffinityFormat === \"openrouter\") {\n\t\t\theaders[\"x-session-id\"] = sessionId;\n\t\t} else {\n\t\t\tif (compat.sessionAffinityFormat === \"openai\") {\n\t\t\t\theaders.session_id = sessionId;\n\t\t\t}\n\t\t\theaders[\"x-client-request-id\"] = sessionId;\n\t\t}\n\t}\n\n\t// Merge options headers last so they can override defaults\n\tif (optionsHeaders) {\n\t\tObject.assign(headers, optionsHeaders);\n\t}\n\n\treturn new OpenAI({\n\t\tapiKey,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: headers,\n\t});\n}\n\nfunction buildParams(model: Model<\"openai-responses\">, context: Context, options?: OpenAIResponsesOptions) {\n\tconst compat = getCompat(model);\n\tconst toolPlacement = splitDeferredTools(context, compat.supportsToolSearch);\n\tconst messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS, {\n\t\tdeferredTools: toolPlacement.deferred,\n\t});\n\n\tconst cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);\n\tconst params: ResponseCreateParamsStreaming = {\n\t\tmodel: model.id,\n\t\tinput: messages,\n\t\tstream: true,\n\t\tprompt_cache_key: cacheRetention === \"none\" ? undefined : clampOpenAIPromptCacheKey(options?.sessionId),\n\t\tprompt_cache_retention: getPromptCacheRetention(compat, cacheRetention),\n\t\tstore: false,\n\t};\n\n\tif (options?.maxTokens) {\n\t\tparams.max_output_tokens = Math.max(options.maxTokens, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS);\n\t}\n\n\tif (options?.temperature !== undefined) {\n\t\tparams.temperature = options?.temperature;\n\t}\n\n\tif (options?.serviceTier !== undefined) {\n\t\tparams.service_tier = options.serviceTier;\n\t}\n\n\tif (toolPlacement.immediate.length > 0) {\n\t\tparams.tools = convertResponsesTools(toolPlacement.immediate);\n\t}\n\n\tif (options?.toolChoice !== undefined) {\n\t\tparams.tool_choice = options.toolChoice;\n\t}\n\n\tif (model.reasoning) {\n\t\tif (options?.reasoningEffort || options?.reasoningSummary) {\n\t\t\tconst effort = options?.reasoningEffort\n\t\t\t\t? (model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort)\n\t\t\t\t: \"medium\";\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: effort as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t\tsummary: options?.reasoningSummary || \"auto\",\n\t\t\t};\n\t\t\tparams.include = [\"reasoning.encrypted_content\"];\n\t\t} else if (model.provider !== \"github-copilot\" && model.thinkingLevelMap?.off !== null) {\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: (model.thinkingLevelMap?.off ?? \"none\") as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t};\n\t\t}\n\t}\n\n\treturn params;\n}\n\nfunction getServiceTierCostMultiplier(\n\tmodel: Pick<Model<\"openai-responses\">, \"id\">,\n\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n): number {\n\tswitch (serviceTier) {\n\t\tcase \"flex\":\n\t\t\treturn 0.5;\n\t\tcase \"priority\":\n\t\t\treturn model.id === \"gpt-5.5\" ? 2.5 : 2;\n\t\tdefault:\n\t\t\treturn 1;\n\t}\n}\n\nfunction applyServiceTierPricing(\n\tusage: Usage,\n\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\tmodel: Pick<Model<\"openai-responses\">, \"id\">,\n) {\n\tconst multiplier = getServiceTierCostMultiplier(model, serviceTier);\n\tif (multiplier === 1) return;\n\n\tusage.cost.input *= multiplier;\n\tusage.cost.output *= multiplier;\n\tusage.cost.cacheRead *= multiplier;\n\tusage.cost.cacheWrite *= multiplier;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
2
|
import { clampThinkingLevel } from "../models.js";
|
|
3
|
+
import { splitDeferredTools } from "../utils/deferred-tools.js";
|
|
3
4
|
import { formatProviderError, normalizeProviderError } from "../utils/error-body.js";
|
|
4
5
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
5
6
|
import { headersToRecord } from "../utils/headers.js";
|
|
@@ -28,6 +29,9 @@ function getClientApiKey(provider, apiKey, headers) {
|
|
|
28
29
|
return "unused";
|
|
29
30
|
throw new Error(`No API key for provider: ${provider}`);
|
|
30
31
|
}
|
|
32
|
+
function detectSessionAffinityFormat(model) {
|
|
33
|
+
return model.provider === "openrouter" || model.baseUrl.includes("openrouter.ai") ? "openrouter" : "openai";
|
|
34
|
+
}
|
|
31
35
|
/**
|
|
32
36
|
* Resolve cache retention preference.
|
|
33
37
|
* Defaults to "short" and uses PI_CACHE_RETENTION for backward compatibility.
|
|
@@ -44,8 +48,9 @@ function resolveCacheRetention(cacheRetention, env) {
|
|
|
44
48
|
function getCompat(model) {
|
|
45
49
|
return {
|
|
46
50
|
supportsDeveloperRole: model.compat?.supportsDeveloperRole ?? true,
|
|
47
|
-
|
|
51
|
+
sessionAffinityFormat: model.compat?.sessionAffinityFormat ?? detectSessionAffinityFormat(model),
|
|
48
52
|
supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,
|
|
53
|
+
supportsToolSearch: model.compat?.supportsToolSearch ?? false,
|
|
49
54
|
};
|
|
50
55
|
}
|
|
51
56
|
function getPromptCacheRetention(compat, cacheRetention) {
|
|
@@ -146,10 +151,15 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId) {
|
|
|
146
151
|
Object.assign(headers, copilotHeaders);
|
|
147
152
|
}
|
|
148
153
|
if (sessionId) {
|
|
149
|
-
if (compat.
|
|
150
|
-
headers
|
|
154
|
+
if (compat.sessionAffinityFormat === "openrouter") {
|
|
155
|
+
headers["x-session-id"] = sessionId;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
if (compat.sessionAffinityFormat === "openai") {
|
|
159
|
+
headers.session_id = sessionId;
|
|
160
|
+
}
|
|
161
|
+
headers["x-client-request-id"] = sessionId;
|
|
151
162
|
}
|
|
152
|
-
headers["x-client-request-id"] = sessionId;
|
|
153
163
|
}
|
|
154
164
|
// Merge options headers last so they can override defaults
|
|
155
165
|
if (optionsHeaders) {
|
|
@@ -163,9 +173,12 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId) {
|
|
|
163
173
|
});
|
|
164
174
|
}
|
|
165
175
|
function buildParams(model, context, options) {
|
|
166
|
-
const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS);
|
|
167
|
-
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
168
176
|
const compat = getCompat(model);
|
|
177
|
+
const toolPlacement = splitDeferredTools(context, compat.supportsToolSearch);
|
|
178
|
+
const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS, {
|
|
179
|
+
deferredTools: toolPlacement.deferred,
|
|
180
|
+
});
|
|
181
|
+
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
169
182
|
const params = {
|
|
170
183
|
model: model.id,
|
|
171
184
|
input: messages,
|
|
@@ -183,8 +196,11 @@ function buildParams(model, context, options) {
|
|
|
183
196
|
if (options?.serviceTier !== undefined) {
|
|
184
197
|
params.service_tier = options.serviceTier;
|
|
185
198
|
}
|
|
186
|
-
if (
|
|
187
|
-
params.tools = convertResponsesTools(
|
|
199
|
+
if (toolPlacement.immediate.length > 0) {
|
|
200
|
+
params.tools = convertResponsesTools(toolPlacement.immediate);
|
|
201
|
+
}
|
|
202
|
+
if (options?.toolChoice !== undefined) {
|
|
203
|
+
params.tool_choice = options.toolChoice;
|
|
188
204
|
}
|
|
189
205
|
if (model.reasoning) {
|
|
190
206
|
if (options?.reasoningEffort || options?.reasoningSummary) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-responses.js","sourceRoot":"","sources":["../../src/api/openai-responses.ts"],"names":[],"mappings":"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","sourcesContent":["import OpenAI from \"openai\";\nimport type { ResponseCreateParamsStreaming } from \"openai/resources/responses/responses.js\";\nimport { clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tCacheRetention,\n\tContext,\n\tModel,\n\tOpenAIResponsesCompat,\n\tProviderEnv,\n\tProviderHeaders,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tUsage,\n} from \"../types.ts\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { headersToRecord } from \"../utils/headers.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.ts\";\nimport { clampOpenAIPromptCacheKey } from \"./openai-prompt-cache.ts\";\nimport { convertResponsesMessages, convertResponsesTools, processResponsesStream } from \"./openai-responses-shared.ts\";\nimport { buildBaseOptions } from \"./simple-options.ts\";\n\nconst OPENAI_TOOL_CALL_PROVIDERS = new Set([\"openai\", \"openai-codex\", \"opencode\"]);\n// OpenAI Responses rejects max_output_tokens below 16: https://github.com/earendil-works/pi/issues/6265\nconst OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;\n\nfunction hasHeader(headers: ProviderHeaders | undefined, name: string): boolean {\n\tif (!headers) return false;\n\tconst expected = name.toLowerCase();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (key.toLowerCase() === expected && value !== null && value.trim().length > 0) return true;\n\t}\n\treturn false;\n}\n\nfunction getClientApiKey(provider: string, apiKey: string | undefined, headers: ProviderHeaders | undefined): string {\n\tif (apiKey) return apiKey;\n\tif (hasHeader(headers, \"authorization\") || hasHeader(headers, \"cf-aig-authorization\")) return \"unused\";\n\tthrow new Error(`No API key for provider: ${provider}`);\n}\n\n/**\n * Resolve cache retention preference.\n * Defaults to \"short\" and uses PI_CACHE_RETENTION for backward compatibility.\n */\nfunction resolveCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction getCompat(model: Model<\"openai-responses\">): Required<OpenAIResponsesCompat> {\n\treturn {\n\t\tsupportsDeveloperRole: model.compat?.supportsDeveloperRole ?? true,\n\t\tsendSessionIdHeader: model.compat?.sendSessionIdHeader ?? true,\n\t\tsupportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,\n\t};\n}\n\nfunction getPromptCacheRetention(\n\tcompat: Required<OpenAIResponsesCompat>,\n\tcacheRetention: CacheRetention,\n): \"24h\" | undefined {\n\treturn cacheRetention === \"long\" && compat.supportsLongCacheRetention ? \"24h\" : undefined;\n}\n\nfunction formatOpenAIResponsesError(error: unknown): string {\n\treturn formatProviderError(normalizeProviderError(error), \"OpenAI API error\");\n}\n\n// OpenAI Responses-specific options\nexport interface OpenAIResponsesOptions extends StreamOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n\tserviceTier?: ResponseCreateParamsStreaming[\"service_tier\"];\n}\n\n/**\n * Generate function for OpenAI Responses API\n */\nexport const stream: StreamFunction<\"openai-responses\", OpenAIResponsesOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: OpenAIResponsesOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t// Start async processing\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\t// Create OpenAI client\n\t\t\tconst apiKey = getClientApiKey(model.provider, options?.apiKey, options?.headers);\n\t\t\tconst cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);\n\t\t\tconst cacheSessionId = cacheRetention === \"none\" ? undefined : options?.sessionId;\n\t\t\tconst client = createClient(model, context, apiKey, options?.headers, cacheSessionId);\n\t\t\tlet params = buildParams(model, context, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as ResponseCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst requestOptions = {\n\t\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t\t\t...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),\n\t\t\t\tmaxRetries: options?.maxRetries ?? 0,\n\t\t\t};\n\t\t\tconst { data: openaiStream, response } = await client.responses.create(params, requestOptions).withResponse();\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\tawait processResponsesStream(openaiStream, output, stream, model, {\n\t\t\t\tserviceTier: options?.serviceTier,\n\t\t\t\tapplyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model),\n\t\t\t});\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(\"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) {\n\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t// partialJson is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatOpenAIResponsesError(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\nexport const streamSimple: StreamFunction<\"openai-responses\", SimpleStreamOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tgetClientApiKey(model.provider, options?.apiKey, options?.headers);\n\n\tconst base = buildBaseOptions(model, context, options, options?.apiKey);\n\tconst clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;\n\tconst reasoningEffort = clampedReasoning === \"off\" ? undefined : clampedReasoning;\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\treasoningEffort,\n\t} satisfies OpenAIResponsesOptions);\n};\n\nfunction createClient(\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\tapiKey: string,\n\toptionsHeaders?: ProviderHeaders,\n\tsessionId?: string,\n) {\n\tconst compat = getCompat(model);\n\tconst headers: ProviderHeaders = { ...model.headers };\n\tif (model.provider === \"github-copilot\") {\n\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\tconst copilotHeaders = buildCopilotDynamicHeaders({\n\t\t\tmessages: context.messages,\n\t\t\thasImages,\n\t\t});\n\t\tObject.assign(headers, copilotHeaders);\n\t}\n\n\tif (sessionId) {\n\t\tif (compat.sendSessionIdHeader) {\n\t\t\theaders.session_id = sessionId;\n\t\t}\n\t\theaders[\"x-client-request-id\"] = sessionId;\n\t}\n\n\t// Merge options headers last so they can override defaults\n\tif (optionsHeaders) {\n\t\tObject.assign(headers, optionsHeaders);\n\t}\n\n\treturn new OpenAI({\n\t\tapiKey,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: headers,\n\t});\n}\n\nfunction buildParams(model: Model<\"openai-responses\">, context: Context, options?: OpenAIResponsesOptions) {\n\tconst messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS);\n\n\tconst cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);\n\tconst compat = getCompat(model);\n\tconst params: ResponseCreateParamsStreaming = {\n\t\tmodel: model.id,\n\t\tinput: messages,\n\t\tstream: true,\n\t\tprompt_cache_key: cacheRetention === \"none\" ? undefined : clampOpenAIPromptCacheKey(options?.sessionId),\n\t\tprompt_cache_retention: getPromptCacheRetention(compat, cacheRetention),\n\t\tstore: false,\n\t};\n\n\tif (options?.maxTokens) {\n\t\tparams.max_output_tokens = Math.max(options.maxTokens, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS);\n\t}\n\n\tif (options?.temperature !== undefined) {\n\t\tparams.temperature = options?.temperature;\n\t}\n\n\tif (options?.serviceTier !== undefined) {\n\t\tparams.service_tier = options.serviceTier;\n\t}\n\n\tif (context.tools && context.tools.length > 0) {\n\t\tparams.tools = convertResponsesTools(context.tools);\n\t}\n\n\tif (model.reasoning) {\n\t\tif (options?.reasoningEffort || options?.reasoningSummary) {\n\t\t\tconst effort = options?.reasoningEffort\n\t\t\t\t? (model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort)\n\t\t\t\t: \"medium\";\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: effort as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t\tsummary: options?.reasoningSummary || \"auto\",\n\t\t\t};\n\t\t\tparams.include = [\"reasoning.encrypted_content\"];\n\t\t} else if (model.provider !== \"github-copilot\" && model.thinkingLevelMap?.off !== null) {\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: (model.thinkingLevelMap?.off ?? \"none\") as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t};\n\t\t}\n\t}\n\n\treturn params;\n}\n\nfunction getServiceTierCostMultiplier(\n\tmodel: Pick<Model<\"openai-responses\">, \"id\">,\n\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n): number {\n\tswitch (serviceTier) {\n\t\tcase \"flex\":\n\t\t\treturn 0.5;\n\t\tcase \"priority\":\n\t\t\treturn model.id === \"gpt-5.5\" ? 2.5 : 2;\n\t\tdefault:\n\t\t\treturn 1;\n\t}\n}\n\nfunction applyServiceTierPricing(\n\tusage: Usage,\n\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\tmodel: Pick<Model<\"openai-responses\">, \"id\">,\n) {\n\tconst multiplier = getServiceTierCostMultiplier(model, serviceTier);\n\tif (multiplier === 1) return;\n\n\tusage.cost.input *= multiplier;\n\tusage.cost.output *= multiplier;\n\tusage.cost.cacheRead *= multiplier;\n\tusage.cost.cacheWrite *= multiplier;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"openai-responses.js","sourceRoot":"","sources":["../../src/api/openai-responses.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAelD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACvH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;AACnF,wGAAwG;AACxG,MAAM,kCAAkC,GAAG,EAAE,CAAC;AAE9C,SAAS,SAAS,CAAC,OAAoC,EAAE,IAAY,EAAW;IAC/E,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IAC9F,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,SAAS,eAAe,CAAC,QAAgB,EAAE,MAA0B,EAAE,OAAoC,EAAU;IACpH,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,SAAS,CAAC,OAAO,EAAE,eAAe,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,sBAAsB,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvG,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;AAAA,CACxD;AAED,SAAS,2BAA2B,CAAC,KAA8D,EAAE;IACpG,OAAO,KAAK,CAAC,QAAQ,KAAK,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;AAAA,CAC5G;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAAC,cAA+B,EAAE,GAAiB,EAAkB;IAClG,IAAI,cAAc,EAAE,CAAC;QACpB,OAAO,cAAc,CAAC;IACvB,CAAC;IACD,IAAI,mBAAmB,CAAC,oBAAoB,EAAE,GAAG,CAAC,KAAK,MAAM,EAAE,CAAC;QAC/D,OAAO,MAAM,CAAC;IACf,CAAC;IACD,OAAO,OAAO,CAAC;AAAA,CACf;AAED,SAAS,SAAS,CAAC,KAAgC,EAAmC;IACrF,OAAO;QACN,qBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,qBAAqB,IAAI,IAAI;QAClE,qBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,qBAAqB,IAAI,2BAA2B,CAAC,KAAK,CAAC;QAChG,0BAA0B,EAAE,KAAK,CAAC,MAAM,EAAE,0BAA0B,IAAI,IAAI;QAC5E,kBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,kBAAkB,IAAI,KAAK;KAC7D,CAAC;AAAA,CACF;AAED,SAAS,uBAAuB,CAC/B,MAAuC,EACvC,cAA8B,EACV;IACpB,OAAO,cAAc,KAAK,MAAM,IAAI,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAC1F;AAED,SAAS,0BAA0B,CAAC,KAAc,EAAU;IAC3D,OAAO,mBAAmB,CAAC,sBAAsB,CAAC,KAAK,CAAC,EAAE,kBAAkB,CAAC,CAAC;AAAA,CAC9E;AAUD;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAA+D,CACjF,KAAgC,EAChC,OAAgB,EAChB,OAAgC,EACF,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,2BAA2B,EAAE,CAAC;IAEjD,yBAAyB;IACzB,CAAC,KAAK,IAAI,EAAE,CAAC;QACZ,MAAM,MAAM,GAAqB;YAChC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,EAAE;YACX,GAAG,EAAE,KAAK,CAAC,GAAU;YACrB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,KAAK,EAAE,KAAK,CAAC,EAAE;YACf,KAAK,EAAE;gBACN,KAAK,EAAE,CAAC;gBACR,MAAM,EAAE,CAAC;gBACT,SAAS,EAAE,CAAC;gBACZ,UAAU,EAAE,CAAC;gBACb,WAAW,EAAE,CAAC;gBACd,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;aACpE;YACD,UAAU,EAAE,MAAM;YAClB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACrB,CAAC;QAEF,IAAI,CAAC;YACJ,uBAAuB;YACvB,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAClF,MAAM,cAAc,GAAG,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YACpF,MAAM,cAAc,GAAG,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC;YAClF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;YACtF,IAAI,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,MAAM,OAAO,EAAE,SAAS,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC7D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,GAAG,UAA2C,CAAC;YACtD,CAAC;YACD,MAAM,cAAc,GAAG;gBACtB,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtD,GAAG,CAAC,OAAO,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3E,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,CAAC;aACpC,CAAC;YACF,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,YAAY,EAAE,CAAC;YAC9G,MAAM,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAC5G,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAEhD,MAAM,sBAAsB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;gBACjE,WAAW,EAAE,OAAO,EAAE,WAAW;gBACjC,uBAAuB,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC,uBAAuB,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC;aACnG,CAAC,CAAC;YAEH,IAAI,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACxC,CAAC;YAED,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;gBACtE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC9C,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1E,MAAM,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpC,OAAQ,KAA4B,CAAC,KAAK,CAAC;gBAC3C,oEAAoE;gBACpE,OAAQ,KAAkC,CAAC,WAAW,CAAC;YACxD,CAAC;YACD,MAAM,CAAC,UAAU,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YACnE,MAAM,CAAC,YAAY,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;YACxD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACzE,MAAM,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;IAAA,CACD,CAAC,EAAE,CAAC;IAEL,OAAO,MAAM,CAAC;AAAA,CACd,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAA4D,CACpF,KAAgC,EAChC,OAAgB,EAChB,OAA6B,EACC,EAAE,CAAC;IACjC,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEnE,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACxE,MAAM,gBAAgB,GAAG,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvG,MAAM,eAAe,GAAG,gBAAgB,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAElF,OAAO,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE;QAC7B,GAAG,IAAI;QACP,eAAe;KACkB,CAAC,CAAC;AAAA,CACpC,CAAC;AAEF,SAAS,YAAY,CACpB,KAAgC,EAChC,OAAgB,EAChB,MAAc,EACd,cAAgC,EAChC,SAAkB,EACjB;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,OAAO,GAAoB,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IACtD,IAAI,KAAK,CAAC,QAAQ,KAAK,gBAAgB,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,cAAc,GAAG,0BAA0B,CAAC;YACjD,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,SAAS;SACT,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACf,IAAI,MAAM,CAAC,qBAAqB,KAAK,YAAY,EAAE,CAAC;YACnD,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;QACrC,CAAC;aAAM,CAAC;YACP,IAAI,MAAM,CAAC,qBAAqB,KAAK,QAAQ,EAAE,CAAC;gBAC/C,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;YAChC,CAAC;YACD,OAAO,CAAC,qBAAqB,CAAC,GAAG,SAAS,CAAC;QAC5C,CAAC;IACF,CAAC;IAED,2DAA2D;IAC3D,IAAI,cAAc,EAAE,CAAC;QACpB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,MAAM,CAAC;QACjB,MAAM;QACN,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,uBAAuB,EAAE,IAAI;QAC7B,cAAc,EAAE,OAAO;KACvB,CAAC,CAAC;AAAA,CACH;AAED,SAAS,WAAW,CAAC,KAAgC,EAAE,OAAgB,EAAE,OAAgC,EAAE;IAC1G,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,0BAA0B,EAAE;QACrF,aAAa,EAAE,aAAa,CAAC,QAAQ;KACrC,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACpF,MAAM,MAAM,GAAkC;QAC7C,KAAK,EAAE,KAAK,CAAC,EAAE;QACf,KAAK,EAAE,QAAQ;QACf,MAAM,EAAE,IAAI;QACZ,gBAAgB,EAAE,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,yBAAyB,CAAC,OAAO,EAAE,SAAS,CAAC;QACvG,sBAAsB,EAAE,uBAAuB,CAAC,MAAM,EAAE,cAAc,CAAC;QACvE,KAAK,EAAE,KAAK;KACZ,CAAC;IAEF,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;QACxB,MAAM,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,kCAAkC,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,OAAO,EAAE,WAAW,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,CAAC,WAAW,GAAG,OAAO,EAAE,WAAW,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,EAAE,WAAW,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAC3C,CAAC;IAED,IAAI,aAAa,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,KAAK,GAAG,qBAAqB,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,OAAO,EAAE,UAAU,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IACzC,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACrB,IAAI,OAAO,EAAE,eAAe,IAAI,OAAO,EAAE,gBAAgB,EAAE,CAAC;YAC3D,MAAM,MAAM,GAAG,OAAO,EAAE,eAAe;gBACtC,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,eAAe,CAAC;gBAChF,CAAC,CAAC,QAAQ,CAAC;YACZ,MAAM,CAAC,SAAS,GAAG;gBAClB,MAAM,EAAE,MAAwD;gBAChE,OAAO,EAAE,OAAO,EAAE,gBAAgB,IAAI,MAAM;aAC5C,CAAC;YACF,MAAM,CAAC,OAAO,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;YACxF,MAAM,CAAC,SAAS,GAAG;gBAClB,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,IAAI,MAAM,CAAmD;aACjG,CAAC;QACH,CAAC;IACF,CAAC;IAED,OAAO,MAAM,CAAC;AAAA,CACd;AAED,SAAS,4BAA4B,CACpC,KAA4C,EAC5C,WAAsE,EAC7D;IACT,QAAQ,WAAW,EAAE,CAAC;QACrB,KAAK,MAAM;YACV,OAAO,GAAG,CAAC;QACZ,KAAK,UAAU;YACd,OAAO,KAAK,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC;YACC,OAAO,CAAC,CAAC;IACX,CAAC;AAAA,CACD;AAED,SAAS,uBAAuB,CAC/B,KAAY,EACZ,WAAsE,EACtE,KAA4C,EAC3C;IACD,MAAM,UAAU,GAAG,4BAA4B,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACpE,IAAI,UAAU,KAAK,CAAC;QAAE,OAAO;IAE7B,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC;IAC/B,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,UAAU,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC;IACpC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;AAAA,CACvG","sourcesContent":["import OpenAI from \"openai\";\nimport type { ResponseCreateParamsStreaming } from \"openai/resources/responses/responses.js\";\nimport { clampThinkingLevel } from \"../models.ts\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tCacheRetention,\n\tContext,\n\tModel,\n\tOpenAIResponsesCompat,\n\tProviderEnv,\n\tProviderHeaders,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tUsage,\n} from \"../types.ts\";\nimport { splitDeferredTools } from \"../utils/deferred-tools.ts\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { headersToRecord } from \"../utils/headers.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.ts\";\nimport { clampOpenAIPromptCacheKey } from \"./openai-prompt-cache.ts\";\nimport { convertResponsesMessages, convertResponsesTools, processResponsesStream } from \"./openai-responses-shared.ts\";\nimport { buildBaseOptions } from \"./simple-options.ts\";\n\nconst OPENAI_TOOL_CALL_PROVIDERS = new Set([\"openai\", \"openai-codex\", \"opencode\"]);\n// OpenAI Responses rejects max_output_tokens below 16: https://github.com/earendil-works/pi/issues/6265\nconst OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;\n\nfunction hasHeader(headers: ProviderHeaders | undefined, name: string): boolean {\n\tif (!headers) return false;\n\tconst expected = name.toLowerCase();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (key.toLowerCase() === expected && value !== null && value.trim().length > 0) return true;\n\t}\n\treturn false;\n}\n\nfunction getClientApiKey(provider: string, apiKey: string | undefined, headers: ProviderHeaders | undefined): string {\n\tif (apiKey) return apiKey;\n\tif (hasHeader(headers, \"authorization\") || hasHeader(headers, \"cf-aig-authorization\")) return \"unused\";\n\tthrow new Error(`No API key for provider: ${provider}`);\n}\n\nfunction detectSessionAffinityFormat(model: Pick<Model<\"openai-responses\">, \"provider\" | \"baseUrl\">) {\n\treturn model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\") ? \"openrouter\" : \"openai\";\n}\n\n/**\n * Resolve cache retention preference.\n * Defaults to \"short\" and uses PI_CACHE_RETENTION for backward compatibility.\n */\nfunction resolveCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\nfunction getCompat(model: Model<\"openai-responses\">): Required<OpenAIResponsesCompat> {\n\treturn {\n\t\tsupportsDeveloperRole: model.compat?.supportsDeveloperRole ?? true,\n\t\tsessionAffinityFormat: model.compat?.sessionAffinityFormat ?? detectSessionAffinityFormat(model),\n\t\tsupportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,\n\t\tsupportsToolSearch: model.compat?.supportsToolSearch ?? false,\n\t};\n}\n\nfunction getPromptCacheRetention(\n\tcompat: Required<OpenAIResponsesCompat>,\n\tcacheRetention: CacheRetention,\n): \"24h\" | undefined {\n\treturn cacheRetention === \"long\" && compat.supportsLongCacheRetention ? \"24h\" : undefined;\n}\n\nfunction formatOpenAIResponsesError(error: unknown): string {\n\treturn formatProviderError(normalizeProviderError(error), \"OpenAI API error\");\n}\n\n// OpenAI Responses-specific options\nexport interface OpenAIResponsesOptions extends StreamOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n\tserviceTier?: ResponseCreateParamsStreaming[\"service_tier\"];\n\ttoolChoice?: ResponseCreateParamsStreaming[\"tool_choice\"];\n}\n\n/**\n * Generate function for OpenAI Responses API\n */\nexport const stream: StreamFunction<\"openai-responses\", OpenAIResponsesOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: OpenAIResponsesOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t// Start async processing\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\t// Create OpenAI client\n\t\t\tconst apiKey = getClientApiKey(model.provider, options?.apiKey, options?.headers);\n\t\t\tconst cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);\n\t\t\tconst cacheSessionId = cacheRetention === \"none\" ? undefined : options?.sessionId;\n\t\t\tconst client = createClient(model, context, apiKey, options?.headers, cacheSessionId);\n\t\t\tlet params = buildParams(model, context, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as ResponseCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst requestOptions = {\n\t\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t\t\t...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),\n\t\t\t\tmaxRetries: options?.maxRetries ?? 0,\n\t\t\t};\n\t\t\tconst { data: openaiStream, response } = await client.responses.create(params, requestOptions).withResponse();\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\tawait processResponsesStream(openaiStream, output, stream, model, {\n\t\t\t\tserviceTier: options?.serviceTier,\n\t\t\t\tapplyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model),\n\t\t\t});\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(\"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) {\n\t\t\t\tdelete (block as { index?: number }).index;\n\t\t\t\t// partialJson is only a streaming scratch buffer; never persist it.\n\t\t\t\tdelete (block as { partialJson?: string }).partialJson;\n\t\t\t}\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = formatOpenAIResponsesError(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\nexport const streamSimple: StreamFunction<\"openai-responses\", SimpleStreamOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tgetClientApiKey(model.provider, options?.apiKey, options?.headers);\n\n\tconst base = buildBaseOptions(model, context, options, options?.apiKey);\n\tconst clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;\n\tconst reasoningEffort = clampedReasoning === \"off\" ? undefined : clampedReasoning;\n\n\treturn stream(model, context, {\n\t\t...base,\n\t\treasoningEffort,\n\t} satisfies OpenAIResponsesOptions);\n};\n\nfunction createClient(\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\tapiKey: string,\n\toptionsHeaders?: ProviderHeaders,\n\tsessionId?: string,\n) {\n\tconst compat = getCompat(model);\n\tconst headers: ProviderHeaders = { ...model.headers };\n\tif (model.provider === \"github-copilot\") {\n\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\tconst copilotHeaders = buildCopilotDynamicHeaders({\n\t\t\tmessages: context.messages,\n\t\t\thasImages,\n\t\t});\n\t\tObject.assign(headers, copilotHeaders);\n\t}\n\n\tif (sessionId) {\n\t\tif (compat.sessionAffinityFormat === \"openrouter\") {\n\t\t\theaders[\"x-session-id\"] = sessionId;\n\t\t} else {\n\t\t\tif (compat.sessionAffinityFormat === \"openai\") {\n\t\t\t\theaders.session_id = sessionId;\n\t\t\t}\n\t\t\theaders[\"x-client-request-id\"] = sessionId;\n\t\t}\n\t}\n\n\t// Merge options headers last so they can override defaults\n\tif (optionsHeaders) {\n\t\tObject.assign(headers, optionsHeaders);\n\t}\n\n\treturn new OpenAI({\n\t\tapiKey,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: headers,\n\t});\n}\n\nfunction buildParams(model: Model<\"openai-responses\">, context: Context, options?: OpenAIResponsesOptions) {\n\tconst compat = getCompat(model);\n\tconst toolPlacement = splitDeferredTools(context, compat.supportsToolSearch);\n\tconst messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS, {\n\t\tdeferredTools: toolPlacement.deferred,\n\t});\n\n\tconst cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);\n\tconst params: ResponseCreateParamsStreaming = {\n\t\tmodel: model.id,\n\t\tinput: messages,\n\t\tstream: true,\n\t\tprompt_cache_key: cacheRetention === \"none\" ? undefined : clampOpenAIPromptCacheKey(options?.sessionId),\n\t\tprompt_cache_retention: getPromptCacheRetention(compat, cacheRetention),\n\t\tstore: false,\n\t};\n\n\tif (options?.maxTokens) {\n\t\tparams.max_output_tokens = Math.max(options.maxTokens, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS);\n\t}\n\n\tif (options?.temperature !== undefined) {\n\t\tparams.temperature = options?.temperature;\n\t}\n\n\tif (options?.serviceTier !== undefined) {\n\t\tparams.service_tier = options.serviceTier;\n\t}\n\n\tif (toolPlacement.immediate.length > 0) {\n\t\tparams.tools = convertResponsesTools(toolPlacement.immediate);\n\t}\n\n\tif (options?.toolChoice !== undefined) {\n\t\tparams.tool_choice = options.toolChoice;\n\t}\n\n\tif (model.reasoning) {\n\t\tif (options?.reasoningEffort || options?.reasoningSummary) {\n\t\t\tconst effort = options?.reasoningEffort\n\t\t\t\t? (model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort)\n\t\t\t\t: \"medium\";\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: effort as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t\tsummary: options?.reasoningSummary || \"auto\",\n\t\t\t};\n\t\t\tparams.include = [\"reasoning.encrypted_content\"];\n\t\t} else if (model.provider !== \"github-copilot\" && model.thinkingLevelMap?.off !== null) {\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: (model.thinkingLevelMap?.off ?? \"none\") as NonNullable<typeof params.reasoning>[\"effort\"],\n\t\t\t};\n\t\t}\n\t}\n\n\treturn params;\n}\n\nfunction getServiceTierCostMultiplier(\n\tmodel: Pick<Model<\"openai-responses\">, \"id\">,\n\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n): number {\n\tswitch (serviceTier) {\n\t\tcase \"flex\":\n\t\t\treturn 0.5;\n\t\tcase \"priority\":\n\t\t\treturn model.id === \"gpt-5.5\" ? 2.5 : 2;\n\t\tdefault:\n\t\t\treturn 1;\n\t}\n}\n\nfunction applyServiceTierPricing(\n\tusage: Usage,\n\tserviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined,\n\tmodel: Pick<Model<\"openai-responses\">, \"id\">,\n) {\n\tconst multiplier = getServiceTierCostMultiplier(model, serviceTier);\n\tif (multiplier === 1) return;\n\n\tusage.cost.input *= multiplier;\n\tusage.cost.output *= multiplier;\n\tusage.cost.cacheRead *= multiplier;\n\tusage.cost.cacheWrite *= multiplier;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n}\n"]}
|