@cydm/pie 2.7.4 → 2.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -512,6 +512,338 @@ function hashText(text) {
512
512
  return hasher.digest();
513
513
  }
514
514
 
515
+ // ../../node_modules/@noble/hashes/esm/utils.js
516
+ function isBytes(a) {
517
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
518
+ }
519
+ function abytes(b, ...lengths) {
520
+ if (!isBytes(b))
521
+ throw new Error("Uint8Array expected");
522
+ if (lengths.length > 0 && !lengths.includes(b.length))
523
+ throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
524
+ }
525
+ function aexists(instance, checkFinished = true) {
526
+ if (instance.destroyed)
527
+ throw new Error("Hash instance has been destroyed");
528
+ if (checkFinished && instance.finished)
529
+ throw new Error("Hash#digest() has already been called");
530
+ }
531
+ function aoutput(out, instance) {
532
+ abytes(out);
533
+ const min = instance.outputLen;
534
+ if (out.length < min) {
535
+ throw new Error("digestInto() expects output buffer of length at least " + min);
536
+ }
537
+ }
538
+ function clean(...arrays) {
539
+ for (let i = 0; i < arrays.length; i++) {
540
+ arrays[i].fill(0);
541
+ }
542
+ }
543
+ function createView(arr) {
544
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
545
+ }
546
+ function rotr(word, shift) {
547
+ return word << 32 - shift | word >>> shift;
548
+ }
549
+ function utf8ToBytes(str) {
550
+ if (typeof str !== "string")
551
+ throw new Error("string expected");
552
+ return new Uint8Array(new TextEncoder().encode(str));
553
+ }
554
+ function toBytes(data) {
555
+ if (typeof data === "string")
556
+ data = utf8ToBytes(data);
557
+ abytes(data);
558
+ return data;
559
+ }
560
+ var Hash = class {
561
+ };
562
+ function createHasher(hashCons) {
563
+ const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
564
+ const tmp = hashCons();
565
+ hashC.outputLen = tmp.outputLen;
566
+ hashC.blockLen = tmp.blockLen;
567
+ hashC.create = () => hashCons();
568
+ return hashC;
569
+ }
570
+
571
+ // ../../node_modules/@noble/hashes/esm/_md.js
572
+ function setBigUint64(view, byteOffset, value, isLE) {
573
+ if (typeof view.setBigUint64 === "function")
574
+ return view.setBigUint64(byteOffset, value, isLE);
575
+ const _32n = BigInt(32);
576
+ const _u32_max = BigInt(4294967295);
577
+ const wh = Number(value >> _32n & _u32_max);
578
+ const wl = Number(value & _u32_max);
579
+ const h = isLE ? 4 : 0;
580
+ const l = isLE ? 0 : 4;
581
+ view.setUint32(byteOffset + h, wh, isLE);
582
+ view.setUint32(byteOffset + l, wl, isLE);
583
+ }
584
+ function Chi(a, b, c) {
585
+ return a & b ^ ~a & c;
586
+ }
587
+ function Maj(a, b, c) {
588
+ return a & b ^ a & c ^ b & c;
589
+ }
590
+ var HashMD = class extends Hash {
591
+ constructor(blockLen, outputLen, padOffset, isLE) {
592
+ super();
593
+ this.finished = false;
594
+ this.length = 0;
595
+ this.pos = 0;
596
+ this.destroyed = false;
597
+ this.blockLen = blockLen;
598
+ this.outputLen = outputLen;
599
+ this.padOffset = padOffset;
600
+ this.isLE = isLE;
601
+ this.buffer = new Uint8Array(blockLen);
602
+ this.view = createView(this.buffer);
603
+ }
604
+ update(data) {
605
+ aexists(this);
606
+ data = toBytes(data);
607
+ abytes(data);
608
+ const { view, buffer, blockLen } = this;
609
+ const len = data.length;
610
+ for (let pos = 0; pos < len; ) {
611
+ const take = Math.min(blockLen - this.pos, len - pos);
612
+ if (take === blockLen) {
613
+ const dataView = createView(data);
614
+ for (; blockLen <= len - pos; pos += blockLen)
615
+ this.process(dataView, pos);
616
+ continue;
617
+ }
618
+ buffer.set(data.subarray(pos, pos + take), this.pos);
619
+ this.pos += take;
620
+ pos += take;
621
+ if (this.pos === blockLen) {
622
+ this.process(view, 0);
623
+ this.pos = 0;
624
+ }
625
+ }
626
+ this.length += data.length;
627
+ this.roundClean();
628
+ return this;
629
+ }
630
+ digestInto(out) {
631
+ aexists(this);
632
+ aoutput(out, this);
633
+ this.finished = true;
634
+ const { buffer, view, blockLen, isLE } = this;
635
+ let { pos } = this;
636
+ buffer[pos++] = 128;
637
+ clean(this.buffer.subarray(pos));
638
+ if (this.padOffset > blockLen - pos) {
639
+ this.process(view, 0);
640
+ pos = 0;
641
+ }
642
+ for (let i = pos; i < blockLen; i++)
643
+ buffer[i] = 0;
644
+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
645
+ this.process(view, 0);
646
+ const oview = createView(out);
647
+ const len = this.outputLen;
648
+ if (len % 4)
649
+ throw new Error("_sha2: outputLen should be aligned to 32bit");
650
+ const outLen = len / 4;
651
+ const state = this.get();
652
+ if (outLen > state.length)
653
+ throw new Error("_sha2: outputLen bigger than state");
654
+ for (let i = 0; i < outLen; i++)
655
+ oview.setUint32(4 * i, state[i], isLE);
656
+ }
657
+ digest() {
658
+ const { buffer, outputLen } = this;
659
+ this.digestInto(buffer);
660
+ const res = buffer.slice(0, outputLen);
661
+ this.destroy();
662
+ return res;
663
+ }
664
+ _cloneInto(to) {
665
+ to || (to = new this.constructor());
666
+ to.set(...this.get());
667
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
668
+ to.destroyed = destroyed;
669
+ to.finished = finished;
670
+ to.length = length;
671
+ to.pos = pos;
672
+ if (length % blockLen)
673
+ to.buffer.set(buffer);
674
+ return to;
675
+ }
676
+ clone() {
677
+ return this._cloneInto();
678
+ }
679
+ };
680
+ var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
681
+ 1779033703,
682
+ 3144134277,
683
+ 1013904242,
684
+ 2773480762,
685
+ 1359893119,
686
+ 2600822924,
687
+ 528734635,
688
+ 1541459225
689
+ ]);
690
+
691
+ // ../../node_modules/@noble/hashes/esm/sha2.js
692
+ var SHA256_K = /* @__PURE__ */ Uint32Array.from([
693
+ 1116352408,
694
+ 1899447441,
695
+ 3049323471,
696
+ 3921009573,
697
+ 961987163,
698
+ 1508970993,
699
+ 2453635748,
700
+ 2870763221,
701
+ 3624381080,
702
+ 310598401,
703
+ 607225278,
704
+ 1426881987,
705
+ 1925078388,
706
+ 2162078206,
707
+ 2614888103,
708
+ 3248222580,
709
+ 3835390401,
710
+ 4022224774,
711
+ 264347078,
712
+ 604807628,
713
+ 770255983,
714
+ 1249150122,
715
+ 1555081692,
716
+ 1996064986,
717
+ 2554220882,
718
+ 2821834349,
719
+ 2952996808,
720
+ 3210313671,
721
+ 3336571891,
722
+ 3584528711,
723
+ 113926993,
724
+ 338241895,
725
+ 666307205,
726
+ 773529912,
727
+ 1294757372,
728
+ 1396182291,
729
+ 1695183700,
730
+ 1986661051,
731
+ 2177026350,
732
+ 2456956037,
733
+ 2730485921,
734
+ 2820302411,
735
+ 3259730800,
736
+ 3345764771,
737
+ 3516065817,
738
+ 3600352804,
739
+ 4094571909,
740
+ 275423344,
741
+ 430227734,
742
+ 506948616,
743
+ 659060556,
744
+ 883997877,
745
+ 958139571,
746
+ 1322822218,
747
+ 1537002063,
748
+ 1747873779,
749
+ 1955562222,
750
+ 2024104815,
751
+ 2227730452,
752
+ 2361852424,
753
+ 2428436474,
754
+ 2756734187,
755
+ 3204031479,
756
+ 3329325298
757
+ ]);
758
+ var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
759
+ var SHA256 = class extends HashMD {
760
+ constructor(outputLen = 32) {
761
+ super(64, outputLen, 8, false);
762
+ this.A = SHA256_IV[0] | 0;
763
+ this.B = SHA256_IV[1] | 0;
764
+ this.C = SHA256_IV[2] | 0;
765
+ this.D = SHA256_IV[3] | 0;
766
+ this.E = SHA256_IV[4] | 0;
767
+ this.F = SHA256_IV[5] | 0;
768
+ this.G = SHA256_IV[6] | 0;
769
+ this.H = SHA256_IV[7] | 0;
770
+ }
771
+ get() {
772
+ const { A, B, C, D, E, F, G, H } = this;
773
+ return [A, B, C, D, E, F, G, H];
774
+ }
775
+ // prettier-ignore
776
+ set(A, B, C, D, E, F, G, H) {
777
+ this.A = A | 0;
778
+ this.B = B | 0;
779
+ this.C = C | 0;
780
+ this.D = D | 0;
781
+ this.E = E | 0;
782
+ this.F = F | 0;
783
+ this.G = G | 0;
784
+ this.H = H | 0;
785
+ }
786
+ process(view, offset) {
787
+ for (let i = 0; i < 16; i++, offset += 4)
788
+ SHA256_W[i] = view.getUint32(offset, false);
789
+ for (let i = 16; i < 64; i++) {
790
+ const W15 = SHA256_W[i - 15];
791
+ const W2 = SHA256_W[i - 2];
792
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
793
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
794
+ SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
795
+ }
796
+ let { A, B, C, D, E, F, G, H } = this;
797
+ for (let i = 0; i < 64; i++) {
798
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
799
+ const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
800
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
801
+ const T2 = sigma0 + Maj(A, B, C) | 0;
802
+ H = G;
803
+ G = F;
804
+ F = E;
805
+ E = D + T1 | 0;
806
+ D = C;
807
+ C = B;
808
+ B = A;
809
+ A = T1 + T2 | 0;
810
+ }
811
+ A = A + this.A | 0;
812
+ B = B + this.B | 0;
813
+ C = C + this.C | 0;
814
+ D = D + this.D | 0;
815
+ E = E + this.E | 0;
816
+ F = F + this.F | 0;
817
+ G = G + this.G | 0;
818
+ H = H + this.H | 0;
819
+ this.set(A, B, C, D, E, F, G, H);
820
+ }
821
+ roundClean() {
822
+ clean(SHA256_W);
823
+ }
824
+ destroy() {
825
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
826
+ clean(this.buffer);
827
+ }
828
+ };
829
+ var sha256 = /* @__PURE__ */ createHasher(() => new SHA256());
830
+
831
+ // ../../packages/platform/src/sha256.ts
832
+ function createSha256Hasher() {
833
+ const hash = sha256.create();
834
+ return {
835
+ update(bytes) {
836
+ hash.update(bytes);
837
+ },
838
+ digestHex() {
839
+ const bytes = hash.digest();
840
+ let hex = "";
841
+ for (const byte of bytes) hex += byte.toString(16).padStart(2, "0");
842
+ return hex;
843
+ }
844
+ };
845
+ }
846
+
515
847
  // ../../packages/platform/src/detector.ts
516
848
  function isPuerTS() {
517
849
  try {
@@ -3126,7 +3458,7 @@ var NodeConnection = class {
3126
3458
  this.resolveClosed = resolve;
3127
3459
  });
3128
3460
  socket.on("error", (error) => this.fail(failure(
3129
- error.code === "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" ? "overflow" : this.opened ? "protocol" : "handshake",
3461
+ error.code === "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" ? "overflow" : !this.opened ? "handshake" : error.code?.startsWith("WS_ERR_") ? "protocol" : "closed",
3130
3462
  "WebSocket transport failed"
3131
3463
  )));
3132
3464
  socket.on("open", () => {
@@ -5113,6 +5445,68 @@ function buildResponsesCreateEvent(model, context, options) {
5113
5445
  return { type: "response.create", ...params };
5114
5446
  }
5115
5447
 
5448
+ // ../../packages/ai/src/providers/responses/responses-remote-failure.ts
5449
+ var MAX_TEXT = 4096;
5450
+ var transientCodes = /* @__PURE__ */ new Set(["server_error", "rate_limit_exceeded", "slow_down", "rate_limit_error", "server_is_overloaded", "service_unavailable_error"]);
5451
+ function responsesRemoteFailure(value, status, headers) {
5452
+ const root = isRecord2(value) ? value : {};
5453
+ const response = isRecord2(root.response) ? root.response : {};
5454
+ const error = isRecord2(root.error) ? root.error : isRecord2(response.error) ? response.error : root;
5455
+ const code = typeof error.code === "string" ? error.code.slice(0, 128).toLowerCase() : "";
5456
+ const type = typeof error.type === "string" ? error.type.slice(0, 128).toLowerCase() : "";
5457
+ const message = (typeof value === "string" ? value : typeof error.message === "string" ? error.message : "").slice(0, MAX_TEXT).toLowerCase();
5458
+ const httpStatus = status ?? root.status ?? root.statusCode;
5459
+ const fields = `${code} ${type}`;
5460
+ let category = "other";
5461
+ if (/context_length_exceeded|context_window_exceeded|context_overflow/.test(fields) || /context (?:length|window).{0,60}(?:exceed|too (?:long|large))|maximum context length|exceeds.{0,30}context window/.test(message)) category = "context_overflow";
5462
+ else if (/billing|insufficient_quota|insufficient_balance|credit|usage_limit|spend_limit/.test(fields) || /billing|(?:account|monthly) quota|exceeded your current quota|insufficient (?:credit|balance)|credit balance|spend(?:ing)? limit/.test(message)) category = "other";
5463
+ else if (typeof httpStatus === "number" && httpStatus >= 400 && httpStatus < 500 && httpStatus !== 429) category = "other";
5464
+ else if (httpStatus === 429 || typeof httpStatus === "number" && httpStatus >= 500 && httpStatus <= 599 || transientCodes.has(code) || transientCodes.has(type) || /server (?:is )?overloaded|temporarily unavailable|internal server error|rate limit (?:exceeded|reached)/.test(message)) category = "transient";
5465
+ const retryAfterMs = parseRetryAfter(headers ?? root.headers);
5466
+ return { category, ...retryAfterMs !== void 0 ? { retryAfterMs } : {} };
5467
+ }
5468
+ function parseRetryAfter(headers) {
5469
+ if (!headers || typeof headers !== "object") return void 0;
5470
+ let raw;
5471
+ if ("get" in headers && typeof headers.get === "function") raw = headers.get("retry-after");
5472
+ else for (const [key, value] of Object.entries(headers)) if (key.toLowerCase() === "retry-after") raw = value;
5473
+ if (typeof raw !== "string" || raw.length > 128) return void 0;
5474
+ const text = raw.trim();
5475
+ if (/^\d+(?:\.\d+)?$/.test(text)) {
5476
+ const delay = Number(text) * 1e3;
5477
+ return Number.isFinite(delay) ? delay : Number.MAX_VALUE;
5478
+ }
5479
+ if (!/^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/.test(text)) return void 0;
5480
+ const date = Date.parse(text);
5481
+ if (!Number.isFinite(date) || new Date(date).toUTCString() !== text) return void 0;
5482
+ return Math.max(0, date - Date.now());
5483
+ }
5484
+ async function readResponsesErrorBody(read, signal) {
5485
+ let timer;
5486
+ let onAbort;
5487
+ try {
5488
+ return await Promise.race([
5489
+ Promise.resolve().then(read).then((text) => text.slice(0, MAX_TEXT)).catch(() => ""),
5490
+ new Promise((resolve) => {
5491
+ onAbort = () => resolve("");
5492
+ if (signal.aborted) resolve("");
5493
+ else signal.addEventListener("abort", onAbort, { once: true });
5494
+ timer = setTimeout(() => resolve(""), 250);
5495
+ })
5496
+ ]);
5497
+ } finally {
5498
+ if (timer !== void 0) clearTimeout(timer);
5499
+ if (onAbort) signal.removeEventListener("abort", onAbort);
5500
+ }
5501
+ }
5502
+ function parseResponsesErrorBody(text) {
5503
+ try {
5504
+ return JSON.parse(text);
5505
+ } catch {
5506
+ return text;
5507
+ }
5508
+ }
5509
+
5116
5510
  // ../../packages/ai/src/providers/responses/responses-usage.ts
5117
5511
  function tokenCount(value) {
5118
5512
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return void 0;
@@ -5183,6 +5577,19 @@ var ResponsesEventReducer = class {
5183
5577
  }
5184
5578
  /** Feed one raw wire event; returns the AssistantMessageEvents to emit. */
5185
5579
  feed(raw) {
5580
+ if (this.terminal) return [];
5581
+ try {
5582
+ const events = this.feedInbound(raw);
5583
+ if (this.isTerminal && this.output.stopReason === "error") {
5584
+ this.output.remoteFailure = responsesRemoteFailure(raw);
5585
+ }
5586
+ return events;
5587
+ } catch (error) {
5588
+ this.terminal = null;
5589
+ throw error;
5590
+ }
5591
+ }
5592
+ feedInbound(raw) {
5186
5593
  const events = [];
5187
5594
  if (!isResponsesEventLike(raw)) {
5188
5595
  throw new ResponsesProtocolError("Responses stream returned an event without a string type.");
@@ -5626,12 +6033,21 @@ var DEFAULT_RESPONSES_STREAM_IDLE_TIMEOUT_MS = 2 * 60 * 1e3;
5626
6033
  var DEFAULT_RESPONSES_FIRST_BYTE_TIMEOUT_MS = 3 * 60 * 1e3;
5627
6034
  var REASONING_STREAM_IDLE_TIMEOUT_MS = 5 * 60 * 1e3;
5628
6035
  var REASONING_FIRST_BYTE_TIMEOUT_MS = 5 * 60 * 1e3;
5629
- function parseSSEDataLine2(line) {
5630
- const trimmed = line.trim();
5631
- if (!trimmed || trimmed.startsWith(":")) return null;
5632
- if (!trimmed.startsWith("data:")) return null;
5633
- const data = trimmed.slice(5);
5634
- return data.startsWith(" ") ? data.slice(1) : data;
6036
+ async function* readSSEData(lines) {
6037
+ let data = [];
6038
+ let firstLine = true;
6039
+ for await (const rawLine of lines) {
6040
+ let line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
6041
+ if (firstLine && line.startsWith("\uFEFF")) line = line.slice(1);
6042
+ firstLine = false;
6043
+ if (line === "") {
6044
+ if (data.length > 0) yield data.join("\n");
6045
+ data = [];
6046
+ } else if (line === "data" || line.startsWith("data:")) {
6047
+ const value = line === "data" ? "" : line.slice(5);
6048
+ data.push(value.startsWith(" ") ? value.slice(1) : value);
6049
+ }
6050
+ }
5635
6051
  }
5636
6052
  function singleAttemptSupport() {
5637
6053
  let capabilities;
@@ -5687,8 +6103,12 @@ function streamResponsesSSE(model, context, options) {
5687
6103
  let budgets = {};
5688
6104
  let totalTimer;
5689
6105
  let internalTimeout;
5690
- let localFailure = false;
6106
+ let localFailure = true;
5691
6107
  let providerRejected = false;
6108
+ let providerErrorMessage;
6109
+ let transportLost = false;
6110
+ let endedWithoutTerminal = false;
6111
+ let responseId;
5692
6112
  const requestAbort = new AbortController();
5693
6113
  const onUserAbort = () => requestAbort.abort();
5694
6114
  const clearTotalTimer = () => {
@@ -5738,8 +6158,8 @@ function streamResponsesSSE(model, context, options) {
5738
6158
  timeoutKind: "request_total",
5739
6159
  terminalAccepted: false,
5740
6160
  cancelSource: "internal_timeout",
5741
- retryAllowed: !submitted,
5742
- retryDecision: submitted ? "not_retryable_after_submission" : "not_submitted"
6161
+ retryAllowed: !!reducer.message.remoteFailure || !submitted,
6162
+ retryDecision: reducer.message.remoteFailure ? `remote_${reducer.message.remoteFailure.category}` : submitted ? "not_retryable_after_submission" : "not_submitted"
5743
6163
  });
5744
6164
  requestAbort.abort();
5745
6165
  }, resolved.requestTimeoutMs);
@@ -5767,6 +6187,7 @@ function streamResponsesSSE(model, context, options) {
5767
6187
  };
5768
6188
  const body = JSON.stringify(payload);
5769
6189
  reportSubmission(options, body, { transport: "sse", reusedConnection: false, continuation: false, attempt: 1 });
6190
+ localFailure = false;
5770
6191
  submitted = true;
5771
6192
  phase = "submission_attempted";
5772
6193
  lifecycle();
@@ -5779,20 +6200,42 @@ function streamResponsesSSE(model, context, options) {
5779
6200
  retryPolicy: "never",
5780
6201
  ...resolved.http,
5781
6202
  label: `${model.provider}/${model.id}`
6203
+ }).catch((error) => {
6204
+ const status = error && typeof error === "object" ? error.status ?? error.statusCode : void 0;
6205
+ if (typeof status === "number" && status >= 400) {
6206
+ providerRejected = true;
6207
+ reducer.message.remoteFailure = responsesRemoteFailure(error, status);
6208
+ providerErrorMessage = `API error ${status}: ${error instanceof Error ? error.message : "request rejected"}`;
6209
+ }
6210
+ transportLost = !providerRejected && !(error instanceof ResponsesProtocolError || error instanceof SyntaxError);
6211
+ throw error;
5782
6212
  });
5783
6213
  if (!response.ok) {
5784
- const errorBody = await response.text().catch(() => "");
5785
6214
  providerRejected = true;
5786
- throw new Error(`API error ${response.status}: ${errorBody}`);
6215
+ providerErrorMessage = `API error ${response.status}`;
6216
+ reducer.message.remoteFailure = responsesRemoteFailure({}, response.status, response.headers);
6217
+ const errorBody = await readResponsesErrorBody(() => response.text(), requestAbort.signal);
6218
+ if (errorBody) {
6219
+ providerErrorMessage += `: ${errorBody}`;
6220
+ reducer.message.remoteFailure = responsesRemoteFailure(parseResponsesErrorBody(errorBody), response.status, response.headers);
6221
+ }
6222
+ requestAbort.abort();
6223
+ throw new Error(providerErrorMessage);
5787
6224
  }
5788
6225
  if (!response.readSSELines) {
5789
- throw new Error("SSE streaming not supported on this platform");
6226
+ throw new ResponsesProtocolError("SSE streaming not supported on this platform");
5790
6227
  }
5791
- for await (const line of response.readSSELines(requestAbort.signal)) {
6228
+ async function* transportLines() {
6229
+ try {
6230
+ yield* response.readSSELines(requestAbort.signal);
6231
+ } catch (error) {
6232
+ transportLost = !(error instanceof ResponsesProtocolError || error instanceof SyntaxError);
6233
+ throw error;
6234
+ }
6235
+ }
6236
+ for await (const data of readSSEData(transportLines())) {
5792
6237
  receivedMessageCount += 1;
5793
6238
  lastReceiveAt = monotonicNow();
5794
- const data = parseSSEDataLine2(line);
5795
- if (data === null) continue;
5796
6239
  if (phase === "submission_attempted") {
5797
6240
  phase = "first_application_message";
5798
6241
  lifecycle();
@@ -5800,27 +6243,47 @@ function streamResponsesSSE(model, context, options) {
5800
6243
  if (data === "[DONE]") {
5801
6244
  continue;
5802
6245
  }
5803
- let event;
6246
+ if (requestAbort.signal.aborted) {
6247
+ throw new Error(internalTimeout ? `Responses request timeout (${internalTimeout})` : "Request was aborted");
6248
+ }
6249
+ let events;
5804
6250
  try {
5805
- event = JSON.parse(data);
6251
+ let event;
6252
+ try {
6253
+ event = JSON.parse(data);
6254
+ } catch (error) {
6255
+ const message = error instanceof Error ? error.message : String(error);
6256
+ throw new ResponsesProtocolError(`Responses SSE stream returned malformed JSON: ${message}`);
6257
+ }
6258
+ if (!isResponsesEventLike(event)) {
6259
+ throw new ResponsesProtocolError("Responses SSE payload is not an event object with a string type.");
6260
+ }
6261
+ if (event.type.startsWith("response.output") || event.type.startsWith("response.content") || event.type.startsWith("response.reasoning")) {
6262
+ sawModelContent = true;
6263
+ }
6264
+ const incomingResponse = event.response;
6265
+ if (event.type === "response.created" && (!isRecord2(incomingResponse) || typeof incomingResponse.id !== "string" || !incomingResponse.id)) {
6266
+ throw new ResponsesProtocolError("response.created requires a response id.");
6267
+ }
6268
+ if (isRecord2(incomingResponse) && typeof incomingResponse.id === "string") {
6269
+ if (responseId && (incomingResponse.id !== responseId || event.type === "response.created")) {
6270
+ throw new ResponsesProtocolError("Response identity changed within a request.");
6271
+ }
6272
+ responseId = incomingResponse.id;
6273
+ }
6274
+ events = reducer.feed(event);
5806
6275
  } catch (error) {
5807
- const message = error instanceof Error ? error.message : String(error);
5808
- throw new ResponsesProtocolError(`Responses SSE stream returned malformed JSON: ${message}`);
5809
- }
5810
- if (!isResponsesEventLike(event)) {
5811
- throw new ResponsesProtocolError("Responses SSE payload is not an event object with a string type.");
5812
- }
5813
- if (typeof event.type === "string" && (event.type.startsWith("response.output") || event.type.startsWith("response.content") || event.type.startsWith("response.reasoning"))) {
5814
- sawModelContent = true;
6276
+ reducer.message.remoteFailure = { category: "other" };
6277
+ throw error;
5815
6278
  }
5816
- for (const assistantEvent of reducer.feed(event)) {
6279
+ for (const assistantEvent of events) {
5817
6280
  stream.push(assistantEvent);
5818
6281
  }
5819
6282
  if (reducer.isTerminal) {
5820
6283
  terminalAccepted = true;
5821
6284
  phase = "terminal_accepted";
5822
6285
  clearTotalTimer();
5823
- lifecycle({ retryAllowed: reducer.message.retryable !== false, retryDecision: "terminal" });
6286
+ lifecycle({ retryAllowed: reducer.message.retryable !== false, retryDecision: reducer.message.remoteFailure ? `remote_${reducer.message.remoteFailure.category}` : "terminal" });
5824
6287
  break;
5825
6288
  }
5826
6289
  }
@@ -5831,6 +6294,7 @@ function streamResponsesSSE(model, context, options) {
5831
6294
  if (requestAbort.signal.aborted) {
5832
6295
  throw new Error(internalTimeout ? `Responses request timeout (${internalTimeout})` : "Request was aborted");
5833
6296
  }
6297
+ endedWithoutTerminal = true;
5834
6298
  throw reducer.finishWithoutTerminal();
5835
6299
  } catch (error) {
5836
6300
  if (reducer.isTerminal) {
@@ -5840,26 +6304,28 @@ function streamResponsesSSE(model, context, options) {
5840
6304
  const message = reducer.message;
5841
6305
  const userAborted = options?.signal?.aborted === true;
5842
6306
  message.stopReason = userAborted ? "aborted" : "error";
6307
+ if (userAborted) delete message.remoteFailure;
5843
6308
  const adapterTimeoutKind = error instanceof Error ? error.timeoutKind : void 0;
5844
6309
  if (!internalTimeout && (adapterTimeoutKind === "first_byte" || adapterTimeoutKind === "stream_idle")) {
5845
6310
  internalTimeout = adapterTimeoutKind === "first_byte" ? "first_response" : "stream_idle";
5846
6311
  }
5847
- message.errorMessage = internalTimeout ? `Responses request timeout (${internalTimeout}) after ${Math.round(monotonicNow() - startedAt)}ms` : error instanceof Error ? error.message : JSON.stringify(error);
6312
+ const protocolFailure = !endedWithoutTerminal && (error instanceof ResponsesProtocolError || error instanceof SyntaxError || !transportLost && error instanceof TypeError);
6313
+ message.errorMessage = providerErrorMessage ?? (internalTimeout && !protocolFailure ? `Responses request timeout (${internalTimeout}) after ${Math.round(monotonicNow() - startedAt)}ms` : error instanceof Error ? error.message : JSON.stringify(error));
5848
6314
  const compat = getResponsesCompat(model);
5849
- const streamLost = !internalTimeout && submitted && !localFailure && !providerRejected && message.stopReason === "error";
5850
- if (internalTimeout && compat.timeoutReplay) {
6315
+ const streamLost = (endedWithoutTerminal || transportLost) && !protocolFailure && !internalTimeout && submitted && !localFailure && !providerRejected && message.stopReason === "error";
6316
+ if (internalTimeout && !message.remoteFailure && !protocolFailure && submitted && !providerRejected && !localFailure && !userAborted && compat.timeoutReplay) {
5851
6317
  message.replayEligible = true;
5852
6318
  message.replayClass = internalTimeout;
5853
- } else if (streamLost && compat.timeoutReplay) {
6319
+ } else if (streamLost && !message.remoteFailure && compat.timeoutReplay) {
5854
6320
  message.replayEligible = true;
5855
6321
  message.replayClass = receivedMessageCount === 0 ? "stream_lost" : "stream_lost_partial";
5856
6322
  }
5857
- if ((submitted || localFailure) && !(streamLost && receivedMessageCount === 0)) message.retryable = false;
6323
+ if (!message.remoteFailure && (userAborted || (submitted || localFailure) && !(streamLost && receivedMessageCount === 0))) message.retryable = false;
5858
6324
  phase = "cleanup";
5859
6325
  lifecycle({
5860
6326
  timeoutKind: internalTimeout,
5861
6327
  retryAllowed: !userAborted && !localFailure && message.retryable !== false,
5862
- retryDecision: streamLost ? receivedMessageCount === 0 ? message.replayEligible ? "replay_exempt_stream_lost" : "stream_lost_no_evidence" : message.replayEligible ? "replay_exempt_after_submission" : "not_retryable_after_submission" : submitted ? "not_retryable_after_submission" : localFailure ? "local_configuration_error" : "not_submitted",
6328
+ retryDecision: message.remoteFailure ? `remote_${message.remoteFailure.category}` : streamLost ? receivedMessageCount === 0 ? message.replayEligible ? "replay_exempt_stream_lost" : "stream_lost_no_evidence" : message.replayEligible ? "replay_exempt_after_submission" : "not_retryable_after_submission" : submitted ? "not_retryable_after_submission" : localFailure ? "local_configuration_error" : "not_submitted",
5863
6329
  cancelSource: userAborted ? "user" : internalTimeout ? "internal_timeout" : "none",
5864
6330
  cleanupOutcome: "request_abandoned"
5865
6331
  });
@@ -5873,9 +6339,112 @@ function streamResponsesSSE(model, context, options) {
5873
6339
  return stream;
5874
6340
  }
5875
6341
 
6342
+ // ../../packages/ai/src/providers/responses/responses-continuation.ts
6343
+ function jsonSha256(value) {
6344
+ return hashJson(value);
6345
+ }
6346
+ function hashJson(value, parts) {
6347
+ const hash = createSha256Hasher();
6348
+ const bytes = new Uint8Array(8192);
6349
+ let used = 0;
6350
+ const byte = (n) => {
6351
+ bytes[used++] = n;
6352
+ if (used === bytes.length) {
6353
+ hash.update(bytes);
6354
+ used = 0;
6355
+ }
6356
+ };
6357
+ const emit = (text) => {
6358
+ for (let i = 0; i < text.length; i++) {
6359
+ const cp = text.codePointAt(i);
6360
+ if (cp < 128) byte(cp);
6361
+ else if (cp < 2048) {
6362
+ byte(192 | cp >> 6);
6363
+ byte(128 | cp & 63);
6364
+ } else if (cp < 65536) {
6365
+ byte(224 | cp >> 12);
6366
+ byte(128 | cp >> 6 & 63);
6367
+ byte(128 | cp & 63);
6368
+ } else {
6369
+ byte(240 | cp >> 18);
6370
+ byte(128 | cp >> 12 & 63);
6371
+ byte(128 | cp >> 6 & 63);
6372
+ byte(128 | cp & 63);
6373
+ i++;
6374
+ }
6375
+ }
6376
+ };
6377
+ const string = (text) => {
6378
+ emit('"');
6379
+ for (let start = 0; start < text.length; ) {
6380
+ let end = Math.min(start + 2048, text.length);
6381
+ if (end < text.length && text.charCodeAt(end - 1) >= 55296 && text.charCodeAt(end - 1) <= 56319) end--;
6382
+ const escaped = JSON.stringify(text.slice(start, end));
6383
+ emit(escaped.slice(1, -1));
6384
+ start = end;
6385
+ }
6386
+ emit('"');
6387
+ };
6388
+ const ancestors = /* @__PURE__ */ new Set();
6389
+ const omitted = (v) => v === void 0 || typeof v === "function" || typeof v === "symbol";
6390
+ const visit = (v) => {
6391
+ if (typeof v === "string") {
6392
+ string(v);
6393
+ return;
6394
+ }
6395
+ if (v === null || typeof v !== "object") {
6396
+ const encoded = JSON.stringify(v);
6397
+ if (encoded === void 0) throw new TypeError("Not a JSON value");
6398
+ emit(encoded);
6399
+ return;
6400
+ }
6401
+ const prototype = Object.getPrototypeOf(v);
6402
+ if (!Array.isArray(v) && prototype !== Object.prototype && prototype !== null || typeof v.toJSON === "function") throw new TypeError("Not a JSON snapshot");
6403
+ if (ancestors.has(v)) throw new TypeError("Circular JSON snapshot");
6404
+ ancestors.add(v);
6405
+ if (Array.isArray(v)) {
6406
+ emit("[");
6407
+ for (let i = 0; i < v.length; i++) {
6408
+ if (Object.getOwnPropertyDescriptor(v, i)?.get) throw new TypeError("Not a JSON snapshot");
6409
+ if (i) emit(",");
6410
+ visit(omitted(v[i]) ? null : v[i]);
6411
+ }
6412
+ emit("]");
6413
+ } else {
6414
+ emit("{");
6415
+ let first = true;
6416
+ for (const key of Object.keys(v)) {
6417
+ if (Object.getOwnPropertyDescriptor(v, key)?.get) throw new TypeError("Not a JSON snapshot");
6418
+ const entry = v[key];
6419
+ if (omitted(entry)) continue;
6420
+ if (!first) emit(",");
6421
+ first = false;
6422
+ string(key);
6423
+ emit(":");
6424
+ visit(entry);
6425
+ }
6426
+ emit("}");
6427
+ }
6428
+ ancestors.delete(v);
6429
+ };
6430
+ if (parts) {
6431
+ emit("[");
6432
+ for (let i = 0; i < parts.count + parts.output.length; i++) {
6433
+ if (i) emit(",");
6434
+ const item = i < parts.count ? parts.input[i] : parts.output[i - parts.count];
6435
+ visit(omitted(item) ? null : item);
6436
+ }
6437
+ emit("]");
6438
+ } else visit(value);
6439
+ if (used) hash.update(bytes.subarray(0, used));
6440
+ return hash.digestHex();
6441
+ }
6442
+ function inputSha256(input, count = input.length, output = []) {
6443
+ return hashJson(void 0, { input, count, output });
6444
+ }
6445
+
5876
6446
  // ../../packages/ai/src/providers/responses/responses-ws.ts
5877
6447
  var owners = /* @__PURE__ */ new WeakMap();
5878
- var MAX_ANCHOR_BYTES = 1024 * 1024;
5879
6448
  var DEFAULT_CONNECT_TIMEOUT_MS = 3e4;
5880
6449
  var DEFAULT_FIRST_RESPONSE_TIMEOUT_MS = 2 * 60 * 1e3;
5881
6450
  var DEFAULT_STREAM_IDLE_TIMEOUT_MS = 2 * 60 * 1e3;
@@ -5963,6 +6532,7 @@ function streamResponsesWS(model, context, options) {
5963
6532
  if (state.busy) {
5964
6533
  reducer.message.stopReason = "error";
5965
6534
  reducer.message.errorMessage = "Responses owner already has an in-flight request.";
6535
+ reducer.message.retryable = false;
5966
6536
  stream.push({ type: "error", reason: "error", error: reducer.message });
5967
6537
  stream.end();
5968
6538
  return stream;
@@ -5991,9 +6561,22 @@ function streamResponsesWS(model, context, options) {
5991
6561
  void (async () => {
5992
6562
  let sent = false;
5993
6563
  let finished = false;
6564
+ let candidateAnchor;
5994
6565
  let terminalEvents = [];
5995
6566
  let fallback = false;
5996
6567
  let timedOut;
6568
+ let providerRejected = false;
6569
+ let localFailure = true;
6570
+ let transportLost = false;
6571
+ let endedWithoutTerminal = false;
6572
+ const transportIO = async (operation) => {
6573
+ try {
6574
+ return await operation();
6575
+ } catch (error) {
6576
+ transportLost = !(error instanceof ResponsesProtocolError || error instanceof SyntaxError) && (!(error instanceof WebSocketTransportError) || error.kind === "closed" || error.kind === "timeout");
6577
+ throw error;
6578
+ }
6579
+ };
5997
6580
  let retryDecision = "none";
5998
6581
  let requestTimer;
5999
6582
  let totalTimer;
@@ -6160,12 +6743,23 @@ function streamResponsesWS(model, context, options) {
6160
6743
  }
6161
6744
  const key = options?.apiKey || getEnvApiKey(model.provider, model.apiKeyEnv);
6162
6745
  if (!key) throw new Error(`No API key for provider: ${model.provider}`);
6163
- const payload = buildResponsesCreateEvent(model, context, options);
6746
+ const encoded = buildResponsesCreateEvent(model, context, options);
6747
+ const { input, ...encodedSettings } = encoded;
6748
+ const settings = JSON.parse(JSON.stringify(encodedSettings));
6749
+ const payload = { ...settings, input };
6164
6750
  const headers = { Authorization: `Bearer ${key}`, ...model.headers, ...options?.headers };
6165
- const { input, ...settings } = payload;
6166
- const identity = JSON.stringify([model.provider, model.api, model.id, model.baseUrl, headers, settings]);
6751
+ const endpoint = websocketUrl(model.baseUrl);
6752
+ let continuationReason = "no_anchor";
6753
+ const identityValue = [1, model.provider, model.api, model.id, endpoint, headers, settings, compat];
6754
+ let identity;
6755
+ try {
6756
+ identity = jsonSha256(identityValue);
6757
+ } catch {
6758
+ }
6759
+ if (!identity) state.anchor = void 0;
6167
6760
  clearConnectionIdleTimer(state);
6168
- if (state.identity !== identity || state.connection?.state() !== "open") {
6761
+ if (!identity || state.identity !== identity || state.connection?.state() !== "open") {
6762
+ if (state.anchor) continuationReason = state.identity !== identity ? "identity_changed" : "connection_changed";
6169
6763
  const stale = state.connection;
6170
6764
  state.connection = void 0;
6171
6765
  state.anchor = void 0;
@@ -6176,29 +6770,37 @@ function streamResponsesWS(model, context, options) {
6176
6770
  reusedConnection = !!state.connection;
6177
6771
  if (state.abort.signal.aborted) throw new Error("Request aborted");
6178
6772
  lifecycle("request_start");
6773
+ localFailure = false;
6179
6774
  const client = getWebSocketClient();
6180
6775
  if (!client) {
6181
6776
  if (options?.transport === "auto") {
6182
6777
  await runSSEFallback();
6183
6778
  return;
6184
6779
  }
6185
- throw new Error("WebSocket transport is not available on this host.");
6780
+ throw new ResponsesProtocolError("WebSocket transport is not available on this host.");
6186
6781
  }
6187
6782
  let connection = state.connection;
6188
6783
  if (!connection) {
6189
6784
  try {
6190
- connection = await client.connect(websocketUrl(model.baseUrl), {
6785
+ connection = await client.connect(endpoint, {
6191
6786
  headers,
6192
6787
  signal: requestAbort.signal,
6193
6788
  connectTimeoutMs: budgets.connectTimeoutMs
6194
6789
  });
6195
6790
  } catch (error) {
6196
6791
  if (error instanceof WebSocketTransportError && error.kind === "timeout") timedOut = "connect";
6792
+ const status = error && typeof error === "object" ? error.status ?? error.statusCode : void 0;
6793
+ if (typeof status === "number" && status >= 400) {
6794
+ providerRejected = true;
6795
+ reducer.message.remoteFailure = responsesRemoteFailure(error, status);
6796
+ }
6197
6797
  if (error instanceof WebSocketTransportError && error.kind === "handshake" && !options?.signal?.aborted && !state.abort.signal.aborted) {
6198
- const status = error.status ?? 0;
6199
- const endpointHasNoWebsockets = options?.transport === "auto" && [404, 405, 426, 501].includes(status);
6200
- const wsEdgeRefused = status === 0 || status === 429 || status >= 500 && status <= 599;
6798
+ const status2 = error.status ?? 0;
6799
+ providerRejected = status2 > 0;
6800
+ const endpointHasNoWebsockets = options?.transport === "auto" && [404, 405, 426, 501].includes(status2);
6801
+ const wsEdgeRefused = status2 === 0 || status2 === 429 || status2 >= 500 && status2 <= 599;
6201
6802
  if (endpointHasNoWebsockets || wsEdgeRefused) {
6803
+ delete reducer.message.remoteFailure;
6202
6804
  await runSSEFallback();
6203
6805
  return;
6204
6806
  }
@@ -6217,28 +6819,57 @@ function streamResponsesWS(model, context, options) {
6217
6819
  const activeConnection = connection;
6218
6820
  const fullInput = input;
6219
6821
  const anchor = state.anchor;
6220
- if (!options?.onPayload && model.compat?.responsesContinuation && anchor && fullInput.length > anchor.count && JSON.stringify(fullInput.slice(0, anchor.count)) === anchor.prefix) {
6221
- payload.previous_response_id = anchor.id;
6222
- payload.input = fullInput.slice(anchor.count);
6822
+ let prefixHashMs = 0;
6823
+ if (options?.onPayload) continuationReason = "payload_hook";
6824
+ else if (!compat.responsesContinuation) continuationReason = "disabled";
6825
+ else if (!identity) continuationReason = "hash_unavailable";
6826
+ else if (anchor) continuationReason = fullInput.length <= anchor.confirmedItemCount ? "history_shortened" : "history_changed";
6827
+ if (!options?.onPayload && compat.responsesContinuation && identity && anchor && anchor.connectionGeneration === connectionGeneration && anchor.requestIdentitySha256 === identity && fullInput.length > anchor.confirmedItemCount) {
6828
+ const hashStarted = monotonicNow();
6829
+ try {
6830
+ if (inputSha256(fullInput, anchor.confirmedItemCount) === anchor.prefixSha256) {
6831
+ continuationReason = "verified_prefix";
6832
+ payload.previous_response_id = anchor.responseId;
6833
+ payload.input = fullInput.slice(anchor.confirmedItemCount);
6834
+ }
6835
+ } catch {
6836
+ continuationReason = "hash_unavailable";
6837
+ }
6838
+ prefixHashMs = monotonicNow() - hashStarted;
6223
6839
  }
6224
6840
  state.anchor = void 0;
6225
6841
  for (let attempt = 0; attempt < 2; attempt++) {
6226
6842
  let rebuild = false;
6227
- options?.onPayload?.(payload);
6843
+ let body;
6844
+ try {
6845
+ options?.onPayload?.(payload);
6846
+ body = JSON.stringify(payload);
6847
+ } catch (error) {
6848
+ localFailure = true;
6849
+ throw error;
6850
+ }
6228
6851
  if (state.abort.signal.aborted || requestAbort.signal.aborted) throw new Error("Request aborted");
6229
6852
  sent = true;
6230
- const body = JSON.stringify(payload);
6231
- reportSubmission(options, body, { transport: "websocket", reusedConnection: reusedConnection || attempt > 0, continuation: !!payload.previous_response_id, attempt: attempt + 1 });
6853
+ reportSubmission(options, body, {
6854
+ transport: "websocket",
6855
+ reusedConnection: reusedConnection || attempt > 0,
6856
+ continuation: !!payload.previous_response_id,
6857
+ attempt: attempt + 1,
6858
+ continuationReason,
6859
+ fullInputItems: fullInput.length,
6860
+ sentInputItems: Array.isArray(payload.input) ? payload.input.length : void 0,
6861
+ prefixHashMs
6862
+ });
6232
6863
  lifecycle("submission_attempted", { submissionAttempted: true });
6233
6864
  armPhaseTimer("first_response", budgets.firstResponseTimeoutMs);
6234
- await activeConnection.send(body, { signal: requestAbort.signal });
6865
+ await transportIO(() => activeConnection.send(body, { signal: requestAbort.signal }));
6235
6866
  let started = false;
6236
6867
  let responseId;
6237
6868
  const receiveIterator = activeConnection.receive(requestAbort.signal)[Symbol.asyncIterator]();
6238
6869
  let receiveDone = false;
6239
6870
  try {
6240
6871
  while (true) {
6241
- const step = await receiveIterator.next();
6872
+ const step = await transportIO(() => receiveIterator.next());
6242
6873
  if (step.done) {
6243
6874
  receiveDone = true;
6244
6875
  break;
@@ -6251,44 +6882,61 @@ function streamResponsesWS(model, context, options) {
6251
6882
  if (state.abort.signal.aborted || requestAbort.signal.aborted) {
6252
6883
  throw new Error(timedOut ? `Responses request timeout (${timedOut})` : "Request aborted");
6253
6884
  }
6254
- if (message.isBinary) throw new ResponsesProtocolError("Responses requires JSON text messages.");
6255
- const event = JSON.parse(message.data);
6256
- if (!isRecord2(event)) throw new ResponsesProtocolError("Invalid Responses WebSocket event.");
6257
- if (typeof event.type === "string") {
6258
- if (event.type === "response.created") sawResponseCreated = true;
6259
- else if (event.type.startsWith("response.output") || event.type.startsWith("response.content") || event.type.startsWith("response.reasoning")) sawModelContent = true;
6260
- }
6261
- 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") {
6262
- delete payload.previous_response_id;
6263
- payload.input = fullInput;
6264
- rebuild = true;
6265
- break;
6266
- }
6267
- if (!started && typeof event.type === "string" && event.type !== "error" && !event.type.startsWith("response.")) continue;
6268
- if (!started && event.type !== "error") {
6269
- if (event.type !== "response.created" || !isRecord2(event.response) || typeof event.response.id !== "string" || event.response.id === state.lastResponseId) {
6270
- throw new ResponsesProtocolError("Expected a new response.created before output.");
6885
+ let events;
6886
+ try {
6887
+ if (message.isBinary) throw new ResponsesProtocolError("Responses requires JSON text messages.");
6888
+ const event = JSON.parse(message.data);
6889
+ if (!isRecord2(event)) throw new ResponsesProtocolError("Invalid Responses WebSocket event.");
6890
+ if (typeof event.type === "string") {
6891
+ if (event.type === "response.created") sawResponseCreated = true;
6892
+ else if (event.type.startsWith("response.output") || event.type.startsWith("response.content") || event.type.startsWith("response.reasoning")) sawModelContent = true;
6271
6893
  }
6272
- started = true;
6273
- responseId = event.response.id;
6894
+ 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") {
6895
+ delete payload.previous_response_id;
6896
+ payload.input = fullInput;
6897
+ continuationReason = "previous_response_not_found";
6898
+ rebuild = true;
6899
+ break;
6900
+ }
6901
+ if (!started && typeof event.type === "string" && event.type !== "error" && !event.type.startsWith("response.")) continue;
6902
+ if (started && event.type === "response.created") throw new ResponsesProtocolError("Duplicate response.created within a request.");
6903
+ if (!started && event.type !== "error") {
6904
+ if (event.type !== "response.created" || !isRecord2(event.response) || typeof event.response.id !== "string" || !event.response.id || event.response.id === state.lastResponseId) {
6905
+ throw new ResponsesProtocolError("Expected a new response.created before output.");
6906
+ }
6907
+ started = true;
6908
+ responseId = event.response.id;
6909
+ }
6910
+ if (responseId && isRecord2(event.response) && event.response.id !== responseId) throw new ResponsesProtocolError("Response identity changed within a request.");
6911
+ events = reducer.feed(event);
6912
+ } catch (error) {
6913
+ reducer.message.remoteFailure = { category: "other" };
6914
+ throw error;
6274
6915
  }
6275
- if (responseId && isRecord2(event.response) && event.response.id !== responseId) throw new ResponsesProtocolError("Response identity changed within a request.");
6276
- const events = reducer.feed(event);
6277
6916
  if (reducer.isTerminal) {
6278
- if (reducer.message.stopReason === "error") reducer.message.retryable = false;
6279
6917
  const response = reducer.terminalResponse;
6280
6918
  state.lastResponseId = response?.id;
6281
- if (!options?.onPayload && response?.status === "completed" && reducer.message.stopReason !== "error") {
6282
- const prefixItems = [...fullInput, ...buildResponsesOutput(reducer.message)];
6283
- const prefix = JSON.stringify(prefixItems);
6284
- if (prefix.length * 2 <= MAX_ANCHOR_BYTES) state.anchor = { id: response.id, prefix, count: prefixItems.length };
6919
+ if (!options?.onPayload && compat.responsesContinuation && identity && response?.status === "completed" && reducer.message.stopReason !== "error") {
6920
+ try {
6921
+ const output = buildResponsesOutput(reducer.message);
6922
+ candidateAnchor = {
6923
+ version: 1,
6924
+ responseId: response.id,
6925
+ confirmedItemCount: fullInput.length + output.length,
6926
+ prefixSha256: inputSha256(fullInput, fullInput.length, output),
6927
+ requestIdentitySha256: identity,
6928
+ connectionGeneration
6929
+ };
6930
+ } catch {
6931
+ }
6285
6932
  }
6286
6933
  finished = true;
6287
6934
  clearRequestTimers();
6935
+ retryDecision = reducer.message.remoteFailure ? `remote_${reducer.message.remoteFailure.category}` : "terminal";
6288
6936
  lifecycle("terminal_accepted", {
6289
6937
  terminalAccepted: true,
6290
6938
  retryAllowed: reducer.message.retryable !== false,
6291
- retryDecision: "terminal"
6939
+ retryDecision
6292
6940
  });
6293
6941
  for (const e of events) publish(e);
6294
6942
  break;
@@ -6302,7 +6950,10 @@ function streamResponsesWS(model, context, options) {
6302
6950
  retryDecision = "rebuild_previous_response";
6303
6951
  continue;
6304
6952
  }
6305
- if (!reducer.isTerminal) throw reducer.finishWithoutTerminal();
6953
+ if (!reducer.isTerminal) {
6954
+ endedWithoutTerminal = true;
6955
+ throw reducer.finishWithoutTerminal();
6956
+ }
6306
6957
  break;
6307
6958
  }
6308
6959
  } catch (error) {
@@ -6311,24 +6962,30 @@ function streamResponsesWS(model, context, options) {
6311
6962
  const userAborted = options?.signal?.aborted === true;
6312
6963
  const ownerDisposed = !userAborted && !timedOut && state.abort.signal.aborted;
6313
6964
  message.stopReason = userAborted || ownerDisposed ? "aborted" : "error";
6314
- const cause = timedOut ? `Responses request timeout (${timedOut}) after ${ageMs()}ms` : error instanceof Error ? error.message : String(error);
6965
+ if (userAborted || ownerDisposed) delete message.remoteFailure;
6966
+ const protocolFailure = !endedWithoutTerminal && (error instanceof ResponsesProtocolError || error instanceof SyntaxError || !transportLost && error instanceof TypeError || error instanceof WebSocketTransportError && (error.kind === "protocol" || error.kind === "overflow"));
6967
+ const cause = providerRejected && error instanceof WebSocketTransportError ? `${error.message} (HTTP status ${error.status})` : timedOut && !protocolFailure ? `Responses request timeout (${timedOut}) after ${ageMs()}ms` : error instanceof Error ? error.message : String(error);
6315
6968
  message.errorMessage = cause;
6316
- const streamLost = !timedOut && message.stopReason === "error";
6317
- if (timedOut && compat.timeoutReplay) {
6969
+ const streamLost = (endedWithoutTerminal || transportLost) && !protocolFailure && sent && !timedOut && !providerRejected && message.stopReason === "error";
6970
+ if (timedOut && timedOut !== "connect" && !message.remoteFailure && !protocolFailure && !localFailure && sent && !providerRejected && !userAborted && !ownerDisposed && compat.timeoutReplay) {
6318
6971
  message.replayEligible = true;
6319
6972
  message.replayClass = timedOut;
6320
- } else if (streamLost && compat.timeoutReplay) {
6973
+ } else if (streamLost && !message.remoteFailure && compat.timeoutReplay) {
6321
6974
  message.replayEligible = true;
6322
6975
  message.replayClass = receivedMessageCount === 0 ? "stream_lost" : "stream_lost_partial";
6323
6976
  }
6977
+ if (!message.remoteFailure && (localFailure || providerRejected || protocolFailure || userAborted || ownerDisposed)) {
6978
+ message.retryable = false;
6979
+ }
6324
6980
  if (sent) {
6325
6981
  if (streamLost && receivedMessageCount === 0) {
6326
6982
  retryDecision = message.replayEligible ? "replay_exempt_stream_lost" : "stream_lost_no_evidence";
6327
6983
  } else {
6328
- message.retryable = false;
6984
+ if (!message.remoteFailure) message.retryable = false;
6329
6985
  if (!timedOut) retryDecision = message.replayEligible ? "replay_exempt_after_submission" : "not_retryable_after_submission";
6330
6986
  }
6331
6987
  }
6988
+ if (message.remoteFailure) retryDecision = `remote_${message.remoteFailure.category}`;
6332
6989
  cleanupCancelSource = userAborted ? "user" : timedOut ? "internal_timeout" : ownerDisposed ? "owner_disposal" : "none";
6333
6990
  stream.push({ type: "error", reason: message.stopReason, error: message });
6334
6991
  }
@@ -6339,9 +6996,10 @@ function streamResponsesWS(model, context, options) {
6339
6996
  options?.signal?.removeEventListener("abort", abort);
6340
6997
  state.busy = false;
6341
6998
  const cancelSource = cleanupCancelSource ?? (options?.signal?.aborted ? "user" : timedOut ? "internal_timeout" : state.abort.signal.aborted ? "owner_disposal" : "none");
6342
- const retain = finished && !fallback && !receiveCleanupFailed && !!options?.transportOwner && reducer.message.stopReason !== "error" && !timedOut && state.connection !== void 0 && !state.abort.signal.aborted;
6999
+ const retain = finished && !fallback && !receiveCleanupFailed && !!options?.transportOwner && reducer.message.stopReason !== "error" && !timedOut && state.connection?.state() === "open" && !state.abort.signal.aborted && owners.get(owner) === state && state.requestGeneration === requestGeneration && state.connectionGeneration === connectionGeneration;
6343
7000
  if (!retain) disposeState(owner, state);
6344
7001
  else if (state.connection) {
7002
+ state.anchor = candidateAnchor;
6345
7003
  armConnectionIdleRecycle(state, state.connection, connectionGeneration, budgets.connectionIdleTimeoutMs);
6346
7004
  }
6347
7005
  const cleanupOutcome = receiveCleanupFailed ? "cleanup_failed" : retain ? "connection_reused" : finished ? "connection_closed" : "request_abandoned";
@@ -6349,7 +7007,7 @@ function streamResponsesWS(model, context, options) {
6349
7007
  terminalAccepted: finished,
6350
7008
  timeoutKind: timedOut,
6351
7009
  submissionAttempted: sent,
6352
- retryAllowed: !finished && reducer.message.stopReason !== "aborted" && reducer.message.retryable !== false,
7010
+ retryAllowed: (!finished || !!reducer.message.remoteFailure) && reducer.message.stopReason !== "aborted" && reducer.message.retryable !== false,
6353
7011
  cancelSource,
6354
7012
  retryDecision,
6355
7013
  cleanupOutcome
@@ -6743,7 +7401,7 @@ function FNV1A64(byte) {
6743
7401
  Accumulator = Accumulator ^ Bytes[byte];
6744
7402
  Accumulator = Accumulator * Prime % Size;
6745
7403
  }
6746
- function Hash(value) {
7404
+ function Hash2(value) {
6747
7405
  Accumulator = BigInt("14695981039346656037");
6748
7406
  Visit(value);
6749
7407
  return Accumulator;
@@ -6784,7 +7442,7 @@ function FromArray(schema, references, value) {
6784
7442
  if (schema.uniqueItems === true && !(function() {
6785
7443
  const set = /* @__PURE__ */ new Set();
6786
7444
  for (const element of value) {
6787
- const hashed = Hash(element);
7445
+ const hashed = Hash2(element);
6788
7446
  if (set.has(hashed)) {
6789
7447
  return false;
6790
7448
  } else {
@@ -7304,7 +7962,7 @@ function* FromArray2(schema, references, path, value) {
7304
7962
  if (schema.uniqueItems === true && !(function() {
7305
7963
  const set = /* @__PURE__ */ new Set();
7306
7964
  for (const element of value) {
7307
- const hashed = Hash(element);
7965
+ const hashed = Hash2(element);
7308
7966
  if (set.has(hashed)) {
7309
7967
  return false;
7310
7968
  } else {
@@ -9783,7 +10441,7 @@ __export(value_exports, {
9783
10441
  Encode: () => Encode,
9784
10442
  Equal: () => Equal,
9785
10443
  Errors: () => Errors,
9786
- Hash: () => Hash,
10444
+ Hash: () => Hash2,
9787
10445
  Mutate: () => Mutate,
9788
10446
  Parse: () => Parse,
9789
10447
  Patch: () => Patch,
@@ -9889,7 +10547,7 @@ export {
9889
10547
  modelSupportsToolPurpose,
9890
10548
  sortToolModelCandidatesByCapability,
9891
10549
  Deref,
9892
- Hash,
10550
+ Hash2 as Hash,
9893
10551
  Errors,
9894
10552
  TransformDecodeCheckError,
9895
10553
  TransformDecode,