@cydm/pie 2.6.12 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +68 -2
  2. package/dist/builtin/extensions/ask-user/index.js +3 -3
  3. package/dist/builtin/extensions/plan-mode/index.js +130 -21
  4. package/dist/builtin/extensions/subagent/index.js +4 -5
  5. package/dist/builtin/extensions/todo/index.js +3 -3
  6. package/dist/builtin/skills/computer-use-axi/SKILL.md +103 -0
  7. package/dist/builtin/skills/computer-use-axi/computer-use-axi-cli.js +37 -0
  8. package/dist/builtin/{extensions/computer-use/index.js → skills/computer-use-axi/computer-use-axi-runtime.js} +754 -642
  9. package/dist/builtin/skills/computer-use-axi/package.json +11 -0
  10. package/dist/chunks/{chunk-PPEWRUMQ.js → chunk-6RBSTII7.js} +657 -594
  11. package/dist/chunks/{chunk-AAEBH6KX.js → chunk-IPNAFMOJ.js} +172 -230
  12. package/dist/chunks/{chunk-7B4IIBVS.js → chunk-R5I2QLF2.js} +1269 -4
  13. package/dist/chunks/{chunk-HHNOENEH.js → chunk-TWILEFLD.js} +14 -1
  14. package/dist/chunks/{src-OWQI5M6W.js → src-E7NCXMU5.js} +2 -2
  15. package/dist/chunks/{test-stream-Y7WXELAJ.js → test-stream-BWBJTFNI.js} +1 -1
  16. package/dist/cli.js +463 -232
  17. package/models.schema.json +52 -0
  18. package/package.json +3 -3
  19. package/dist/builtin/extensions/computer-use/package.json +0 -14
  20. package/dist/builtin/extensions/computer-use/scripts/build-native.mjs +0 -278
  21. package/dist/builtin/extensions/computer-use/scripts/test-native-retention.mjs +0 -204
  22. package/dist/chunks/chunk-5353DEEC.js +0 -130
  23. package/dist/chunks/webapi-MBCKO7ZV.js +0 -2481
  24. package/dist/code-intel-worker.cjs +0 -211227
  25. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/linux/arm64/linux-bridge +0 -0
  26. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/linux/x64/linux-bridge +0 -0
  27. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/arm64/pie-computer-use +0 -0
  28. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/universal/pie-computer-use.app/Contents/Info.plist +0 -0
  29. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/universal/pie-computer-use.app/Contents/MacOS/pie-computer-use +0 -0
  30. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/universal/pie-computer-use.app/Contents/_CodeSignature/CodeResources +0 -0
  31. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/macos/x64/pie-computer-use +0 -0
  32. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/prebuilt/windows/windows-bridge.exe +0 -0
  33. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/scripts/helper-path.mjs +0 -0
  34. /package/dist/builtin/{extensions/computer-use → skills/computer-use-axi}/scripts/setup-helper.mjs +0 -0
@@ -474,12 +474,16 @@ function calculateCost(model, usage) {
474
474
  const output = model.cost.output / 1e6 * usage.output;
475
475
  const cacheRead = model.cost.cacheRead / 1e6 * usage.cacheRead;
476
476
  const cacheWrite = model.cost.cacheWrite / 1e6 * usage.cacheWrite;
477
+ const cacheWriteLongTokens = usage.cacheWriteLong ?? 0;
478
+ const cacheWriteLongRate = model.cost.cacheWriteLong ?? model.cost.input * 2;
479
+ const cacheWriteLong = cacheWriteLongTokens > 0 ? cacheWriteLongRate / 1e6 * cacheWriteLongTokens : 0;
477
480
  return {
478
481
  input,
479
482
  output,
480
483
  cacheRead,
481
484
  cacheWrite,
482
- total: input + output + cacheRead + cacheWrite
485
+ ...cacheWriteLongTokens > 0 ? { cacheWriteLong } : {},
486
+ total: input + output + cacheRead + cacheWrite + cacheWriteLong
483
487
  };
484
488
  }
485
489
 
@@ -3047,6 +3051,227 @@ function deletePuertsDirectoryByEnumeration(path, recursive) {
3047
3051
  warnPuertsDeletionShellsOnce(path);
3048
3052
  }
3049
3053
 
3054
+ // ../../packages/platform/src/websocket-node.ts
3055
+ import { createRequire as createRequire5 } from "node:module";
3056
+ var require5 = createRequire5(import.meta.url);
3057
+ var failure = (kind, message) => new WebSocketTransportError(kind, message);
3058
+ var NodeWebSocketClient = class {
3059
+ async connect(url, options = {}) {
3060
+ if (options.signal?.aborted) throw failure("aborted", "Connection aborted");
3061
+ for (const field of ["maxMessageBytes", "maxBufferedBytes", "maxBufferedMessages", "connectTimeoutMs"]) {
3062
+ const value = options[field];
3063
+ if (value !== void 0 && (!Number.isFinite(value) || value <= 0)) throw failure("protocol", `Invalid ${field}`);
3064
+ }
3065
+ const WS = require5("ws");
3066
+ const socket = new WS(url, {
3067
+ headers: options.headers,
3068
+ maxPayload: options.maxMessageBytes ?? 32 * 1024 * 1024
3069
+ });
3070
+ return new Promise((resolve, reject) => {
3071
+ const connection = new NodeConnection(socket, options);
3072
+ const timeout = setTimeout(() => connection.fail(failure("timeout", "WebSocket handshake timed out")), options.connectTimeoutMs ?? 3e4);
3073
+ const cleanup = () => {
3074
+ clearTimeout(timeout);
3075
+ socket.off("open", opened);
3076
+ socket.off("error", error);
3077
+ socket.off("close", closed);
3078
+ socket.off("unexpected-response", refused);
3079
+ };
3080
+ const opened = () => {
3081
+ cleanup();
3082
+ resolve(connection);
3083
+ };
3084
+ const error = () => {
3085
+ cleanup();
3086
+ reject(connection.error ?? failure("handshake", "WebSocket connection failed"));
3087
+ };
3088
+ const closed = () => {
3089
+ cleanup();
3090
+ reject(connection.error ?? failure("handshake", "Connection closed before opening"));
3091
+ };
3092
+ const refused = (_, response) => {
3093
+ cleanup();
3094
+ const err = new WebSocketTransportError("handshake", "WebSocket upgrade refused", { status: response.statusCode });
3095
+ connection.fail(err);
3096
+ response.destroy();
3097
+ reject(err);
3098
+ };
3099
+ socket.once("open", opened);
3100
+ socket.once("error", error);
3101
+ socket.once("close", closed);
3102
+ socket.once("unexpected-response", refused);
3103
+ });
3104
+ }
3105
+ };
3106
+ var NodeConnection = class {
3107
+ constructor(socket, options) {
3108
+ this.socket = socket;
3109
+ this.options = options;
3110
+ this.closed = new Promise((resolve) => {
3111
+ this.resolveClosed = resolve;
3112
+ });
3113
+ socket.on("error", (error) => this.fail(failure(
3114
+ error.code === "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" ? "overflow" : this.opened ? "protocol" : "handshake",
3115
+ "WebSocket transport failed"
3116
+ )));
3117
+ socket.on("open", () => {
3118
+ this.opened = true;
3119
+ this.armIdle();
3120
+ });
3121
+ socket.on("message", (data, isBinary) => {
3122
+ if (this.ended || this.error) return;
3123
+ const buffer = Array.isArray(data) ? Buffer.concat(data) : Buffer.from(data);
3124
+ const bytes = buffer.byteLength;
3125
+ if (bytes > (options.maxMessageBytes ?? 32 * 1024 * 1024) || this.queue.length >= (options.maxBufferedMessages ?? 256) || this.queuedBytes + bytes > (options.maxBufferedBytes ?? 32 * 1024 * 1024)) {
3126
+ this.fail(failure("overflow", "Incoming WebSocket buffer exceeded"));
3127
+ return;
3128
+ }
3129
+ this.queue.push({ data: buffer.toString("utf8"), isBinary, bytes });
3130
+ this.queuedBytes += bytes;
3131
+ this.armIdle();
3132
+ this.wake?.();
3133
+ });
3134
+ socket.once("close", (code, reason) => {
3135
+ this.ended = true;
3136
+ clearTimeout(this.idle);
3137
+ clearTimeout(this.closeTimer);
3138
+ options.signal?.removeEventListener("abort", this.abort);
3139
+ this.resolveClosed({ code, reason: reason.toString() });
3140
+ this.wake?.();
3141
+ });
3142
+ options.signal?.addEventListener("abort", this.abort, { once: true });
3143
+ if (options.signal?.aborted) this.abort();
3144
+ }
3145
+ socket;
3146
+ options;
3147
+ closed;
3148
+ error;
3149
+ resolveClosed;
3150
+ queue = [];
3151
+ queuedBytes = 0;
3152
+ pendingBytes = 0;
3153
+ pendingMessages = 0;
3154
+ sending = Promise.resolve();
3155
+ wake;
3156
+ receiving = false;
3157
+ ended = false;
3158
+ opened = false;
3159
+ idle;
3160
+ closeTimer;
3161
+ abort = () => this.fail(failure("aborted", "Connection aborted"));
3162
+ fail(error) {
3163
+ if (this.ended || this.error) return;
3164
+ this.error = error;
3165
+ this.queue = [];
3166
+ this.queuedBytes = 0;
3167
+ clearTimeout(this.idle);
3168
+ this.socket.terminate();
3169
+ this.wake?.();
3170
+ }
3171
+ armIdle() {
3172
+ clearTimeout(this.idle);
3173
+ if (this.options.idleTimeoutMs && this.options.idleTimeoutMs > 0) {
3174
+ this.idle = setTimeout(() => this.fail(failure("timeout", "WebSocket idle timeout")), this.options.idleTimeoutMs);
3175
+ }
3176
+ }
3177
+ async send(message, options) {
3178
+ const bytes = Buffer.byteLength(message);
3179
+ if (bytes > (this.options.maxMessageBytes ?? 32 * 1024 * 1024) || this.pendingBytes + bytes > (this.options.maxBufferedBytes ?? 32 * 1024 * 1024) || this.pendingMessages >= (this.options.maxBufferedMessages ?? 256)) {
3180
+ throw failure("overflow", "Outgoing WebSocket buffer exceeded");
3181
+ }
3182
+ const signal = options?.signal;
3183
+ if (signal?.aborted) {
3184
+ this.abort();
3185
+ throw failure("aborted", "Send aborted");
3186
+ }
3187
+ const abortSend = () => this.abort();
3188
+ signal?.addEventListener("abort", abortSend, { once: true });
3189
+ this.pendingBytes += bytes;
3190
+ this.pendingMessages++;
3191
+ const operation = this.sending.then(() => new Promise((resolve, reject) => {
3192
+ if (this.error) {
3193
+ reject(this.error);
3194
+ return;
3195
+ }
3196
+ if (this.socket.readyState !== 1) {
3197
+ reject(failure("closed", "Connection is not open"));
3198
+ return;
3199
+ }
3200
+ this.socket.send(message, (error) => error ? reject(this.error ?? failure("closed", "Send failed")) : resolve());
3201
+ }));
3202
+ this.sending = operation.catch(() => {
3203
+ });
3204
+ try {
3205
+ await operation;
3206
+ } finally {
3207
+ this.pendingBytes -= bytes;
3208
+ this.pendingMessages--;
3209
+ signal?.removeEventListener("abort", abortSend);
3210
+ }
3211
+ }
3212
+ async *receive(signal) {
3213
+ if (this.receiving) throw failure("protocol", "Only one receiver is permitted");
3214
+ this.receiving = true;
3215
+ const abortReceive = () => this.abort();
3216
+ signal?.addEventListener("abort", abortReceive, { once: true });
3217
+ try {
3218
+ while (true) {
3219
+ if (signal?.aborted) this.abort();
3220
+ if (this.error) throw this.error;
3221
+ const item = this.queue.shift();
3222
+ if (item) {
3223
+ this.queuedBytes -= item.bytes;
3224
+ yield item;
3225
+ continue;
3226
+ }
3227
+ if (this.ended) return;
3228
+ await new Promise((resolve) => {
3229
+ this.wake = resolve;
3230
+ });
3231
+ this.wake = void 0;
3232
+ }
3233
+ } finally {
3234
+ this.receiving = false;
3235
+ this.wake = void 0;
3236
+ signal?.removeEventListener("abort", abortReceive);
3237
+ }
3238
+ }
3239
+ async close(code = 1e3, reason = "") {
3240
+ if (!this.ended && this.socket.readyState < 2) {
3241
+ this.socket.close(code, reason);
3242
+ this.closeTimer = setTimeout(() => this.socket.terminate(), 1e3);
3243
+ }
3244
+ await this.closed;
3245
+ }
3246
+ state() {
3247
+ return ["connecting", "open", "closing", "closed"][this.socket.readyState];
3248
+ }
3249
+ };
3250
+
3251
+ // ../../packages/platform/src/websocket.ts
3252
+ var WebSocketTransportError = class extends Error {
3253
+ kind;
3254
+ /** HTTP status of a refused handshake, when the transport reports one. */
3255
+ status;
3256
+ /** Close code carried by the failure, when one exists. */
3257
+ closeCode;
3258
+ constructor(kind, message, details = {}) {
3259
+ super(`[websocket:${kind}] ${message}`);
3260
+ this.name = "WebSocketTransportError";
3261
+ this.kind = kind;
3262
+ if (details.status !== void 0) this.status = details.status;
3263
+ if (details.closeCode !== void 0) this.closeCode = details.closeCode;
3264
+ }
3265
+ };
3266
+ var webSocketClientInstance;
3267
+ function getNodeWebSocketClient() {
3268
+ return detectPlatform() === "node" ? new NodeWebSocketClient() : void 0;
3269
+ }
3270
+ function getWebSocketClient() {
3271
+ if (webSocketClientInstance === void 0) webSocketClientInstance = getNodeWebSocketClient() ?? null;
3272
+ return webSocketClientInstance ?? void 0;
3273
+ }
3274
+
3050
3275
  // ../../packages/platform/src/index.ts
3051
3276
  var fileSystemInstance = null;
3052
3277
  var httpClientInstance = null;
@@ -3123,6 +3348,8 @@ function buildBaseOptions(model, options, apiKey) {
3123
3348
  const modelMaxTokens = positiveFiniteOrInfinity(model.maxTokens);
3124
3349
  return {
3125
3350
  temperature: options?.temperature,
3351
+ transport: options?.transport ?? model.transport,
3352
+ transportOwner: options?.transportOwner,
3126
3353
  maxTokens: options?.maxTokens || Math.min(modelMaxTokens, DEFAULT_MAX_TOKENS),
3127
3354
  signal: options?.signal,
3128
3355
  apiKey: apiKey || options?.apiKey,
@@ -3131,6 +3358,7 @@ function buildBaseOptions(model, options, apiKey) {
3131
3358
  headers: options?.headers,
3132
3359
  timeoutMs: options?.timeoutMs,
3133
3360
  onPayload: options?.onPayload,
3361
+ onTransportDiagnostic: options?.onTransportDiagnostic,
3134
3362
  maxRetryDelayMs: options?.maxRetryDelayMs,
3135
3363
  metadata: options?.metadata
3136
3364
  };
@@ -3729,6 +3957,7 @@ function tryParseFinalToolArguments(partialArgs) {
3729
3957
  }
3730
3958
  }
3731
3959
  var streamOpenAICompletions = (model, context, options) => {
3960
+ if ((options?.transport ?? model.transport) === "websocket") throw new Error(`API ${model.api} does not support WebSocket transport.`);
3732
3961
  const stream = new AssistantMessageEventStream();
3733
3962
  (async () => {
3734
3963
  const output = {
@@ -4395,6 +4624,7 @@ function applyCacheBreakpoints(params, retention) {
4395
4624
  }
4396
4625
  }
4397
4626
  var streamAnthropic = (model, context, options) => {
4627
+ if ((options?.transport ?? model.transport) === "websocket") throw new Error(`API ${model.api} does not support WebSocket transport.`);
4398
4628
  const stream = new AssistantMessageEventStream();
4399
4629
  (async () => {
4400
4630
  const output = {
@@ -4470,7 +4700,12 @@ var streamAnthropic = (model, context, options) => {
4470
4700
  output.usage.output = event.message.usage.output_tokens || 0;
4471
4701
  output.usage.cacheRead = event.message.usage.cache_read_input_tokens || 0;
4472
4702
  output.usage.cacheWrite = event.message.usage.cache_creation_input_tokens || 0;
4473
- output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
4703
+ const creation = event.message.usage.cache_creation;
4704
+ if (creation?.ephemeral_1h_input_tokens) {
4705
+ output.usage.cacheWriteLong = creation.ephemeral_1h_input_tokens;
4706
+ output.usage.cacheWrite = Math.max(0, output.usage.cacheWrite - creation.ephemeral_1h_input_tokens);
4707
+ }
4708
+ output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite + (output.usage.cacheWriteLong ?? 0);
4474
4709
  calculateCost(model, output.usage);
4475
4710
  } else if (event.type === "content_block_start") {
4476
4711
  if (event.content_block.type === "text") {
@@ -4578,9 +4813,15 @@ var streamAnthropic = (model, context, options) => {
4578
4813
  if (event.usage.input_tokens != null) output.usage.input = event.usage.input_tokens;
4579
4814
  if (event.usage.output_tokens != null) output.usage.output = event.usage.output_tokens;
4580
4815
  if (event.usage.cache_read_input_tokens != null) output.usage.cacheRead = event.usage.cache_read_input_tokens;
4581
- if (event.usage.cache_creation_input_tokens != null)
4816
+ if (event.usage.cache_creation_input_tokens != null) {
4582
4817
  output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
4583
- output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
4818
+ const creationDelta = event.usage.cache_creation;
4819
+ if (creationDelta?.ephemeral_1h_input_tokens) {
4820
+ output.usage.cacheWriteLong = creationDelta.ephemeral_1h_input_tokens;
4821
+ output.usage.cacheWrite = Math.max(0, output.usage.cacheWrite - creationDelta.ephemeral_1h_input_tokens);
4822
+ }
4823
+ }
4824
+ output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite + (output.usage.cacheWriteLong ?? 0);
4584
4825
  calculateCost(model, output.usage);
4585
4826
  }
4586
4827
  }
@@ -4619,6 +4860,1024 @@ var streamSimpleAnthropic = (model, context, options) => {
4619
4860
  });
4620
4861
  };
4621
4862
 
4863
+ // ../../packages/ai/src/providers/responses/responses-compat.ts
4864
+ function getResponsesCompat(model) {
4865
+ const compat = model.compat ?? {};
4866
+ return {
4867
+ store: compat.store ?? false,
4868
+ supportsStore: compat.supportsStore ?? true,
4869
+ supportsReasoningEffort: compat.supportsReasoningEffort ?? true,
4870
+ supportsEncryptedReasoning: compat.supportsEncryptedReasoning ?? true,
4871
+ responsesContinuation: compat.responsesContinuation ?? false
4872
+ };
4873
+ }
4874
+
4875
+ // ../../packages/ai/src/providers/responses/responses-wire.ts
4876
+ var RESPONSES_PROTOCOL_ERROR_CODE = "responses_protocol_error";
4877
+ var ResponsesProtocolError = class extends Error {
4878
+ code = RESPONSES_PROTOCOL_ERROR_CODE;
4879
+ constructor(message) {
4880
+ super(`${RESPONSES_PROTOCOL_ERROR_CODE}: ${message}`);
4881
+ this.name = "ResponsesProtocolError";
4882
+ }
4883
+ };
4884
+ function isRecord2(value) {
4885
+ return value !== null && typeof value === "object" && !Array.isArray(value);
4886
+ }
4887
+ function isResponsesEventLike(value) {
4888
+ return isRecord2(value) && typeof value.type === "string";
4889
+ }
4890
+ function formatResponsesErrorEvent(event) {
4891
+ const source = isRecord2(event.error) ? event.error : event;
4892
+ const message = typeof source.message === "string" && source.message.length > 0 ? source.message : "Responses stream returned an error";
4893
+ const metadata = [];
4894
+ if (typeof source.code === "string" && source.code.length > 0) {
4895
+ metadata.push(`code=${source.code}`);
4896
+ }
4897
+ if (typeof source.param === "string" && source.param.length > 0) {
4898
+ metadata.push(`param=${source.param}`);
4899
+ }
4900
+ if (typeof event.status === "number") {
4901
+ metadata.push(`status=${event.status}`);
4902
+ }
4903
+ return metadata.length > 0 ? `${message} (${metadata.join(", ")})` : message;
4904
+ }
4905
+
4906
+ // ../../packages/ai/src/providers/responses/responses-request.ts
4907
+ var MAX_REASONING_ENVELOPE_BYTES = 512 * 1024;
4908
+ function decodeReasoningEnvelope(signature) {
4909
+ if (typeof signature !== "string" || signature.length === 0 || signature.length > MAX_REASONING_ENVELOPE_BYTES) {
4910
+ return null;
4911
+ }
4912
+ let parsed;
4913
+ try {
4914
+ parsed = JSON.parse(signature);
4915
+ } catch {
4916
+ return null;
4917
+ }
4918
+ if (!isRecord2(parsed) || parsed.v !== 1 || typeof parsed.id !== "string" || parsed.id.length === 0) {
4919
+ return null;
4920
+ }
4921
+ const encrypted = parsed.encrypted_content;
4922
+ if (encrypted !== void 0 && encrypted !== null && typeof encrypted !== "string") {
4923
+ return null;
4924
+ }
4925
+ return { v: 1, id: parsed.id, encrypted_content: encrypted };
4926
+ }
4927
+ function buildResponsesInput(model, context) {
4928
+ const items = [];
4929
+ const isSameModel = (msg) => msg.provider === model.provider && msg.api === model.api && msg.model === model.id;
4930
+ const transformed = transformMessages(context.messages, model);
4931
+ for (const msg of transformed) {
4932
+ if (msg.role === "user") {
4933
+ items.push(encodeUserMessage(msg.content, model));
4934
+ } else if (msg.role === "assistant") {
4935
+ encodeAssistantMessage(msg, isSameModel, items);
4936
+ } else if (msg.role === "toolResult") {
4937
+ items.push(encodeToolResult(msg, model));
4938
+ }
4939
+ }
4940
+ return items;
4941
+ }
4942
+ function encodeUserMessage(content, model) {
4943
+ if (typeof content === "string") {
4944
+ return { role: "user", type: "message", content };
4945
+ }
4946
+ const parts = [];
4947
+ for (const block of content) {
4948
+ parts.push(...encodeUserContentBlock(block, model));
4949
+ }
4950
+ if (parts.length === 0) {
4951
+ return { role: "user", type: "message", content: "" };
4952
+ }
4953
+ return { role: "user", type: "message", content: parts };
4954
+ }
4955
+ function encodeUserContentBlock(block, model) {
4956
+ const modality = block.type === "fileRef" ? block.modality : block.type;
4957
+ if (modality !== "text" && !model.input.includes(modality)) {
4958
+ throw new ResponsesProtocolError(`Current model does not support ${modality} input.`);
4959
+ }
4960
+ switch (block.type) {
4961
+ case "text":
4962
+ return [{ type: "input_text", text: block.text }];
4963
+ case "image":
4964
+ return [{ type: "input_image", image_url: `data:${block.mimeType};base64,${block.data}` }];
4965
+ case "video":
4966
+ case "audio":
4967
+ throw new ResponsesProtocolError(`Responses ${block.type} input is not supported by this provider.`);
4968
+ case "fileRef": {
4969
+ const ref = block;
4970
+ if (ref.modality === "image") {
4971
+ return [{ type: "input_image", image_url: ref.url }];
4972
+ }
4973
+ throw new ResponsesProtocolError(`Responses ${ref.modality} file references are not supported by this provider.`);
4974
+ }
4975
+ default:
4976
+ throw new ResponsesProtocolError("Unsupported Responses content block.");
4977
+ }
4978
+ }
4979
+ function encodeAssistantMessage(msg, isSameModel, items) {
4980
+ for (const block of msg.content) {
4981
+ if (block.type === "thinking") {
4982
+ const thinking = block;
4983
+ if (isSameModel(msg)) {
4984
+ const envelope = decodeReasoningEnvelope(thinking.thinkingSignature);
4985
+ if (thinking.thinkingSignature && !envelope) {
4986
+ throw new ResponsesProtocolError("Invalid Responses reasoning signature.");
4987
+ }
4988
+ if (envelope) {
4989
+ items.push({
4990
+ type: "reasoning",
4991
+ id: envelope.id,
4992
+ summary: thinking.thinking.trim() ? [{ type: "summary_text", text: thinking.thinking }] : [],
4993
+ ...envelope.encrypted_content ? { encrypted_content: envelope.encrypted_content } : {}
4994
+ });
4995
+ continue;
4996
+ }
4997
+ }
4998
+ if (thinking.thinking && thinking.thinking.trim().length > 0) {
4999
+ items.push({ role: "assistant", type: "message", content: thinking.thinking });
5000
+ }
5001
+ continue;
5002
+ }
5003
+ if (block.type === "text") {
5004
+ const text = block;
5005
+ if (text.text && text.text.trim().length > 0) {
5006
+ items.push({ role: "assistant", type: "message", content: text.text });
5007
+ }
5008
+ continue;
5009
+ }
5010
+ if (block.type === "toolCall") {
5011
+ const call = block;
5012
+ items.push({
5013
+ type: "function_call",
5014
+ call_id: call.id,
5015
+ name: call.name,
5016
+ arguments: JSON.stringify(call.arguments ?? {})
5017
+ });
5018
+ }
5019
+ }
5020
+ }
5021
+ function buildResponsesOutput(message) {
5022
+ const items = [];
5023
+ encodeAssistantMessage(message, () => true, items);
5024
+ return items;
5025
+ }
5026
+ function encodeToolResult(msg, model) {
5027
+ const output = msg.content.every((block) => block.type === "text") ? msg.content.map((block) => block.text).join("\n") || "(empty result)" : msg.content.flatMap((block) => encodeUserContentBlock(block, model));
5028
+ return { type: "function_call_output", call_id: msg.toolCallId, output };
5029
+ }
5030
+ function encodeTools(tools) {
5031
+ return tools.map((tool) => ({
5032
+ type: "function",
5033
+ name: tool.name,
5034
+ description: tool.description,
5035
+ parameters: tool.parameters ?? { type: "object", properties: {} },
5036
+ strict: false
5037
+ }));
5038
+ }
5039
+ function buildResponsesRequest(model, context, options, compat = getResponsesCompat(model)) {
5040
+ const params = {
5041
+ model: model.id,
5042
+ input: buildResponsesInput(model, context)
5043
+ };
5044
+ if (context.systemPrompt !== void 0 && context.systemPrompt !== null && context.systemPrompt.length > 0) {
5045
+ params.instructions = context.systemPrompt;
5046
+ }
5047
+ if (compat.supportsStore) {
5048
+ params.store = compat.store;
5049
+ }
5050
+ if (options?.maxTokens !== void 0 && options.maxTokens > 0) {
5051
+ params.max_output_tokens = options.maxTokens;
5052
+ }
5053
+ if (options?.temperature !== void 0) params.temperature = options.temperature;
5054
+ if (options?.topP !== void 0) params.top_p = options.topP;
5055
+ if (options?.reasoningEffort && model.reasoning && compat.supportsReasoningEffort) {
5056
+ params.reasoning = { effort: options.reasoningEffort };
5057
+ }
5058
+ if (compat.supportsEncryptedReasoning && model.reasoning) {
5059
+ params.include = ["reasoning.encrypted_content"];
5060
+ }
5061
+ if (context.tools && context.tools.length > 0) {
5062
+ params.tools = encodeTools(context.tools);
5063
+ params.parallel_tool_calls = true;
5064
+ }
5065
+ if (options?.toolChoice !== void 0) {
5066
+ params.tool_choice = options.toolChoice === "required" ? "required" : options.toolChoice;
5067
+ }
5068
+ return params;
5069
+ }
5070
+ function buildResponsesSSEPayload(model, context, options) {
5071
+ return { ...buildResponsesRequest(model, context, options), stream: true };
5072
+ }
5073
+ function buildResponsesCreateEvent(model, context, options) {
5074
+ const params = buildResponsesRequest(model, context, options);
5075
+ delete params.stream;
5076
+ return { type: "response.create", ...params };
5077
+ }
5078
+
5079
+ // ../../packages/ai/src/providers/responses/responses-usage.ts
5080
+ function tokenCount(value) {
5081
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return void 0;
5082
+ return Math.floor(value);
5083
+ }
5084
+ function normalizeResponsesUsage(model, usage) {
5085
+ const inputTokens = tokenCount(usage?.input_tokens);
5086
+ const cachedTokens = tokenCount(usage?.input_tokens_details?.cached_tokens) ?? 0;
5087
+ const cacheWriteTokens = tokenCount(usage?.input_tokens_details?.cache_write_tokens) ?? 0;
5088
+ const outputTokens = tokenCount(usage?.output_tokens);
5089
+ const reasoningTokens = tokenCount(usage?.output_tokens_details?.reasoning_tokens);
5090
+ const totalTokens = tokenCount(usage?.total_tokens);
5091
+ const input = inputTokens ?? (totalTokens !== void 0 && outputTokens !== void 0 ? Math.max(cachedTokens + cacheWriteTokens, totalTokens - outputTokens) : cachedTokens + cacheWriteTokens);
5092
+ const output = outputTokens ?? (totalTokens !== void 0 ? Math.max(reasoningTokens ?? 0, totalTokens - input) : reasoningTokens ?? 0);
5093
+ const cacheRead = Math.min(cachedTokens, input);
5094
+ const cacheWrite = Math.min(cacheWriteTokens, input - cacheRead);
5095
+ const inputExclusive = input - cacheRead - cacheWrite;
5096
+ const partitionTotal = input + output;
5097
+ const base = {
5098
+ input: inputExclusive,
5099
+ output,
5100
+ cacheRead,
5101
+ cacheWrite,
5102
+ totalTokens: Math.max(totalTokens ?? 0, partitionTotal)
5103
+ };
5104
+ return { ...base, cost: calculateCost(model, base) };
5105
+ }
5106
+
5107
+ // ../../packages/ai/src/providers/responses/responses-events.ts
5108
+ var ResponsesEventReducer = class {
5109
+ output;
5110
+ model;
5111
+ started = false;
5112
+ terminal = null;
5113
+ items = /* @__PURE__ */ new Map();
5114
+ toolCallStates = [];
5115
+ diagnostics = { unknownEventTypes: /* @__PURE__ */ new Set(), ignoredItemTypes: /* @__PURE__ */ new Set(), terminalType: null };
5116
+ constructor(model) {
5117
+ this.model = model;
5118
+ this.output = {
5119
+ role: "assistant",
5120
+ content: [],
5121
+ api: model.api,
5122
+ provider: model.provider,
5123
+ model: model.id,
5124
+ usageReported: false,
5125
+ usage: {
5126
+ input: 0,
5127
+ output: 0,
5128
+ cacheRead: 0,
5129
+ cacheWrite: 0,
5130
+ totalTokens: 0,
5131
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
5132
+ },
5133
+ stopReason: "stop",
5134
+ timestamp: Date.now()
5135
+ };
5136
+ }
5137
+ get message() {
5138
+ return this.output;
5139
+ }
5140
+ get isTerminal() {
5141
+ return this.terminal !== null;
5142
+ }
5143
+ /** Terminal response object (present on completed/incomplete/failed). */
5144
+ get terminalResponse() {
5145
+ return this.terminal?.response;
5146
+ }
5147
+ /** Feed one raw wire event; returns the AssistantMessageEvents to emit. */
5148
+ feed(raw) {
5149
+ const events = [];
5150
+ if (!isResponsesEventLike(raw)) {
5151
+ throw new ResponsesProtocolError("Responses stream returned an event without a string type.");
5152
+ }
5153
+ if (this.terminal) return events;
5154
+ switch (raw.type) {
5155
+ case "response.created":
5156
+ case "response.in_progress":
5157
+ case "response.queued":
5158
+ if (!this.started) {
5159
+ this.started = true;
5160
+ events.push({ type: "start", partial: this.output });
5161
+ }
5162
+ break;
5163
+ case "response.output_item.added":
5164
+ events.push(...this.onOutputItemAdded(raw));
5165
+ break;
5166
+ case "response.output_item.done":
5167
+ events.push(...this.onOutputItemDone(raw));
5168
+ break;
5169
+ case "response.content_part.added":
5170
+ events.push(...this.onContentPartAdded(raw));
5171
+ break;
5172
+ case "response.content_part.done":
5173
+ break;
5174
+ case "response.output_text.delta":
5175
+ events.push(...this.appendTextDelta(raw, "text"));
5176
+ break;
5177
+ case "response.output_text.done":
5178
+ this.validateTextDone(raw);
5179
+ break;
5180
+ case "response.refusal.delta":
5181
+ events.push(...this.appendTextDelta(raw, "refusal"));
5182
+ break;
5183
+ case "response.refusal.done":
5184
+ break;
5185
+ case "response.reasoning_summary_text.delta":
5186
+ case "response.reasoning_text.delta":
5187
+ events.push(...this.appendReasoningDelta(raw));
5188
+ break;
5189
+ case "response.reasoning_summary_text.done":
5190
+ case "response.reasoning_text.done":
5191
+ break;
5192
+ case "response.reasoning_summary_part.added":
5193
+ case "response.reasoning_summary_part.done":
5194
+ break;
5195
+ case "response.function_call_arguments.delta":
5196
+ events.push(...this.appendFunctionCallArgsDelta(raw));
5197
+ break;
5198
+ case "response.function_call_arguments.done":
5199
+ this.onFunctionCallArgsDone(raw);
5200
+ break;
5201
+ case "response.completed":
5202
+ events.push(...this.onTerminal(raw, "response.completed"));
5203
+ break;
5204
+ case "response.incomplete":
5205
+ events.push(...this.onIncomplete(raw));
5206
+ break;
5207
+ case "response.failed":
5208
+ events.push(...this.onTerminal(raw, "response.failed", "error", this.failedText(raw)));
5209
+ break;
5210
+ case "error":
5211
+ events.push(...this.onTerminal(raw, "error", "error", formatResponsesErrorEvent(raw)));
5212
+ break;
5213
+ default:
5214
+ this.diagnostics.unknownEventTypes.add(raw.type);
5215
+ break;
5216
+ }
5217
+ return events;
5218
+ }
5219
+ /** Stream ended without a terminal event. Caller decides how to fail. */
5220
+ finishWithoutTerminal() {
5221
+ return new ResponsesProtocolError(
5222
+ `Responses stream ended without a terminal event (${this.diagnostics.terminalType ?? "none"} seen).`
5223
+ );
5224
+ }
5225
+ // ─── item lifecycle ─────────────────────────────────────────────────────
5226
+ ensureStarted() {
5227
+ if (this.started) return [];
5228
+ this.started = true;
5229
+ return [{ type: "start", partial: this.output }];
5230
+ }
5231
+ requireItemIndex(raw) {
5232
+ const index = raw.output_index;
5233
+ if (typeof index !== "number" || !Number.isInteger(index) || index < 0) {
5234
+ throw new ResponsesProtocolError(`Responses event "${raw.type}" is missing a valid output_index.`);
5235
+ }
5236
+ return index;
5237
+ }
5238
+ onOutputItemAdded(raw) {
5239
+ const outputIndex = this.requireItemIndex(raw);
5240
+ const item = raw.item;
5241
+ if (!isRecord2(item)) {
5242
+ throw new ResponsesProtocolError(`response.output_item.added at index ${outputIndex} is missing the item.`);
5243
+ }
5244
+ if (this.items.has(outputIndex)) {
5245
+ throw new ResponsesProtocolError(`Responses stream reused output_index ${outputIndex}.`);
5246
+ }
5247
+ const itemId = typeof item.id === "string" ? item.id : "";
5248
+ if (item.type === "message") {
5249
+ this.items.set(outputIndex, { kind: "message", itemId, blocks: /* @__PURE__ */ new Map() });
5250
+ return this.ensureStarted();
5251
+ }
5252
+ if (item.type === "reasoning") {
5253
+ const block = { type: "thinking", thinking: "" };
5254
+ this.output.content.push(block);
5255
+ this.items.set(outputIndex, { kind: "reasoning", itemId, block, lastSummaryIndex: null });
5256
+ const startEvents = this.ensureStarted();
5257
+ return [
5258
+ ...startEvents,
5259
+ { type: "thinking_start", contentIndex: this.output.content.length - 1, partial: this.output }
5260
+ ];
5261
+ }
5262
+ if (item.type === "function_call") {
5263
+ const callId = typeof item.call_id === "string" ? item.call_id : "";
5264
+ if (!callId) {
5265
+ throw new ResponsesProtocolError(`function_call output item at index ${outputIndex} is missing call_id.`);
5266
+ }
5267
+ const name = typeof item.name === "string" ? item.name : "";
5268
+ if (!name || !itemId) throw new ResponsesProtocolError("function_call requires name and item id.");
5269
+ const block = { type: "toolCall", id: callId, name, arguments: {} };
5270
+ this.output.content.push(block);
5271
+ const state = {
5272
+ kind: "function_call",
5273
+ itemId,
5274
+ block,
5275
+ partialArgs: "",
5276
+ finalArgs: null,
5277
+ completed: false,
5278
+ contentIndex: this.output.content.length - 1
5279
+ };
5280
+ this.items.set(outputIndex, state);
5281
+ this.toolCallStates.push(state);
5282
+ const startEvents = this.ensureStarted();
5283
+ return [
5284
+ ...startEvents,
5285
+ { type: "toolcall_start", contentIndex: state.contentIndex, partial: this.output }
5286
+ ];
5287
+ }
5288
+ this.items.set(outputIndex, { kind: "ignored", itemType: String(item.type) });
5289
+ this.diagnostics.ignoredItemTypes.add(String(item.type));
5290
+ return [];
5291
+ }
5292
+ lookupItem(raw, kinds, label) {
5293
+ const outputIndex = this.requireItemIndex(raw);
5294
+ let state = this.items.get(outputIndex);
5295
+ if (!state || !kinds.includes(state.kind)) {
5296
+ throw new ResponsesProtocolError(
5297
+ `Responses event "${raw.type ?? label}" references ${label} output_index ${outputIndex} that was never added (or is of the wrong item type).`
5298
+ );
5299
+ }
5300
+ if (state.kind !== "ignored" && raw.item_id !== void 0 && raw.item_id !== state.itemId) throw new ResponsesProtocolError("Response item identity changed.");
5301
+ return { state, outputIndex };
5302
+ }
5303
+ onContentPartAdded(raw) {
5304
+ const part = raw.part;
5305
+ const partType = isRecord2(part) ? part.type : void 0;
5306
+ const kind = partType === "reasoning_text" ? "reasoning" : "message";
5307
+ const { state } = this.lookupItem(raw, [kind], kind);
5308
+ const partIndex = raw.content_index;
5309
+ if (typeof partIndex !== "number" || !Number.isInteger(partIndex) || partIndex < 0) {
5310
+ throw new ResponsesProtocolError("response.content_part.added is missing a valid content_index.");
5311
+ }
5312
+ if (state.kind !== "message") return [];
5313
+ if (state.blocks.has(partIndex)) {
5314
+ throw new ResponsesProtocolError(`Responses stream reused content_index ${partIndex} on one message item.`);
5315
+ }
5316
+ if (partType !== "output_text" && partType !== "refusal") {
5317
+ return [];
5318
+ }
5319
+ const block = { type: "text", text: "" };
5320
+ this.output.content.push(block);
5321
+ state.blocks.set(partIndex, { block, contentIndex: this.output.content.length - 1 });
5322
+ return [{ type: "text_start", contentIndex: this.output.content.length - 1, partial: this.output }];
5323
+ }
5324
+ messageBlockFor(raw) {
5325
+ const { state } = this.lookupItem(raw, ["message"], "message");
5326
+ if (state.kind !== "message") throw new ResponsesProtocolError("internal: expected message item");
5327
+ const partIndex = raw.content_index;
5328
+ if (typeof partIndex !== "number" || !Number.isInteger(partIndex) || partIndex < 0) {
5329
+ throw new ResponsesProtocolError(`Responses event "${raw.type}" is missing a valid content_index.`);
5330
+ }
5331
+ const entry = state.blocks.get(partIndex);
5332
+ if (!entry) {
5333
+ throw new ResponsesProtocolError(
5334
+ `Responses event "${raw.type}" references content_index ${partIndex} that was never added.`
5335
+ );
5336
+ }
5337
+ return entry;
5338
+ }
5339
+ appendTextDelta(raw, kind) {
5340
+ const delta = raw.delta;
5341
+ if (typeof delta !== "string" || delta.length === 0) return [];
5342
+ const entry = this.messageBlockFor(raw);
5343
+ entry.block.text += delta;
5344
+ return [{ type: "text_delta", contentIndex: entry.contentIndex, delta, partial: this.output }];
5345
+ }
5346
+ validateTextDone(raw) {
5347
+ this.messageBlockFor(raw);
5348
+ }
5349
+ appendReasoningDelta(raw) {
5350
+ const delta = raw.delta;
5351
+ if (typeof delta !== "string" || delta.length === 0) return [];
5352
+ const { state } = this.lookupItem(raw, ["reasoning"], "reasoning");
5353
+ if (state.kind !== "reasoning") return [];
5354
+ let text = delta;
5355
+ const summaryIndex = raw.summary_index;
5356
+ if (typeof summaryIndex === "number" && Number.isInteger(summaryIndex)) {
5357
+ if (state.lastSummaryIndex !== null && summaryIndex !== state.lastSummaryIndex) {
5358
+ text = `
5359
+
5360
+ ${delta}`;
5361
+ }
5362
+ state.lastSummaryIndex = summaryIndex;
5363
+ }
5364
+ state.block.thinking += text;
5365
+ return [{ type: "thinking_delta", contentIndex: this.output.content.indexOf(state.block), delta: text, partial: this.output }];
5366
+ }
5367
+ appendFunctionCallArgsDelta(raw) {
5368
+ const delta = raw.delta ?? raw.arguments;
5369
+ if (typeof delta !== "string" || delta.length === 0) return [];
5370
+ const { state } = this.lookupItem(raw, ["function_call"], "function_call");
5371
+ if (state.kind !== "function_call") return [];
5372
+ state.partialArgs += delta;
5373
+ state.block.arguments = parseStreamingJson(state.partialArgs);
5374
+ return [{ type: "toolcall_delta", contentIndex: state.contentIndex, delta, partial: this.output }];
5375
+ }
5376
+ onFunctionCallArgsDone(raw) {
5377
+ const { state } = this.lookupItem(raw, ["function_call"], "function_call");
5378
+ if (state.kind !== "function_call") return;
5379
+ if (typeof raw.arguments === "string") {
5380
+ state.finalArgs = raw.arguments;
5381
+ }
5382
+ }
5383
+ onOutputItemDone(raw) {
5384
+ const outputIndex = this.requireItemIndex(raw);
5385
+ const item = raw.item;
5386
+ if (!isRecord2(item)) {
5387
+ throw new ResponsesProtocolError(`response.output_item.done at index ${outputIndex} is missing the item.`);
5388
+ }
5389
+ const state = this.items.get(outputIndex);
5390
+ if (!state) {
5391
+ throw new ResponsesProtocolError(`response.output_item.done references output_index ${outputIndex} that was never added.`);
5392
+ }
5393
+ if (state.kind !== "ignored" && (item.id !== state.itemId || item.type !== state.kind)) throw new ResponsesProtocolError("Response done item identity changed.");
5394
+ switch (state.kind) {
5395
+ case "message": {
5396
+ const events = [];
5397
+ for (const { block, contentIndex } of state.blocks.values()) {
5398
+ events.push({ type: "text_end", contentIndex, content: block.text, partial: this.output });
5399
+ }
5400
+ return events;
5401
+ }
5402
+ case "reasoning": {
5403
+ const events = [];
5404
+ const encrypted = typeof item.encrypted_content === "string" ? item.encrypted_content : null;
5405
+ const itemId = typeof item.id === "string" && item.id.length > 0 ? item.id : state.itemId;
5406
+ if (itemId) {
5407
+ state.block.thinkingSignature = JSON.stringify({ v: 1, id: itemId, encrypted_content: encrypted });
5408
+ }
5409
+ events.push({
5410
+ type: "thinking_end",
5411
+ contentIndex: this.output.content.indexOf(state.block),
5412
+ content: state.block.thinking,
5413
+ partial: this.output
5414
+ });
5415
+ return events;
5416
+ }
5417
+ case "function_call": {
5418
+ const finalText = typeof item.arguments === "string" && item.arguments.length > 0 ? item.arguments : state.finalArgs ?? state.partialArgs;
5419
+ if (typeof item.call_id === "string" && item.call_id.length > 0 && item.call_id !== state.block.id) {
5420
+ throw new ResponsesProtocolError(`function_call item changed call_id from "${state.block.id}" to "${item.call_id}".`);
5421
+ }
5422
+ if (typeof item.name === "string" && item.name.length > 0 && item.name !== state.block.name) {
5423
+ throw new ResponsesProtocolError(`function_call item changed name from "${state.block.name}" to "${item.name}".`);
5424
+ }
5425
+ state.completed = true;
5426
+ state.finalArgs = finalText;
5427
+ if (this.canParseArgs(state)) {
5428
+ return this.finalizeFunctionCall(state, finalText);
5429
+ }
5430
+ return [];
5431
+ }
5432
+ case "ignored":
5433
+ return [];
5434
+ }
5435
+ }
5436
+ finalizeFunctionCall(state, argsText) {
5437
+ const text = argsText.trim();
5438
+ let parsed;
5439
+ if (text.length === 0) {
5440
+ parsed = {};
5441
+ } else {
5442
+ try {
5443
+ const value = JSON.parse(text);
5444
+ if (!isRecord2(value)) {
5445
+ throw new ResponsesProtocolError(`function_call "${state.block.name || "unknown"}" arguments are not a JSON object.`);
5446
+ }
5447
+ parsed = value;
5448
+ } catch (error) {
5449
+ if (error instanceof ResponsesProtocolError) throw error;
5450
+ const message = error instanceof Error ? error.message : String(error);
5451
+ throw new ResponsesProtocolError(
5452
+ `function_call "${state.block.name || "unknown"}" returned incomplete or invalid JSON arguments: ${message}`
5453
+ );
5454
+ }
5455
+ }
5456
+ state.block.arguments = parsed;
5457
+ return [{ type: "toolcall_end", contentIndex: state.contentIndex, toolCall: state.block, partial: this.output }];
5458
+ }
5459
+ // ─── terminals ──────────────────────────────────────────────────────────
5460
+ requireTerminalResponse(raw) {
5461
+ const response = raw.response;
5462
+ const expected = raw.type.slice("response.".length);
5463
+ if (!isRecord2(response) || typeof response.id !== "string" || !response.id || response.status !== expected) {
5464
+ throw new ResponsesProtocolError(`Malformed ${raw.type}: requires response id and status ${expected}.`);
5465
+ }
5466
+ return response;
5467
+ }
5468
+ onTerminal(raw, type, reason = "stop", errorText) {
5469
+ this.diagnostics.terminalType = type;
5470
+ const response = type === "error" ? void 0 : this.requireTerminalResponse(raw);
5471
+ this.terminal = { reason, response, errorText };
5472
+ return this.closeResponse(type);
5473
+ }
5474
+ onIncomplete(raw) {
5475
+ this.diagnostics.terminalType = "response.incomplete";
5476
+ const response = this.requireTerminalResponse(raw);
5477
+ const reason = response?.incomplete_details?.reason;
5478
+ if (reason === "content_filter" || reason === "steered" || reason === void 0) {
5479
+ this.terminal = {
5480
+ reason: "error",
5481
+ response,
5482
+ errorText: reason === "steered" ? "Response ended incomplete with reason 'steered' but no steering was sent." : `Response ended incomplete${reason ? ` (${reason})` : " without a reason"}.`
5483
+ };
5484
+ return this.closeResponse("response.incomplete");
5485
+ }
5486
+ this.terminal = { reason: "length", response };
5487
+ return this.closeResponse("response.incomplete");
5488
+ }
5489
+ failedText(raw) {
5490
+ const response = isRecord2(raw.response) ? raw.response : void 0;
5491
+ const error = isRecord2(response?.error) ? response?.error : void 0;
5492
+ const message = typeof error?.message === "string" && error.message.length > 0 ? error.message : "Response failed";
5493
+ const code = typeof error?.code === "string" && error.code.length > 0 ? ` (code=${error.code})` : "";
5494
+ return `${message}${code}`;
5495
+ }
5496
+ /** Apply terminal semantics and produce the final event. */
5497
+ closeResponse(terminalType) {
5498
+ const terminal = this.terminal;
5499
+ const response = terminal.response;
5500
+ if (response && isRecord2(response.usage)) {
5501
+ this.output.usage = normalizeResponsesUsage(this.model, response.usage);
5502
+ this.output.usageReported = [response.usage.input_tokens, response.usage.output_tokens].every((value) => typeof value === "number" && Number.isFinite(value) && value >= 0);
5503
+ }
5504
+ if (terminal.reason === "error") {
5505
+ this.output.stopReason = "error";
5506
+ this.output.errorMessage = terminal.errorText ?? "Response failed";
5507
+ return [{ type: "error", reason: "error", error: this.output }];
5508
+ }
5509
+ let stopReason = terminal.reason === "length" ? "length" : "stop";
5510
+ if (this.toolCallStates.length > 0) {
5511
+ stopReason = "toolUse";
5512
+ }
5513
+ if (terminal.reason === "length") {
5514
+ const truncated = this.toolCallStates.filter((state) => !state.completed || !this.canParseArgs(state));
5515
+ if (truncated.length > 0) {
5516
+ const dropped = new Set(truncated.map((state) => state.block));
5517
+ this.output.content = this.output.content.filter(
5518
+ (block) => block.type !== "toolCall" || !dropped.has(block)
5519
+ );
5520
+ this.toolCallStates = this.toolCallStates.filter((state) => !dropped.has(state.block));
5521
+ const names = truncated.map((state) => `"${state.block.name || "unnamed"}"`).sort().join(", ");
5522
+ this.output.content.push({
5523
+ type: "text",
5524
+ text: `[output truncated: max_output_tokens cut ${truncated.length === 1 ? "a tool call" : `${truncated.length} tool calls`} mid-arguments (${names}); the call${truncated.length === 1 ? " was" : "s were"} dropped. Re-issue the call or continue with fewer/smaller requests.]`
5525
+ });
5526
+ if (this.toolCallStates.length === 0) {
5527
+ stopReason = "length";
5528
+ }
5529
+ }
5530
+ } else if (terminal.reason === "stop") {
5531
+ const brokenCalls = this.toolCallStates.filter((state) => !state.completed || !this.canParseArgs(state));
5532
+ if (brokenCalls.length > 0) {
5533
+ const first = brokenCalls[0];
5534
+ this.output.stopReason = "error";
5535
+ this.output.errorMessage = `function_call "${first.block.name || "unknown"}" returned incomplete or invalid JSON arguments on a completed response.`;
5536
+ return [{ type: "error", reason: "error", error: this.output }];
5537
+ }
5538
+ }
5539
+ if (stopReason === "toolUse" && this.toolCallStates.length === 0) {
5540
+ stopReason = "stop";
5541
+ }
5542
+ this.output.stopReason = stopReason;
5543
+ void terminalType;
5544
+ return [{ type: "done", reason: stopReason, message: this.output }];
5545
+ }
5546
+ canParseArgs(state) {
5547
+ const text = (state.finalArgs ?? state.partialArgs).trim();
5548
+ if (text.length === 0) return false;
5549
+ try {
5550
+ return isRecord2(JSON.parse(text));
5551
+ } catch {
5552
+ return false;
5553
+ }
5554
+ }
5555
+ };
5556
+
5557
+ // ../../packages/ai/src/providers/responses/responses-diagnostics.ts
5558
+ function reportSubmission(options, body, details) {
5559
+ if (!options?.onTransportDiagnostic) return;
5560
+ let requestBytes = 0;
5561
+ for (const character of body) {
5562
+ const point = character.codePointAt(0);
5563
+ requestBytes += point <= 127 ? 1 : point <= 2047 ? 2 : point <= 65535 ? 3 : 4;
5564
+ }
5565
+ try {
5566
+ options.onTransportDiagnostic({ ...details, requestBytes });
5567
+ } catch {
5568
+ }
5569
+ }
5570
+
5571
+ // ../../packages/ai/src/providers/responses/responses-sse.ts
5572
+ var DEFAULT_RESPONSES_STREAM_IDLE_TIMEOUT_MS = 2 * 60 * 1e3;
5573
+ var DEFAULT_RESPONSES_FIRST_BYTE_TIMEOUT_MS = 3 * 60 * 1e3;
5574
+ function parseSSEDataLine2(line) {
5575
+ const trimmed = line.trim();
5576
+ if (!trimmed || trimmed.startsWith(":")) return null;
5577
+ if (!trimmed.startsWith("data:")) return null;
5578
+ const data = trimmed.slice(5);
5579
+ return data.startsWith(" ") ? data.slice(1) : data;
5580
+ }
5581
+ function streamResponsesSSE(model, context, options) {
5582
+ const stream = new AssistantMessageEventStream();
5583
+ void (async () => {
5584
+ const reducer = new ResponsesEventReducer(model);
5585
+ try {
5586
+ const apiKey = options?.apiKey || getEnvApiKey(model.provider, model.apiKeyEnv) || "";
5587
+ if (!apiKey) {
5588
+ throw new Error(`No API key for provider: ${model.provider}`);
5589
+ }
5590
+ const payload = buildResponsesSSEPayload(model, context, options);
5591
+ options?.onPayload?.(payload);
5592
+ const headers = {
5593
+ "Content-Type": "application/json",
5594
+ Accept: "text/event-stream",
5595
+ Authorization: `Bearer ${apiKey}`,
5596
+ ...model.headers || {},
5597
+ ...options?.headers || {}
5598
+ };
5599
+ const body = JSON.stringify(payload);
5600
+ reportSubmission(options, body, { transport: "sse", reusedConnection: false, continuation: false, attempt: 1 });
5601
+ const response = await httpRequest(`${model.baseUrl}/responses`, {
5602
+ method: "POST",
5603
+ headers,
5604
+ body,
5605
+ signal: options?.signal,
5606
+ ...options?.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {
5607
+ firstByteTimeoutMs: DEFAULT_RESPONSES_FIRST_BYTE_TIMEOUT_MS,
5608
+ streamIdleTimeoutMs: DEFAULT_RESPONSES_STREAM_IDLE_TIMEOUT_MS
5609
+ },
5610
+ label: `${model.provider}/${model.id}`
5611
+ });
5612
+ if (!response.ok) {
5613
+ const errorBody = await response.text().catch(() => "");
5614
+ throw new Error(`API error ${response.status}: ${errorBody}`);
5615
+ }
5616
+ if (!response.readSSELines) {
5617
+ throw new Error("SSE streaming not supported on this platform");
5618
+ }
5619
+ for await (const line of response.readSSELines(options?.signal)) {
5620
+ const data = parseSSEDataLine2(line);
5621
+ if (data === null) continue;
5622
+ if (data === "[DONE]") {
5623
+ continue;
5624
+ }
5625
+ let event;
5626
+ try {
5627
+ event = JSON.parse(data);
5628
+ } catch (error) {
5629
+ const message = error instanceof Error ? error.message : String(error);
5630
+ throw new ResponsesProtocolError(`Responses SSE stream returned malformed JSON: ${message}`);
5631
+ }
5632
+ if (!isResponsesEventLike(event)) {
5633
+ throw new ResponsesProtocolError("Responses SSE payload is not an event object with a string type.");
5634
+ }
5635
+ for (const assistantEvent of reducer.feed(event)) {
5636
+ stream.push(assistantEvent);
5637
+ }
5638
+ if (reducer.isTerminal) break;
5639
+ }
5640
+ if (reducer.isTerminal) {
5641
+ stream.end();
5642
+ return;
5643
+ }
5644
+ if (options?.signal?.aborted) {
5645
+ throw new Error("Request was aborted");
5646
+ }
5647
+ if (!reducer.isTerminal) {
5648
+ throw reducer.finishWithoutTerminal();
5649
+ }
5650
+ if (reducer.message.stopReason === "error" || reducer.message.stopReason === "aborted") {
5651
+ throw new Error(reducer.message.errorMessage ?? "An unknown error occurred");
5652
+ }
5653
+ stream.end();
5654
+ } catch (error) {
5655
+ if (reducer.isTerminal) {
5656
+ stream.end();
5657
+ return;
5658
+ }
5659
+ const message = reducer.message;
5660
+ message.stopReason = options?.signal?.aborted ? "aborted" : "error";
5661
+ message.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
5662
+ stream.push({ type: "error", reason: message.stopReason, error: message });
5663
+ stream.end();
5664
+ }
5665
+ })();
5666
+ return stream;
5667
+ }
5668
+
5669
+ // ../../packages/ai/src/providers/responses/responses-ws.ts
5670
+ var owners = /* @__PURE__ */ new WeakMap();
5671
+ var MAX_ANCHOR_BYTES = 1024 * 1024;
5672
+ function disposeModelTransports(owner) {
5673
+ const state = owners.get(owner);
5674
+ if (!state) return;
5675
+ disposeState(owner, state);
5676
+ }
5677
+ function disposeState(owner, state) {
5678
+ if (owners.get(owner) === state) owners.delete(owner);
5679
+ state.anchor = void 0;
5680
+ state.abort.abort();
5681
+ void state.connection?.close().catch(() => {
5682
+ });
5683
+ }
5684
+ function stateFor(owner) {
5685
+ let state = owners.get(owner);
5686
+ if (!state) {
5687
+ state = { busy: false, abort: new AbortController() };
5688
+ owners.set(owner, state);
5689
+ }
5690
+ return state;
5691
+ }
5692
+ function websocketUrl(base) {
5693
+ const url = new URL(`${base.replace(/\/$/, "")}/responses`);
5694
+ if (url.protocol !== "https:" && url.protocol !== "http:") throw new ResponsesProtocolError("Responses requires an HTTP(S) API root.");
5695
+ return `${url.protocol === "https:" ? "wss:" : "ws:"}${url.toString().slice(url.protocol.length)}`;
5696
+ }
5697
+ function streamResponsesWS(model, context, options) {
5698
+ const stream = new AssistantMessageEventStream();
5699
+ const owner = options?.transportOwner ?? {};
5700
+ const state = stateFor(owner);
5701
+ const reducer = new ResponsesEventReducer(model);
5702
+ if (state.busy) {
5703
+ reducer.message.stopReason = "error";
5704
+ reducer.message.errorMessage = "Responses owner already has an in-flight request.";
5705
+ stream.push({ type: "error", reason: "error", error: reducer.message });
5706
+ stream.end();
5707
+ return stream;
5708
+ }
5709
+ state.busy = true;
5710
+ void (async () => {
5711
+ let sent = false;
5712
+ let finished = false;
5713
+ let terminalEvents = [];
5714
+ let fallback = false;
5715
+ const publish = (event) => {
5716
+ if (event.type === "done" || event.type === "error") terminalEvents.push(event);
5717
+ else stream.push(event);
5718
+ };
5719
+ const abort = () => disposeState(owner, state);
5720
+ options?.signal?.addEventListener("abort", abort, { once: true });
5721
+ try {
5722
+ if (options?.signal?.aborted) {
5723
+ abort();
5724
+ throw new Error("Request aborted");
5725
+ }
5726
+ const key = options?.apiKey || getEnvApiKey(model.provider, model.apiKeyEnv);
5727
+ if (!key) throw new Error(`No API key for provider: ${model.provider}`);
5728
+ const payload = buildResponsesCreateEvent(model, context, options);
5729
+ const headers = { Authorization: `Bearer ${key}`, ...model.headers, ...options?.headers };
5730
+ const { input, ...settings } = payload;
5731
+ const identity = JSON.stringify([model.provider, model.api, model.id, model.baseUrl, headers, settings]);
5732
+ if (state.identity !== identity || state.connection?.state() !== "open") {
5733
+ await state.connection?.close();
5734
+ state.connection = void 0;
5735
+ state.anchor = void 0;
5736
+ state.identity = identity;
5737
+ }
5738
+ if (state.abort.signal.aborted) throw new Error("Request aborted");
5739
+ const client = getWebSocketClient();
5740
+ if (!client) {
5741
+ if (options?.transport === "auto") {
5742
+ fallback = true;
5743
+ for await (const event of streamResponsesSSE(model, context, { ...options, signal: state.abort.signal })) publish(event);
5744
+ finished = true;
5745
+ return;
5746
+ }
5747
+ throw new Error("WebSocket transport is not available on this host.");
5748
+ }
5749
+ const reusedConnection = !!state.connection;
5750
+ if (!state.connection) {
5751
+ try {
5752
+ state.connection = await client.connect(websocketUrl(model.baseUrl), {
5753
+ headers,
5754
+ signal: state.abort.signal,
5755
+ connectTimeoutMs: options?.timeoutMs ?? 3e4,
5756
+ idleTimeoutMs: options?.timeoutMs ?? 12e4
5757
+ });
5758
+ } catch (error) {
5759
+ if (options?.transport === "auto" && error instanceof WebSocketTransportError && error.kind === "handshake" && [404, 405, 426, 501].includes(error.status ?? 0) && !options.signal?.aborted && !state.abort.signal.aborted) {
5760
+ fallback = true;
5761
+ for await (const event of streamResponsesSSE(model, context, { ...options, signal: state.abort.signal })) publish(event);
5762
+ finished = true;
5763
+ return;
5764
+ }
5765
+ throw error;
5766
+ }
5767
+ }
5768
+ const fullInput = input;
5769
+ const anchor = state.anchor;
5770
+ if (!options?.onPayload && model.compat?.responsesContinuation && anchor && fullInput.length > anchor.count && JSON.stringify(fullInput.slice(0, anchor.count)) === anchor.prefix) {
5771
+ payload.previous_response_id = anchor.id;
5772
+ payload.input = fullInput.slice(anchor.count);
5773
+ }
5774
+ state.anchor = void 0;
5775
+ for (let attempt = 0; attempt < 2; attempt++) {
5776
+ let rebuild = false;
5777
+ options?.onPayload?.(payload);
5778
+ if (state.abort.signal.aborted) throw new Error("Request aborted");
5779
+ sent = true;
5780
+ const body = JSON.stringify(payload);
5781
+ reportSubmission(options, body, { transport: "websocket", reusedConnection: reusedConnection || attempt > 0, continuation: !!payload.previous_response_id, attempt: attempt + 1 });
5782
+ await state.connection.send(body, { signal: state.abort.signal });
5783
+ let started = false;
5784
+ let responseId;
5785
+ for await (const message of state.connection.receive(state.abort.signal)) {
5786
+ if (state.abort.signal.aborted) throw new Error("Request aborted");
5787
+ if (message.isBinary) throw new ResponsesProtocolError("Responses requires JSON text messages.");
5788
+ const event = JSON.parse(message.data);
5789
+ if (!isRecord2(event)) throw new ResponsesProtocolError("Invalid Responses WebSocket event.");
5790
+ if (!started && attempt === 0 && payload.previous_response_id && event.type === "error" && event.status === 400 && isRecord2(event.error) && event.error.code === "previous_response_not_found" && event.error.param === "previous_response_id") {
5791
+ delete payload.previous_response_id;
5792
+ payload.input = fullInput;
5793
+ rebuild = true;
5794
+ break;
5795
+ }
5796
+ if (!started && typeof event.type === "string" && event.type !== "error" && !event.type.startsWith("response.")) continue;
5797
+ if (!started && event.type !== "error") {
5798
+ if (event.type !== "response.created" || !isRecord2(event.response) || typeof event.response.id !== "string" || event.response.id === state.lastResponseId) {
5799
+ throw new ResponsesProtocolError("Expected a new response.created before output.");
5800
+ }
5801
+ started = true;
5802
+ responseId = event.response.id;
5803
+ }
5804
+ if (responseId && isRecord2(event.response) && event.response.id !== responseId) throw new ResponsesProtocolError("Response identity changed within a request.");
5805
+ const events = reducer.feed(event);
5806
+ if (reducer.isTerminal) {
5807
+ if (reducer.message.stopReason === "error") reducer.message.retryable = false;
5808
+ const response = reducer.terminalResponse;
5809
+ state.lastResponseId = response?.id;
5810
+ if (!options?.onPayload && response?.status === "completed" && reducer.message.stopReason !== "error") {
5811
+ const prefixItems = [...fullInput, ...buildResponsesOutput(reducer.message)];
5812
+ const prefix = JSON.stringify(prefixItems);
5813
+ if (prefix.length * 2 <= MAX_ANCHOR_BYTES) state.anchor = { id: response.id, prefix, count: prefixItems.length };
5814
+ }
5815
+ finished = true;
5816
+ for (const e of events) publish(e);
5817
+ break;
5818
+ }
5819
+ for (const e of events) publish(e);
5820
+ }
5821
+ if (rebuild) continue;
5822
+ if (!reducer.isTerminal) throw reducer.finishWithoutTerminal();
5823
+ break;
5824
+ }
5825
+ } catch (error) {
5826
+ if (!finished) {
5827
+ const message = reducer.message;
5828
+ message.stopReason = options?.signal?.aborted || state.abort.signal.aborted ? "aborted" : "error";
5829
+ message.errorMessage = error instanceof Error ? error.message : String(error);
5830
+ if (sent) message.retryable = false;
5831
+ stream.push({ type: "error", reason: message.stopReason, error: message });
5832
+ }
5833
+ } finally {
5834
+ options?.signal?.removeEventListener("abort", abort);
5835
+ state.busy = false;
5836
+ if (fallback || !finished || !options?.transportOwner || reducer.message.stopReason === "error") disposeState(owner, state);
5837
+ for (const event of terminalEvents) stream.push(event);
5838
+ stream.end();
5839
+ }
5840
+ })();
5841
+ return stream;
5842
+ }
5843
+
5844
+ // ../../packages/ai/src/providers/openai-responses.ts
5845
+ var streamResponses = (model, context, options) => {
5846
+ const transport = options?.transport ?? model.transport ?? "sse";
5847
+ if (transport === "websocket" || transport === "auto") return streamResponsesWS(model, context, { ...options, transport });
5848
+ if (transport !== "sse") throw new Error(`Unsupported transport: ${transport}`);
5849
+ return streamResponsesSSE(model, context, options);
5850
+ };
5851
+ var streamSimpleResponses = (model, context, options) => {
5852
+ const apiKey = options?.apiKey || getEnvApiKey(model.provider, model.apiKeyEnv);
5853
+ if (!apiKey) {
5854
+ throw new Error(`No API key for provider: ${model.provider}`);
5855
+ }
5856
+ const base = buildBaseOptions(model, options, apiKey);
5857
+ const needsThinkingAllowance = Boolean(model.reasoning) && options?.reasoning !== void 0;
5858
+ let maxTokens = base.maxTokens;
5859
+ if (needsThinkingAllowance) {
5860
+ const adjusted = adjustMaxTokensForThinking(
5861
+ base.maxTokens || 0,
5862
+ model.maxTokens,
5863
+ options.reasoning,
5864
+ options?.thinkingBudgets
5865
+ );
5866
+ maxTokens = adjusted.maxTokens;
5867
+ }
5868
+ if (maxTokens === void 0) {
5869
+ maxTokens = DEFAULT_MAX_TOKENS;
5870
+ }
5871
+ const reasoningEffort = model.reasoning ? options?.reasoning : void 0;
5872
+ return streamResponses(model, context, {
5873
+ ...base,
5874
+ maxTokens,
5875
+ // Responses accepts the full effort vocabulary verified in the SDK
5876
+ // ("none" excluded from Pie's ThinkingLevel); pass through unchanged.
5877
+ reasoningEffort
5878
+ });
5879
+ };
5880
+
4622
5881
  // ../../packages/ai/src/stream.ts
4623
5882
  function resolveApiProvider(api) {
4624
5883
  const provider = getApiProvider(api);
@@ -8079,6 +9338,11 @@ registerApiProvider({
8079
9338
  stream: streamAnthropic,
8080
9339
  streamSimple: streamSimpleAnthropic
8081
9340
  });
9341
+ registerApiProvider({
9342
+ api: "openai-responses",
9343
+ stream: streamResponses,
9344
+ streamSimple: streamSimpleResponses
9345
+ });
8082
9346
 
8083
9347
  export {
8084
9348
  hashText,
@@ -8097,6 +9361,7 @@ export {
8097
9361
  getModelCacheCapability,
8098
9362
  EMPTY_ASSISTANT_CONTENT_ERROR,
8099
9363
  OPENAI_COMPAT_PROTOCOL_ERROR_CODE,
9364
+ disposeModelTransports,
8100
9365
  streamSimple,
8101
9366
  completeSimple,
8102
9367
  MODEL_CLASS_FALLBACK_ORDER,