@buoy-gg/agent-core 7.0.35 → 7.0.38

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 (208) hide show
  1. package/README.md +21 -14
  2. package/lib/commonjs/blocks/receipts.js +57 -1
  3. package/lib/commonjs/blocks/receipts.js.map +1 -1
  4. package/lib/commonjs/blocks/types.js +23 -2
  5. package/lib/commonjs/blocks/types.js.map +1 -1
  6. package/lib/commonjs/blocks/uiTool.js +423 -10
  7. package/lib/commonjs/blocks/uiTool.js.map +1 -1
  8. package/lib/commonjs/catalog/catalog.g.js +213 -48
  9. package/lib/commonjs/catalog/catalog.g.js.map +1 -1
  10. package/lib/commonjs/catalog/catalog.source.json +226 -48
  11. package/lib/commonjs/catalog/catalog.types.g.js +44 -0
  12. package/lib/commonjs/catalog/catalog.types.g.js.map +1 -0
  13. package/lib/commonjs/catalog/normalizeParams.js +333 -0
  14. package/lib/commonjs/catalog/normalizeParams.js.map +1 -0
  15. package/lib/commonjs/catalog/signature.js +68 -0
  16. package/lib/commonjs/catalog/signature.js.map +1 -0
  17. package/lib/commonjs/catalog/snapshotReads.js +13 -6
  18. package/lib/commonjs/catalog/snapshotReads.js.map +1 -1
  19. package/lib/commonjs/catalog/toProviderTools.js +44 -6
  20. package/lib/commonjs/catalog/toProviderTools.js.map +1 -1
  21. package/lib/commonjs/context/buildContextPack.js +367 -19
  22. package/lib/commonjs/context/buildContextPack.js.map +1 -1
  23. package/lib/commonjs/effects/digest.js +34 -0
  24. package/lib/commonjs/effects/digest.js.map +1 -0
  25. package/lib/commonjs/effects/ledger.js +98 -2
  26. package/lib/commonjs/effects/ledger.js.map +1 -1
  27. package/lib/commonjs/engine/askGate.js +287 -0
  28. package/lib/commonjs/engine/askGate.js.map +1 -0
  29. package/lib/commonjs/engine/effectFor.js +82 -1
  30. package/lib/commonjs/engine/effectFor.js.map +1 -1
  31. package/lib/commonjs/engine/evidence.js +113 -0
  32. package/lib/commonjs/engine/evidence.js.map +1 -0
  33. package/lib/commonjs/engine/historyBudget.js +363 -0
  34. package/lib/commonjs/engine/historyBudget.js.map +1 -0
  35. package/lib/commonjs/engine/retrieve.js +214 -0
  36. package/lib/commonjs/engine/retrieve.js.map +1 -0
  37. package/lib/commonjs/engine/runAgentTurn.js +1231 -120
  38. package/lib/commonjs/engine/runAgentTurn.js.map +1 -1
  39. package/lib/commonjs/engine/systemPrompt.js +103 -9
  40. package/lib/commonjs/engine/systemPrompt.js.map +1 -1
  41. package/lib/commonjs/engine/textToolCalls.js +276 -0
  42. package/lib/commonjs/engine/textToolCalls.js.map +1 -0
  43. package/lib/commonjs/engine/tokenCalibration.js +81 -0
  44. package/lib/commonjs/engine/tokenCalibration.js.map +1 -0
  45. package/lib/commonjs/engine/verify.js +300 -0
  46. package/lib/commonjs/engine/verify.js.map +1 -0
  47. package/lib/commonjs/index.js +74 -0
  48. package/lib/commonjs/index.js.map +1 -1
  49. package/lib/commonjs/policy/labels.js +19 -3
  50. package/lib/commonjs/policy/labels.js.map +1 -1
  51. package/lib/commonjs/policy/policy.js +6 -1
  52. package/lib/commonjs/policy/policy.js.map +1 -1
  53. package/lib/commonjs/policy/redact.js +42 -5
  54. package/lib/commonjs/policy/redact.js.map +1 -1
  55. package/lib/commonjs/providers/anthropic.js +340 -208
  56. package/lib/commonjs/providers/anthropic.js.map +1 -1
  57. package/lib/commonjs/providers/openai.js +237 -103
  58. package/lib/commonjs/providers/openai.js.map +1 -1
  59. package/lib/commonjs/providers/problem.js +98 -0
  60. package/lib/commonjs/providers/problem.js.map +1 -0
  61. package/lib/commonjs/providers/sse.js +170 -34
  62. package/lib/commonjs/providers/sse.js.map +1 -1
  63. package/lib/commonjs/providers/streamTimer.js +123 -0
  64. package/lib/commonjs/providers/streamTimer.js.map +1 -0
  65. package/lib/commonjs/providers/transport.js +123 -0
  66. package/lib/commonjs/providers/transport.js.map +1 -0
  67. package/lib/commonjs/providers/xhrStream.js +212 -0
  68. package/lib/commonjs/providers/xhrStream.js.map +1 -0
  69. package/lib/commonjs/session.js +242 -58
  70. package/lib/commonjs/session.js.map +1 -1
  71. package/lib/module/blocks/receipts.js +57 -1
  72. package/lib/module/blocks/receipts.js.map +1 -1
  73. package/lib/module/blocks/types.js +23 -2
  74. package/lib/module/blocks/types.js.map +1 -1
  75. package/lib/module/blocks/uiTool.js +421 -10
  76. package/lib/module/blocks/uiTool.js.map +1 -1
  77. package/lib/module/catalog/catalog.g.js +213 -48
  78. package/lib/module/catalog/catalog.g.js.map +1 -1
  79. package/lib/module/catalog/catalog.source.json +226 -48
  80. package/lib/module/catalog/catalog.types.g.js +40 -0
  81. package/lib/module/catalog/catalog.types.g.js.map +1 -0
  82. package/lib/module/catalog/normalizeParams.js +327 -0
  83. package/lib/module/catalog/normalizeParams.js.map +1 -0
  84. package/lib/module/catalog/signature.js +63 -0
  85. package/lib/module/catalog/signature.js.map +1 -0
  86. package/lib/module/catalog/snapshotReads.js +13 -6
  87. package/lib/module/catalog/snapshotReads.js.map +1 -1
  88. package/lib/module/catalog/toProviderTools.js +44 -6
  89. package/lib/module/catalog/toProviderTools.js.map +1 -1
  90. package/lib/module/context/buildContextPack.js +366 -19
  91. package/lib/module/context/buildContextPack.js.map +1 -1
  92. package/lib/module/effects/digest.js +29 -0
  93. package/lib/module/effects/digest.js.map +1 -0
  94. package/lib/module/effects/ledger.js +98 -2
  95. package/lib/module/effects/ledger.js.map +1 -1
  96. package/lib/module/engine/askGate.js +280 -0
  97. package/lib/module/engine/askGate.js.map +1 -0
  98. package/lib/module/engine/effectFor.js +83 -1
  99. package/lib/module/engine/effectFor.js.map +1 -1
  100. package/lib/module/engine/evidence.js +107 -0
  101. package/lib/module/engine/evidence.js.map +1 -0
  102. package/lib/module/engine/historyBudget.js +355 -0
  103. package/lib/module/engine/historyBudget.js.map +1 -0
  104. package/lib/module/engine/retrieve.js +210 -0
  105. package/lib/module/engine/retrieve.js.map +1 -0
  106. package/lib/module/engine/runAgentTurn.js +1227 -121
  107. package/lib/module/engine/runAgentTurn.js.map +1 -1
  108. package/lib/module/engine/systemPrompt.js +101 -9
  109. package/lib/module/engine/systemPrompt.js.map +1 -1
  110. package/lib/module/engine/textToolCalls.js +270 -0
  111. package/lib/module/engine/textToolCalls.js.map +1 -0
  112. package/lib/module/engine/tokenCalibration.js +75 -0
  113. package/lib/module/engine/tokenCalibration.js.map +1 -0
  114. package/lib/module/engine/verify.js +292 -0
  115. package/lib/module/engine/verify.js.map +1 -0
  116. package/lib/module/index.js +7 -3
  117. package/lib/module/index.js.map +1 -1
  118. package/lib/module/policy/labels.js +19 -3
  119. package/lib/module/policy/labels.js.map +1 -1
  120. package/lib/module/policy/policy.js +6 -1
  121. package/lib/module/policy/policy.js.map +1 -1
  122. package/lib/module/policy/redact.js +42 -5
  123. package/lib/module/policy/redact.js.map +1 -1
  124. package/lib/module/providers/anthropic.js +341 -209
  125. package/lib/module/providers/anthropic.js.map +1 -1
  126. package/lib/module/providers/openai.js +238 -104
  127. package/lib/module/providers/openai.js.map +1 -1
  128. package/lib/module/providers/problem.js +92 -0
  129. package/lib/module/providers/problem.js.map +1 -0
  130. package/lib/module/providers/sse.js +166 -34
  131. package/lib/module/providers/sse.js.map +1 -1
  132. package/lib/module/providers/streamTimer.js +118 -0
  133. package/lib/module/providers/streamTimer.js.map +1 -0
  134. package/lib/module/providers/transport.js +119 -0
  135. package/lib/module/providers/transport.js.map +1 -0
  136. package/lib/module/providers/xhrStream.js +207 -0
  137. package/lib/module/providers/xhrStream.js.map +1 -0
  138. package/lib/module/session.js +226 -60
  139. package/lib/module/session.js.map +1 -1
  140. package/lib/typescript/blocks/receipts.d.ts +5 -0
  141. package/lib/typescript/blocks/receipts.d.ts.map +1 -1
  142. package/lib/typescript/blocks/types.d.ts +23 -2
  143. package/lib/typescript/blocks/types.d.ts.map +1 -1
  144. package/lib/typescript/blocks/uiTool.d.ts +11 -2
  145. package/lib/typescript/blocks/uiTool.d.ts.map +1 -1
  146. package/lib/typescript/catalog/catalog.g.d.ts +2 -2
  147. package/lib/typescript/catalog/catalog.g.d.ts.map +1 -1
  148. package/lib/typescript/catalog/catalog.types.g.d.ts +40 -0
  149. package/lib/typescript/catalog/catalog.types.g.d.ts.map +1 -0
  150. package/lib/typescript/catalog/normalizeParams.d.ts +43 -0
  151. package/lib/typescript/catalog/normalizeParams.d.ts.map +1 -0
  152. package/lib/typescript/catalog/signature.d.ts +29 -0
  153. package/lib/typescript/catalog/signature.d.ts.map +1 -0
  154. package/lib/typescript/catalog/snapshotReads.d.ts.map +1 -1
  155. package/lib/typescript/catalog/toProviderTools.d.ts +28 -15
  156. package/lib/typescript/catalog/toProviderTools.d.ts.map +1 -1
  157. package/lib/typescript/context/buildContextPack.d.ts +24 -2
  158. package/lib/typescript/context/buildContextPack.d.ts.map +1 -1
  159. package/lib/typescript/effects/digest.d.ts +10 -0
  160. package/lib/typescript/effects/digest.d.ts.map +1 -0
  161. package/lib/typescript/effects/ledger.d.ts +73 -0
  162. package/lib/typescript/effects/ledger.d.ts.map +1 -1
  163. package/lib/typescript/engine/askGate.d.ts +29 -0
  164. package/lib/typescript/engine/askGate.d.ts.map +1 -0
  165. package/lib/typescript/engine/effectFor.d.ts +6 -1
  166. package/lib/typescript/engine/effectFor.d.ts.map +1 -1
  167. package/lib/typescript/engine/evidence.d.ts +67 -0
  168. package/lib/typescript/engine/evidence.d.ts.map +1 -0
  169. package/lib/typescript/engine/historyBudget.d.ts +115 -0
  170. package/lib/typescript/engine/historyBudget.d.ts.map +1 -0
  171. package/lib/typescript/engine/retrieve.d.ts +32 -0
  172. package/lib/typescript/engine/retrieve.d.ts.map +1 -0
  173. package/lib/typescript/engine/runAgentTurn.d.ts +179 -3
  174. package/lib/typescript/engine/runAgentTurn.d.ts.map +1 -1
  175. package/lib/typescript/engine/systemPrompt.d.ts +80 -0
  176. package/lib/typescript/engine/systemPrompt.d.ts.map +1 -1
  177. package/lib/typescript/engine/textToolCalls.d.ts +58 -0
  178. package/lib/typescript/engine/textToolCalls.d.ts.map +1 -0
  179. package/lib/typescript/engine/tokenCalibration.d.ts +46 -0
  180. package/lib/typescript/engine/tokenCalibration.d.ts.map +1 -0
  181. package/lib/typescript/engine/verify.d.ts +67 -0
  182. package/lib/typescript/engine/verify.d.ts.map +1 -0
  183. package/lib/typescript/index.d.ts +7 -3
  184. package/lib/typescript/index.d.ts.map +1 -1
  185. package/lib/typescript/policy/labels.d.ts.map +1 -1
  186. package/lib/typescript/policy/policy.d.ts.map +1 -1
  187. package/lib/typescript/policy/redact.d.ts.map +1 -1
  188. package/lib/typescript/providers/anthropic.d.ts.map +1 -1
  189. package/lib/typescript/providers/openai.d.ts +0 -16
  190. package/lib/typescript/providers/openai.d.ts.map +1 -1
  191. package/lib/typescript/providers/problem.d.ts +50 -0
  192. package/lib/typescript/providers/problem.d.ts.map +1 -0
  193. package/lib/typescript/providers/sse.d.ts +86 -2
  194. package/lib/typescript/providers/sse.d.ts.map +1 -1
  195. package/lib/typescript/providers/streamTimer.d.ts +59 -0
  196. package/lib/typescript/providers/streamTimer.d.ts.map +1 -0
  197. package/lib/typescript/providers/transport.d.ts +48 -0
  198. package/lib/typescript/providers/transport.d.ts.map +1 -0
  199. package/lib/typescript/providers/types.d.ts +105 -3
  200. package/lib/typescript/providers/types.d.ts.map +1 -1
  201. package/lib/typescript/providers/xhrStream.d.ts +45 -0
  202. package/lib/typescript/providers/xhrStream.d.ts.map +1 -0
  203. package/lib/typescript/session.d.ts +55 -4
  204. package/lib/typescript/session.d.ts.map +1 -1
  205. package/lib/typescript/types.d.ts +6 -0
  206. package/lib/typescript/types.d.ts.map +1 -1
  207. package/package.json +10 -10
  208. package/LICENSE +0 -58
@@ -4,7 +4,11 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.errorBody = errorBody;
7
+ exports.framesFrom = framesFrom;
8
+ exports.nonStreamProblem = nonStreamProblem;
7
9
  exports.readSse = readSse;
10
+ exports.truncatedMessage = truncatedMessage;
11
+ exports.unparseableMessage = unparseableMessage;
8
12
  /**
9
13
  * SSE reading, with the React Native reality baked in.
10
14
  *
@@ -14,15 +18,24 @@ exports.readSse = readSse;
14
18
  * TV-CLI lanes never had it. So `readSse` degrades to reading the whole body
15
19
  * and replaying it as events rather than failing: a non-streaming answer is a
16
20
  * slower chat, while a hard failure is no chat at all.
21
+ *
22
+ * THE TWO PATHS MUST AGREE. They did not. The buffered path appended "\n\n" to
23
+ * the body before parsing, which turns an unterminated final frame — the exact
24
+ * signature of a cut connection — into a well-formed event. The streaming path
25
+ * discarded that same frame, as the SSE spec requires. So one lane invented a
26
+ * complete answer where the other saw a broken one. Now both discard it and
27
+ * both RECORD it (`SseReadStatus.truncated`), because "was this reply whole?"
28
+ * is a question the engine has to answer before it runs anything.
17
29
  */
18
30
 
19
- function* parseChunk(buffer) {
31
+ function* parseChunk(buffer, onFrame) {
20
32
  let rest = buffer;
21
33
  let idx;
22
34
  // Frames are separated by a blank line. \r\n\r\n is legal too.
23
35
  while ((idx = rest.search(/\r?\n\r?\n/)) !== -1) {
24
36
  const raw = rest.slice(0, idx);
25
37
  rest = rest.slice(idx + (rest[idx] === "\r" ? 4 : 2));
38
+ onFrame?.();
26
39
  let event;
27
40
  const dataLines = [];
28
41
  for (const line of raw.split(/\r?\n/)) {
@@ -36,53 +49,124 @@ function* parseChunk(buffer) {
36
49
  }
37
50
  return rest;
38
51
  }
39
- async function* readSse(response) {
52
+
53
+ /**
54
+ * Drain complete frames out of `buffer`, returning what is left over.
55
+ *
56
+ * Shared by both paths so a framing fix can only ever be made in one place.
57
+ */
58
+ function* drain(buffer, out, onFrame) {
59
+ const gen = parseChunk(buffer, onFrame);
60
+ let next = gen.next();
61
+ while (!next.done) {
62
+ yield next.value;
63
+ next = gen.next();
64
+ }
65
+ out.rest = next.value;
66
+ }
67
+
68
+ /**
69
+ * Turn a stream of TEXT chunks into SSE frames.
70
+ *
71
+ * The one place framing happens, whatever produced the bytes: a `fetch` body
72
+ * reader, an `XMLHttpRequest` progress slice, or a whole body read at once on
73
+ * a runtime that cannot stream. Splitting it out is what lets the XHR
74
+ * transport exist without a second parser to keep in step with this one.
75
+ */
76
+ async function* framesFrom(chunks, options = {}) {
77
+ const {
78
+ status,
79
+ onFrame
80
+ } = options;
81
+ const leftover = {
82
+ rest: ""
83
+ };
84
+ let buffer = "";
85
+ for await (const chunk of chunks) {
86
+ buffer += chunk;
87
+ yield* drain(buffer, leftover, onFrame);
88
+ buffer = leftover.rest;
89
+ }
90
+ if (status && leftover.rest.trim()) status.truncated = true;
91
+ }
92
+ async function* readSse(response, options = {}) {
93
+ const {
94
+ status,
95
+ onFrame,
96
+ signal
97
+ } = options;
40
98
  const body = response.body;
99
+ const leftover = {
100
+ rest: ""
101
+ };
41
102
  if (!body || typeof body.getReader !== "function") {
42
- // No streaming on this platform — read it all, then replay.
103
+ // No streaming on this platform — read it all, then replay. Note there is
104
+ // no "\n\n" here any more: an unterminated tail is discarded exactly as
105
+ // the streaming path discards it (see the header).
43
106
  const text = await response.text();
44
- let rest = "";
45
- const gen = parseChunk(text + "\n\n");
46
- let next = gen.next();
47
- while (!next.done) {
48
- yield next.value;
49
- next = gen.next();
50
- }
51
- rest = next.value;
52
- if (rest.trim()) {
53
- const tail = parseChunk(rest + "\n\n");
54
- let t = tail.next();
55
- while (!t.done) {
56
- yield t.value;
57
- t = tail.next();
58
- }
59
- }
107
+ yield* drain(text, leftover, onFrame);
108
+ if (status && leftover.rest.trim()) status.truncated = true;
60
109
  return;
61
110
  }
62
111
  const reader = body.getReader();
63
112
  const decoder = new TextDecoder();
64
113
  let buffer = "";
114
+ let finished = false;
115
+ /**
116
+ * One promise for the whole read, not one per chunk.
117
+ *
118
+ * It never resolves — only rejects — so racing it is free apart from the
119
+ * `Promise.race` allocation, and an answer of a few hundred frames pays far
120
+ * more for `JSON.parse` than for this.
121
+ */
122
+ const aborted = signal ? new Promise((_resolve, reject) => {
123
+ const fail = () => {
124
+ const err = new Error("Aborted");
125
+ err.name = "AbortError";
126
+ reject(err);
127
+ };
128
+ if (signal.aborted) fail();else signal.addEventListener?.("abort", fail, {
129
+ once: true
130
+ });
131
+ }) : undefined;
132
+ // Nothing awaits this until the race below, and a rejection with no handler
133
+ // is an unhandled rejection on some runtimes. This is the handler.
134
+ aborted?.catch(() => {});
65
135
  try {
66
136
  for (;;) {
137
+ const read = reader.read();
67
138
  const {
68
139
  done,
69
140
  value
70
- } = await reader.read();
141
+ } = aborted ? await Promise.race([read, aborted]) : await read;
71
142
  if (done) break;
72
143
  buffer += decoder.decode(value, {
73
144
  stream: true
74
145
  });
75
- const gen = parseChunk(buffer);
76
- let next = gen.next();
77
- while (!next.done) {
78
- yield next.value;
79
- next = gen.next();
80
- }
81
- buffer = next.value;
146
+ yield* drain(buffer, leftover, onFrame);
147
+ buffer = leftover.rest;
82
148
  }
149
+ // Flush the decoder: a multi-byte character split across the last two
150
+ // chunks is only completed here, and an INCOMPLETE one at EOF is itself
151
+ // evidence the connection was cut.
152
+ buffer += decoder.decode();
153
+ yield* drain(buffer, leftover, onFrame);
154
+ if (status && leftover.rest.trim()) status.truncated = true;
155
+ finished = true;
83
156
  } finally {
84
- // Cancelling on abort keeps the socket from lingering after the user
85
- // closes the sheet mid-answer.
157
+ if (!finished) {
158
+ // The consumer left early — an abort, a timeout, or a `break` in the
159
+ // provider. `releaseLock` alone leaves the socket open; only `cancel`
160
+ // tears the request down, and it must come first because cancelling a
161
+ // locked reader is the only way to reach the underlying stream.
162
+ try {
163
+ // Not awaited: the consumer is already leaving, and a cancel that
164
+ // rejects (an errored stream) must not become an unhandled rejection.
165
+ void Promise.resolve(reader.cancel()).catch(() => {});
166
+ } catch {
167
+ /* already cancelled or errored */
168
+ }
169
+ }
86
170
  try {
87
171
  reader.releaseLock();
88
172
  } catch {
@@ -91,14 +175,66 @@ async function* readSse(response) {
91
175
  }
92
176
  }
93
177
 
94
- /** Body text for a failed response, trimmed to something a user can read. */
178
+ /**
179
+ * A 200 that is not a stream at all.
180
+ *
181
+ * Gateways in front of a model do this: an auth proxy that has lost its
182
+ * upstream serves an HTML error page, a misrouted path serves an SPA shell,
183
+ * and a gateway that ignored `stream: true` serves one JSON object. Every one
184
+ * of those parses to zero SSE frames, so the old code read it as a model that
185
+ * had nothing to say and ended the turn with a blank bubble.
186
+ *
187
+ * Returns a message when the body should be treated as an error, and undefined
188
+ * when it looks like something the SSE reader can work with. Consumes the body
189
+ * only in the failing case.
190
+ */
191
+ async function nonStreamProblem(response) {
192
+ const type = response.headers?.get?.("content-type") ?? "";
193
+ if (!type) return undefined; // No header to judge by — let the parser try.
194
+ const lowered = type.toLowerCase();
195
+ if (lowered.includes("event-stream")) return undefined;
196
+ // A JSON body is either a non-streaming reply or a structured error; both
197
+ // are worth reporting with their own text rather than guessing.
198
+ const detail = (await response.text().catch(() => "")).slice(0, 600);
199
+ if (lowered.includes("json")) {
200
+ return `The endpoint answered with JSON instead of a stream — it may not support "stream": true.${detail ? ` — ${detail}` : ""}`;
201
+ }
202
+ return `The endpoint answered with ${type} instead of an event stream.${detail ? ` — ${detail}` : ""}`;
203
+ }
204
+
205
+ /**
206
+ * Body text for a failed response, trimmed to something a user can read.
207
+ * The detail alone — the transport prefixes the status and classifies it.
208
+ */
95
209
  async function errorBody(response) {
96
- let detail = "";
97
210
  try {
98
- detail = (await response.text()).slice(0, 600);
211
+ return (await response.text()).slice(0, 600);
99
212
  } catch {
100
- /* body already consumed or unreadable */
213
+ return ""; // body already consumed or unreadable
101
214
  }
102
- return `HTTP ${response.status}${detail ? ` — ${detail}` : ""}`;
215
+ }
216
+
217
+ /**
218
+ * The message for a stream that stopped before the provider said it was done.
219
+ *
220
+ * `truncated` distinguishes the two shapes: cut mid-frame (a dropped
221
+ * connection) versus a clean frame boundary with no terminal marker (a gateway
222
+ * that closes the socket instead of sending one). The second is a
223
+ * compatibility problem worth naming, because retrying it will not help.
224
+ */
225
+ function truncatedMessage(truncated) {
226
+ return truncated ? "The connection dropped before the answer finished." : "The endpoint closed the stream without saying the answer was finished.";
227
+ }
228
+
229
+ /**
230
+ * The message for arguments that would not parse, with enough in it to act on.
231
+ * `stopReason` "length" is the common cause — a reasoning model spends its
232
+ * budget thinking and the tool call is truncated mid-JSON — and the tail of
233
+ * the raw arguments says immediately whether that is what happened.
234
+ */
235
+ function unparseableMessage(name, args, stopReason) {
236
+ const truncated = stopReason === "length";
237
+ const tail = args.length > 160 ? `…${args.slice(-160)}` : args;
238
+ return `Model sent unparseable arguments for ${name}` + (truncated ? " (cut off at max_tokens — raise it or reduce thinking budget)" : "") + ` [stop: ${stopReason ?? "none"}, ${args.length} chars] ${tail}`;
103
239
  }
104
240
  //# sourceMappingURL=sse.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["parseChunk","buffer","rest","idx","search","raw","slice","event","dataLines","line","split","startsWith","trim","push","replace","length","data","join","readSse","response","body","getReader","text","gen","next","done","value","tail","t","reader","decoder","TextDecoder","read","decode","stream","releaseLock","errorBody","detail","status"],"sourceRoot":"../../../src","sources":["providers/sse.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["parseChunk","buffer","onFrame","rest","idx","search","raw","slice","event","dataLines","line","split","startsWith","trim","push","replace","length","data","join","drain","out","gen","next","done","value","framesFrom","chunks","options","status","leftover","chunk","truncated","readSse","response","signal","body","getReader","text","reader","decoder","TextDecoder","finished","aborted","Promise","_resolve","reject","fail","err","Error","name","addEventListener","once","undefined","catch","read","race","decode","stream","resolve","cancel","releaseLock","nonStreamProblem","type","headers","get","lowered","toLowerCase","includes","detail","errorBody","truncatedMessage","unparseableMessage","args","stopReason","tail"],"sourceRoot":"../../../src","sources":["providers/sse.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DEFAULT_IDLE_TIMEOUT_MS = exports.DEFAULT_CONNECT_TIMEOUT_MS = void 0;
7
+ exports.createStreamTimer = createStreamTimer;
8
+ /**
9
+ * The clock on a model request.
10
+ *
11
+ * There was none. A gateway that accepted the socket and then said nothing —
12
+ * an overloaded proxy, a dropped VPN, a laptop that slept mid-answer — left
13
+ * the turn running with the thinking strip animating until a person pressed
14
+ * Stop. The 180s turn deadline did not help: it is read at the TOP of a step
15
+ * (`runAgentTurn`), and a step parked inside `await fetch(...)` never reaches
16
+ * the next one.
17
+ *
18
+ * Two clocks, because the two silences mean different things:
19
+ *
20
+ * - CONNECT covers "no headers yet". Nothing has been generated, so nothing is
21
+ * lost by giving up; 30s is already long for a gateway to acknowledge a POST.
22
+ * - IDLE covers "headers arrived, then nothing". This one has to be generous.
23
+ * Anthropic sends `ping` frames, but an OpenAI-protocol reasoning model can
24
+ * legitimately emit nothing for a long stretch while it thinks, and cutting
25
+ * that off would look like a broken product. Any frame at all — a keepalive
26
+ * comment included — resets it, so only total silence trips it.
27
+ *
28
+ * A timeout is NOT a retry. Nothing is re-sent: the request may have reached
29
+ * the model, and a duplicate turn is a duplicate bill and possibly duplicate
30
+ * writes. The turn ends with an honest notice and a Continue button.
31
+ */
32
+
33
+ const DEFAULT_CONNECT_TIMEOUT_MS = exports.DEFAULT_CONNECT_TIMEOUT_MS = 30_000;
34
+ const DEFAULT_IDLE_TIMEOUT_MS = exports.DEFAULT_IDLE_TIMEOUT_MS = 90_000;
35
+ /**
36
+ * A timer over an optional caller signal.
37
+ *
38
+ * When no `AbortController` exists (a runtime old enough to lack it) this
39
+ * degrades to passing the caller's signal straight through with no clocks,
40
+ * rather than failing to send anything at all.
41
+ */
42
+ function createStreamTimer(callerSignal, options = {}) {
43
+ const connectMs = options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
44
+ const idleMs = options.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
45
+ const Controller = typeof AbortController === "function" ? AbortController : undefined;
46
+ if (!Controller) {
47
+ return {
48
+ signal: callerSignal,
49
+ connected() {},
50
+ activity() {},
51
+ expired: undefined,
52
+ message: () => undefined,
53
+ dispose() {}
54
+ };
55
+ }
56
+ const controller = new Controller();
57
+ let expired;
58
+ let handle;
59
+ let disposed = false;
60
+ const clear = () => {
61
+ if (handle !== undefined) {
62
+ clearTimeout(handle);
63
+ handle = undefined;
64
+ }
65
+ };
66
+ const arm = (ms, which) => {
67
+ clear();
68
+ if (disposed || !Number.isFinite(ms) || ms <= 0) return;
69
+ handle = setTimeout(() => {
70
+ handle = undefined;
71
+ expired = which;
72
+ // The abort is what actually unblocks `fetch` / `reader.read()`. The
73
+ // reason is tracked here rather than read back off the signal because
74
+ // `AbortSignal.reason` is not reliably present on React Native.
75
+ try {
76
+ controller.abort();
77
+ } catch {
78
+ /* already aborted */
79
+ }
80
+ }, ms);
81
+ };
82
+ const onCallerAbort = () => {
83
+ clear();
84
+ try {
85
+ controller.abort();
86
+ } catch {
87
+ /* already aborted */
88
+ }
89
+ };
90
+ if (callerSignal) {
91
+ if (callerSignal.aborted) onCallerAbort();else callerSignal.addEventListener?.("abort", onCallerAbort);
92
+ }
93
+ arm(connectMs, "connect");
94
+ return {
95
+ signal: controller.signal,
96
+ connected() {
97
+ arm(idleMs, "idle");
98
+ },
99
+ activity() {
100
+ // Only rearm a clock that is already running: a provider that reports
101
+ // activity after `dispose` must not resurrect the timer.
102
+ if (!disposed) arm(idleMs, "idle");
103
+ },
104
+ get expired() {
105
+ return expired;
106
+ },
107
+ message() {
108
+ if (expired === "connect") {
109
+ return `The model endpoint did not respond within ${Math.round(connectMs / 1000)}s. Nothing was generated, and nothing was re-sent.`;
110
+ }
111
+ if (expired === "idle") {
112
+ return `The model endpoint stopped sending after ${Math.round(idleMs / 1000)}s of silence. Whatever arrived is above; nothing was re-sent.`;
113
+ }
114
+ return undefined;
115
+ },
116
+ dispose() {
117
+ disposed = true;
118
+ clear();
119
+ callerSignal?.removeEventListener?.("abort", onCallerAbort);
120
+ }
121
+ };
122
+ }
123
+ //# sourceMappingURL=streamTimer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DEFAULT_CONNECT_TIMEOUT_MS","exports","DEFAULT_IDLE_TIMEOUT_MS","createStreamTimer","callerSignal","options","connectMs","connectTimeoutMs","idleMs","idleTimeoutMs","Controller","AbortController","undefined","signal","connected","activity","expired","message","dispose","controller","handle","disposed","clear","clearTimeout","arm","ms","which","Number","isFinite","setTimeout","abort","onCallerAbort","aborted","addEventListener","Math","round","removeEventListener"],"sourceRoot":"../../../src","sources":["providers/streamTimer.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createTransport = createTransport;
7
+ var _sse = require("./sse");
8
+ var _xhrStream = require("./xhrStream");
9
+ var _problem = require("./problem");
10
+ /**
11
+ * How a request is SENT, decided before it is sent.
12
+ *
13
+ * The obvious place to add XHR was inside `readSse`, once a missing
14
+ * `response.body` had already proved that `fetch` could not stream. That is
15
+ * the wrong boundary and would have been a real bug: the POST has already
16
+ * happened by then, the reader has neither the URL nor the headers nor the
17
+ * body to repeat it, and issuing a second one would ask the model to generate
18
+ * the same answer twice — billed twice, and for a turn that writes, acted on
19
+ * twice. Transport is chosen up front; a response that has started is consumed
20
+ * exactly once, whatever it turns out to be.
21
+ *
22
+ * `auto` therefore learns rather than probes. The first request goes through
23
+ * `fetch`; if that response has no reader, the answer is buffered (as it
24
+ * always was on that runtime) and the SESSION remembers, so every later
25
+ * request uses XHR and streams. One buffered reply at the start of a bare-RN
26
+ * session, and nothing to configure.
27
+ */
28
+
29
+ const EMPTY = async function* () {};
30
+
31
+ /**
32
+ * One transport per provider instance, because the `auto` decision is worth
33
+ * remembering: re-learning it would buffer the first reply of every turn.
34
+ */
35
+ function createTransport(config) {
36
+ const requested = config.transport ?? "auto";
37
+ /**
38
+ * Set once a `fetch` response has come back with no reader. Only ever
39
+ * flipped one way: a runtime does not gain streaming mid-session.
40
+ */
41
+ let fetchCannotStream = false;
42
+ const useXhr = () => {
43
+ // A host-supplied `fetch` is never bypassed. It is how a harness keeps
44
+ // model traffic off the global (and out of the network interceptor), and
45
+ // routing around it would defeat the reason it was passed in.
46
+ if (config.fetch) return requested === "xhr" && (0, _xhrStream.xhrAvailable)();
47
+ if (requested === "xhr") return (0, _xhrStream.xhrAvailable)();
48
+ if (requested === "fetch") return false;
49
+ return fetchCannotStream && (0, _xhrStream.xhrAvailable)();
50
+ };
51
+ return {
52
+ async open(req) {
53
+ if (useXhr()) {
54
+ const response = await (0, _xhrStream.xhrStream)({
55
+ url: config.endpoint,
56
+ headers: req.headers,
57
+ body: req.body,
58
+ signal: req.signal
59
+ });
60
+ if (!response.ok) {
61
+ const detail = (await response.text()).slice(0, 600);
62
+ return {
63
+ problem: `HTTP ${response.status}${detail ? ` — ${detail}` : ""}`,
64
+ problemInfo: (0, _problem.classifyProblem)({
65
+ status: response.status,
66
+ type: (0, _problem.errorTypeOf)(detail),
67
+ message: detail,
68
+ retryAfter: response.retryAfter
69
+ }),
70
+ frames: EMPTY
71
+ };
72
+ }
73
+ const type = response.contentType.toLowerCase();
74
+ if (type && !type.includes("event-stream")) {
75
+ const detail = (await response.text()).slice(0, 600);
76
+ return {
77
+ problem: type.includes("json") ? `The endpoint answered with JSON instead of a stream — it may not support "stream": true.${detail ? ` — ${detail}` : ""}` : `The endpoint answered with ${response.contentType} instead of an event stream.${detail ? ` — ${detail}` : ""}`,
78
+ frames: EMPTY
79
+ };
80
+ }
81
+ return {
82
+ frames: options => response.frames(options)
83
+ };
84
+ }
85
+ const response = await (config.fetch ?? fetch)(config.endpoint, {
86
+ method: "POST",
87
+ headers: req.headers,
88
+ signal: req.signal,
89
+ body: req.body
90
+ });
91
+ if (!response.ok) {
92
+ const detail = await (0, _sse.errorBody)(response);
93
+ return {
94
+ problem: `HTTP ${response.status}${detail ? ` — ${detail}` : ""}`,
95
+ problemInfo: (0, _problem.classifyProblem)({
96
+ status: response.status,
97
+ type: (0, _problem.errorTypeOf)(detail),
98
+ message: detail,
99
+ retryAfter: response.headers?.get?.("retry-after") ?? null
100
+ }),
101
+ frames: EMPTY
102
+ };
103
+ }
104
+ const problem = await (0, _sse.nonStreamProblem)(response);
105
+ if (problem) return {
106
+ problem,
107
+ frames: EMPTY
108
+ };
109
+
110
+ // Learn, for the NEXT request. This one is already in flight and is read
111
+ // through the buffered path — re-sending it is what this file exists to
112
+ // avoid.
113
+ const body = response.body;
114
+ if ((!body || typeof body.getReader !== "function") && !config.fetch) {
115
+ fetchCannotStream = true;
116
+ }
117
+ return {
118
+ frames: options => (0, _sse.readSse)(response, options)
119
+ };
120
+ }
121
+ };
122
+ }
123
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_sse","require","_xhrStream","_problem","EMPTY","createTransport","config","requested","transport","fetchCannotStream","useXhr","fetch","xhrAvailable","open","req","response","xhrStream","url","endpoint","headers","body","signal","ok","detail","text","slice","problem","status","problemInfo","classifyProblem","type","errorTypeOf","message","retryAfter","frames","contentType","toLowerCase","includes","options","method","errorBody","get","nonStreamProblem","getReader","readSse"],"sourceRoot":"../../../src","sources":["providers/transport.ts"],"mappings":"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","ignoreList":[]}