@fgv/ts-extras 5.1.0-33 → 5.1.0-34

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 (77) hide show
  1. package/dist/packlets/ai-assist/apiClient.js +4 -4
  2. package/dist/packlets/ai-assist/apiClient.js.map +1 -1
  3. package/dist/packlets/ai-assist/chatRequestBuilders.js +86 -3
  4. package/dist/packlets/ai-assist/chatRequestBuilders.js.map +1 -1
  5. package/dist/packlets/ai-assist/converters.js +31 -1
  6. package/dist/packlets/ai-assist/converters.js.map +1 -1
  7. package/dist/packlets/ai-assist/index.js +3 -2
  8. package/dist/packlets/ai-assist/index.js.map +1 -1
  9. package/dist/packlets/ai-assist/model.js.map +1 -1
  10. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js +176 -32
  11. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -1
  12. package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +511 -0
  13. package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -0
  14. package/dist/packlets/ai-assist/streamingAdapters/common.js +95 -0
  15. package/dist/packlets/ai-assist/streamingAdapters/common.js.map +1 -1
  16. package/dist/packlets/ai-assist/streamingAdapters/gemini.js +34 -10
  17. package/dist/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -1
  18. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js +215 -15
  19. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -1
  20. package/dist/packlets/ai-assist/streamingClient.js +18 -0
  21. package/dist/packlets/ai-assist/streamingClient.js.map +1 -1
  22. package/dist/packlets/ai-assist/thinkingOptionsResolver.js +23 -0
  23. package/dist/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -1
  24. package/dist/packlets/ai-assist/toolFormats.js +106 -10
  25. package/dist/packlets/ai-assist/toolFormats.js.map +1 -1
  26. package/dist/ts-extras.d.ts +339 -3
  27. package/lib/packlets/ai-assist/apiClient.d.ts.map +1 -1
  28. package/lib/packlets/ai-assist/apiClient.js +3 -3
  29. package/lib/packlets/ai-assist/apiClient.js.map +1 -1
  30. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts +29 -5
  31. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts.map +1 -1
  32. package/lib/packlets/ai-assist/chatRequestBuilders.js +86 -3
  33. package/lib/packlets/ai-assist/chatRequestBuilders.js.map +1 -1
  34. package/lib/packlets/ai-assist/converters.d.ts +9 -1
  35. package/lib/packlets/ai-assist/converters.d.ts.map +1 -1
  36. package/lib/packlets/ai-assist/converters.js +31 -1
  37. package/lib/packlets/ai-assist/converters.js.map +1 -1
  38. package/lib/packlets/ai-assist/index.d.ts +4 -3
  39. package/lib/packlets/ai-assist/index.d.ts.map +1 -1
  40. package/lib/packlets/ai-assist/index.js +5 -1
  41. package/lib/packlets/ai-assist/index.js.map +1 -1
  42. package/lib/packlets/ai-assist/model.d.ts +183 -3
  43. package/lib/packlets/ai-assist/model.d.ts.map +1 -1
  44. package/lib/packlets/ai-assist/model.js.map +1 -1
  45. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts +58 -5
  46. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts.map +1 -1
  47. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js +175 -31
  48. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -1
  49. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts +158 -0
  50. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts.map +1 -0
  51. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +517 -0
  52. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -0
  53. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts +51 -0
  54. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts.map +1 -1
  55. package/lib/packlets/ai-assist/streamingAdapters/common.js +97 -0
  56. package/lib/packlets/ai-assist/streamingAdapters/common.js.map +1 -1
  57. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts +16 -2
  58. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts.map +1 -1
  59. package/lib/packlets/ai-assist/streamingAdapters/gemini.js +34 -10
  60. package/lib/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -1
  61. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts +15 -2
  62. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts.map +1 -1
  63. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js +214 -14
  64. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -1
  65. package/lib/packlets/ai-assist/streamingClient.d.ts +17 -0
  66. package/lib/packlets/ai-assist/streamingClient.d.ts.map +1 -1
  67. package/lib/packlets/ai-assist/streamingClient.js +20 -1
  68. package/lib/packlets/ai-assist/streamingClient.js.map +1 -1
  69. package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts +18 -2
  70. package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts.map +1 -1
  71. package/lib/packlets/ai-assist/thinkingOptionsResolver.js +24 -0
  72. package/lib/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -1
  73. package/lib/packlets/ai-assist/toolFormats.d.ts +40 -9
  74. package/lib/packlets/ai-assist/toolFormats.d.ts.map +1 -1
  75. package/lib/packlets/ai-assist/toolFormats.js +107 -10
  76. package/lib/packlets/ai-assist/toolFormats.js.map +1 -1
  77. package/package.json +7 -7
@@ -41,9 +41,14 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
42
  exports.callAnthropicStream = callAnthropicStream;
43
43
  /**
44
- * Streaming adapter for the Anthropic Messages API. Surfaces server tool
45
- * use (e.g. `web_search`) as unified `tool-event` markers based on the
46
- * `content_block_start` / `content_block_stop` lifecycle.
44
+ * Streaming adapter for the Anthropic Messages API. Handles server tool
45
+ * use (e.g. `web_search`) as unified `tool-event` markers and client-defined
46
+ * tool calls (type `tool_use`) with B4 thinking-block accumulation.
47
+ *
48
+ * The ordered accumulation buffer preserves all content blocks from the
49
+ * assistant turn in their original stream positions. The C3 continuation
50
+ * builder reads this buffer to reconstruct the assistant turn for the
51
+ * follow-up request.
47
52
  *
48
53
  * @packageDocumentation
49
54
  */
@@ -51,21 +56,30 @@ const ts_utils_1 = require("@fgv/ts-utils");
51
56
  const chatRequestBuilders_1 = require("../chatRequestBuilders");
52
57
  const sseParser_1 = require("../sseParser");
53
58
  const toolFormats_1 = require("../toolFormats");
59
+ const thinkingOptionsResolver_1 = require("../thinkingOptionsResolver");
54
60
  const common_1 = require("./common");
55
61
  const anthropicContentBlockInner = ts_utils_1.Validators.object({
56
62
  type: ts_utils_1.Validators.string.optional(),
57
- name: ts_utils_1.Validators.string.optional()
58
- }, { options: { optionalFields: ['type', 'name'] } });
63
+ name: ts_utils_1.Validators.string.optional(),
64
+ id: ts_utils_1.Validators.string.optional(),
65
+ data: ts_utils_1.Validators.string.optional()
66
+ }, { options: { optionalFields: ['type', 'name', 'id', 'data'] } });
59
67
  const anthropicContentBlockStartPayload = ts_utils_1.Validators.object({
68
+ index: ts_utils_1.Validators.number.optional(),
60
69
  content_block: anthropicContentBlockInner
61
- });
70
+ }, { options: { optionalFields: ['index'] } });
62
71
  const anthropicContentBlockDeltaInner = ts_utils_1.Validators.object({
63
72
  type: ts_utils_1.Validators.string.optional(),
64
- text: ts_utils_1.Validators.string.optional()
65
- }, { options: { optionalFields: ['type', 'text'] } });
73
+ text: ts_utils_1.Validators.string.optional(),
74
+ partial_json: ts_utils_1.Validators.string.optional(),
75
+ thinking: ts_utils_1.Validators.string.optional(),
76
+ signature: ts_utils_1.Validators.string.optional()
77
+ }, { options: { optionalFields: ['type', 'text', 'partial_json', 'thinking', 'signature'] } });
66
78
  const anthropicContentBlockDeltaPayload = ts_utils_1.Validators.object({
79
+ index: ts_utils_1.Validators.number.optional(),
67
80
  delta: anthropicContentBlockDeltaInner
68
- });
81
+ }, { options: { optionalFields: ['index'] } });
82
+ const anthropicContentBlockStopPayload = ts_utils_1.Validators.object({ index: ts_utils_1.Validators.number.optional() }, { options: { optionalFields: ['index'] } });
69
83
  const anthropicMessageDeltaInner = ts_utils_1.Validators.object({ stop_reason: ts_utils_1.Validators.string.optional() }, { options: { optionalFields: ['stop_reason'] } });
70
84
  const anthropicMessageDeltaPayload = ts_utils_1.Validators.object({
71
85
  delta: anthropicMessageDeltaInner
@@ -75,50 +89,160 @@ const anthropicErrorPayload = ts_utils_1.Validators.object({ error: anthropicErr
75
89
  // ============================================================================
76
90
  // Stream translator
77
91
  // ============================================================================
92
+ /**
93
+ * Recognized Anthropic Messages API SSE event names. Anything not in this set surfaces a
94
+ * one-time `logger.warn` per stream — same rationale as the OpenAI Responses adapter's
95
+ * `RECOGNIZED_OPENAI_RESPONSES_EVENTS` allowlist in `openaiResponses.ts`. Add to this set
96
+ * when a new event type is observed and confirmed safe to ignore.
97
+ *
98
+ * @internal
99
+ */
100
+ const RECOGNIZED_ANTHROPIC_EVENTS = new Set([
101
+ // ---- handled by the translator ----
102
+ 'content_block_start',
103
+ 'content_block_delta',
104
+ 'content_block_stop',
105
+ 'message_delta',
106
+ 'message_stop',
107
+ 'error',
108
+ // ---- lifecycle / heartbeats: intentionally silent ----
109
+ 'message_start',
110
+ 'ping'
111
+ ]);
78
112
  /**
79
113
  * Translates an Anthropic Messages API SSE stream into unified events.
80
114
  *
115
+ * Maintains an ordered accumulation buffer (keyed by SSE `index`) for all
116
+ * content blocks: `thinking`, `redacted_thinking`, `text`, and `tool_use`.
117
+ * The buffer is available on the returned generator via `.accumulationBuffer`.
118
+ *
119
+ * Unrecognized event names are reported once per stream via `logger?.warn` —
120
+ * see {@link RECOGNIZED_ANTHROPIC_EVENTS}.
121
+ *
81
122
  * @internal
82
123
  */
83
- function translateAnthropicStream(response) {
124
+ function translateAnthropicStream(response, accumulationBuffer, logger) {
84
125
  return __asyncGenerator(this, arguments, function* translateAnthropicStream_1() {
85
126
  var _a, e_1, _b, _c;
86
- var _d, _e;
127
+ var _d, _e, _f, _g;
87
128
  let fullText = '';
88
129
  let truncated = false;
89
130
  let stopped = false;
131
+ // Track unrecognized event names we have already warned about, so a hot stream of
132
+ // an unknown event type produces exactly one log line per name per stream.
133
+ const warnedEvents = new Set();
90
134
  try {
91
135
  /* c8 ignore next - body is non-null at this point per openSseConnection */
92
136
  if (!response.body)
93
137
  return yield __await(void 0);
94
138
  try {
95
- for (var _f = true, _g = __asyncValues((0, sseParser_1.readSseEvents)(response.body)), _h; _h = yield __await(_g.next()), _a = _h.done, !_a; _f = true) {
96
- _c = _h.value;
97
- _f = false;
139
+ for (var _h = true, _j = __asyncValues((0, sseParser_1.readSseEvents)(response.body)), _k; _k = yield __await(_j.next()), _a = _k.done, !_a; _h = true) {
140
+ _c = _k.value;
141
+ _h = false;
98
142
  const message = _c;
99
143
  const eventName = message.event;
100
144
  if (eventName === 'content_block_start') {
101
145
  const payload = (0, common_1.validateEventPayload)((0, sseParser_1.parseSseEventJson)(message.data), anthropicContentBlockStartPayload);
102
- /* c8 ignore next 6 - defensive: block?.type optional chaining null branches are unreachable */
103
- const block = payload === null || payload === void 0 ? void 0 : payload.content_block;
104
- if ((block === null || block === void 0 ? void 0 : block.type) === 'server_tool_use' && block.name === 'web_search') {
146
+ /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */
147
+ if (!payload)
148
+ continue;
149
+ const { index: rawIndex, content_block: block } = payload;
150
+ const index = rawIndex !== null && rawIndex !== void 0 ? rawIndex : 0;
151
+ if (block.type === 'thinking') {
152
+ accumulationBuffer.set(index, { type: 'thinking', thinking: '', signature: '' });
153
+ }
154
+ else if (block.type === 'redacted_thinking') {
155
+ accumulationBuffer.set(index, {
156
+ type: 'redacted_thinking',
157
+ /* c8 ignore next 1 - defensive: Anthropic always provides data for redacted_thinking */
158
+ data: (_d = block.data) !== null && _d !== void 0 ? _d : ''
159
+ });
160
+ }
161
+ else if (block.type === 'text') {
162
+ accumulationBuffer.set(index, { type: 'text', text: '' });
163
+ }
164
+ else if (block.type === 'tool_use' && block.id && block.name) {
165
+ accumulationBuffer.set(index, {
166
+ type: 'tool_use',
167
+ id: block.id,
168
+ name: block.name,
169
+ argsBuffer: ''
170
+ });
171
+ yield yield __await({ type: 'client-tool-call-start', toolName: block.name, callId: block.id });
172
+ }
173
+ else if (block.type === 'server_tool_use' && block.name === 'web_search') {
105
174
  yield yield __await({ type: 'tool-event', toolType: 'web_search', phase: 'started' });
106
175
  }
107
- else if ((block === null || block === void 0 ? void 0 : block.type) === 'web_search_tool_result') {
176
+ else if (block.type === 'web_search_tool_result') {
108
177
  yield yield __await({ type: 'tool-event', toolType: 'web_search', phase: 'completed' });
109
178
  }
110
179
  }
111
180
  else if (eventName === 'content_block_delta') {
112
181
  const payload = (0, common_1.validateEventPayload)((0, sseParser_1.parseSseEventJson)(message.data), anthropicContentBlockDeltaPayload);
113
- /* c8 ignore next 1 - defensive: payload?.delta.type null branch unreachable after validation */
114
- if ((payload === null || payload === void 0 ? void 0 : payload.delta.type) === 'text_delta' && typeof payload.delta.text === 'string') {
115
- const delta = payload.delta.text;
116
- if (delta.length > 0) {
117
- fullText += delta;
118
- yield yield __await({ type: 'text-delta', delta });
182
+ /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */
183
+ if (!payload)
184
+ continue;
185
+ const { index: rawDeltaIndex, delta } = payload;
186
+ const index = rawDeltaIndex !== null && rawDeltaIndex !== void 0 ? rawDeltaIndex : 0;
187
+ const block = accumulationBuffer.get(index);
188
+ if (delta.type === 'text_delta' && typeof delta.text === 'string') {
189
+ /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */
190
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'text') {
191
+ block.text += delta.text;
192
+ }
193
+ if (delta.text.length > 0) {
194
+ fullText += delta.text;
195
+ yield yield __await({ type: 'text-delta', delta: delta.text });
196
+ }
197
+ }
198
+ else if (delta.type === 'input_json_delta' && typeof delta.partial_json === 'string') {
199
+ /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */
200
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'tool_use') {
201
+ block.argsBuffer += delta.partial_json;
202
+ }
203
+ }
204
+ else if (delta.type === 'thinking_delta' && typeof delta.thinking === 'string') {
205
+ /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */
206
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'thinking') {
207
+ block.thinking += delta.thinking;
208
+ }
209
+ }
210
+ else if (delta.type === 'signature_delta' && typeof delta.signature === 'string') {
211
+ // CRITICAL (E5): signature must be APPENDED, not overwritten.
212
+ // The signature is base64 arriving in multiple chunks.
213
+ // Overwriting produces a truncated signature that Anthropic rejects with HTTP 400.
214
+ /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */
215
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'thinking') {
216
+ block.signature += delta.signature;
119
217
  }
120
218
  }
121
219
  }
220
+ else if (eventName === 'content_block_stop') {
221
+ const payload = (0, common_1.validateEventPayload)((0, sseParser_1.parseSseEventJson)(message.data), anthropicContentBlockStopPayload);
222
+ /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */
223
+ if (!payload)
224
+ continue;
225
+ /* c8 ignore next 1 - defensive: payload.index ?? 0 null branch is unreachable */
226
+ const block = accumulationBuffer.get((_e = payload.index) !== null && _e !== void 0 ? _e : 0);
227
+ /* c8 ignore next 1 - defensive: block always exists when block_stop follows block_start */
228
+ if ((block === null || block === void 0 ? void 0 : block.type) === 'tool_use') {
229
+ let args;
230
+ try {
231
+ /* c8 ignore next 1 - defensive: argsBuffer || '{}' empty-string branch unreachable in tests */
232
+ const parsed = JSON.parse(block.argsBuffer || '{}');
233
+ /* c8 ignore start - defensive: non-object/malformed parse defaults to empty object */
234
+ args =
235
+ parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)
236
+ ? parsed
237
+ : {};
238
+ }
239
+ catch (_l) {
240
+ args = {};
241
+ }
242
+ /* c8 ignore stop */
243
+ yield yield __await({ type: 'client-tool-call-done', toolName: block.name, callId: block.id, args });
244
+ }
245
+ }
122
246
  else if (eventName === 'message_delta') {
123
247
  const payload = (0, common_1.validateEventPayload)((0, sseParser_1.parseSseEventJson)(message.data), anthropicMessageDeltaPayload);
124
248
  /* c8 ignore next 1 - defensive: payload?.delta null branch unreachable after validation */
@@ -134,16 +258,30 @@ function translateAnthropicStream(response) {
134
258
  yield yield __await({
135
259
  type: 'error',
136
260
  /* c8 ignore next 1 - defensive: payload?.error null branch unreachable after validation */
137
- message: (_e = (_d = payload === null || payload === void 0 ? void 0 : payload.error) === null || _d === void 0 ? void 0 : _d.message) !== null && _e !== void 0 ? _e : 'Anthropic stream returned an error event'
261
+ message: (_g = (_f = payload === null || payload === void 0 ? void 0 : payload.error) === null || _f === void 0 ? void 0 : _f.message) !== null && _g !== void 0 ? _g : 'Anthropic stream returned an error event'
138
262
  });
139
263
  return yield __await(void 0);
140
264
  }
265
+ else if (typeof eventName === 'string' &&
266
+ !RECOGNIZED_ANTHROPIC_EVENTS.has(eventName) &&
267
+ !warnedEvents.has(eventName)) {
268
+ // Empirical drift instrument: an unrecognized Anthropic event surfaces as a one-time
269
+ // warning per stream. Update RECOGNIZED_ANTHROPIC_EVENTS once the new event is either
270
+ // handled or confirmed safe to ignore.
271
+ warnedEvents.add(eventName);
272
+ logger === null || logger === void 0 ? void 0 : logger.warn(`${common_1.UNRECOGNIZED_EVENT_WARN_TAG} Anthropic streaming adapter: unrecognized SSE event ` +
273
+ `'${eventName}'. ` +
274
+ `payload preview: ${(0, common_1.formatUnrecognizedEventPayloadPreview)(message.data)}. ` +
275
+ `This may indicate provider drift — if the new event carries data the adapter ` +
276
+ `should surface, add a handler; otherwise add the name to ` +
277
+ `RECOGNIZED_ANTHROPIC_EVENTS.`);
278
+ }
141
279
  }
142
280
  }
143
281
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
144
282
  finally {
145
283
  try {
146
- if (!_f && !_a && (_b = _g.return)) yield __await(_b.call(_g));
284
+ if (!_h && !_a && (_b = _j.return)) yield __await(_b.call(_j));
147
285
  }
148
286
  finally { if (e_1) throw e_1.error; }
149
287
  }
@@ -169,14 +307,19 @@ function translateAnthropicStream(response) {
169
307
  *
170
308
  * @internal
171
309
  */
172
- async function callAnthropicStream(config, prompt, messagesBefore, temperature, tools, logger, signal, resolvedThinking) {
310
+ async function callAnthropicStream(config, prompt, messagesBefore, temperature, tools, logger, signal, resolvedThinking, accumulationBuffer, continuationMessages) {
173
311
  const url = `${config.baseUrl}/messages`;
174
- const messages = (0, chatRequestBuilders_1.buildAnthropicMessages)(prompt, { head: messagesBefore });
312
+ const messages = (0, chatRequestBuilders_1.buildAnthropicMessages)(prompt, {
313
+ head: messagesBefore,
314
+ rawTail: continuationMessages
315
+ });
175
316
  // When thinking is active, temperature is rejected by Anthropic (validated upstream).
176
317
  const body = Object.assign(Object.assign({ model: config.model, system: prompt.system, messages, max_tokens: 4096 }, ((resolvedThinking === null || resolvedThinking === void 0 ? void 0 : resolvedThinking.anthropicEffort) === undefined ? { temperature } : {})), { stream: true });
177
318
  if ((resolvedThinking === null || resolvedThinking === void 0 ? void 0 : resolvedThinking.anthropicEffort) !== undefined) {
178
- body.thinking = { type: 'enabled' };
179
- body.output_config = { effort: resolvedThinking.anthropicEffort };
319
+ body.thinking = {
320
+ type: 'enabled',
321
+ budget_tokens: (0, thinkingOptionsResolver_1.anthropicEffortToBudgetTokens)(resolvedThinking.anthropicEffort)
322
+ };
180
323
  }
181
324
  if ((resolvedThinking === null || resolvedThinking === void 0 ? void 0 : resolvedThinking.otherParams) !== undefined) {
182
325
  Object.assign(body, resolvedThinking.otherParams);
@@ -194,7 +337,8 @@ async function callAnthropicStream(config, prompt, messagesBefore, temperature,
194
337
  const toolTypes = tools && tools.length > 0 ? tools.map((t) => t.type).join(',') : 'none';
195
338
  logger.info(`Anthropic streaming: model=${config.model}, tools=${toolTypes}`);
196
339
  }
340
+ const buffer = accumulationBuffer !== null && accumulationBuffer !== void 0 ? accumulationBuffer : new Map();
197
341
  const conn = await (0, common_1.openSseConnection)(url, headers, body, logger, signal);
198
- return conn.onSuccess((response) => (0, ts_utils_1.succeed)(translateAnthropicStream(response)));
342
+ return conn.onSuccess((response) => (0, ts_utils_1.succeed)(translateAnthropicStream(response, buffer, logger)));
199
343
  }
200
344
  //# sourceMappingURL=anthropic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Streaming adapter for the Anthropic Messages API. Surfaces server tool\n * use (e.g. `web_search`) as unified `tool-event` markers based on the\n * `content_block_start` / `content_block_stop` lifecycle.\n *\n * @packageDocumentation\n */\n\nimport { type Logging, Result, succeed, type Validator, Validators } from '@fgv/ts-utils';\n\nimport { buildAnthropicMessages } from '../chatRequestBuilders';\nimport { AiPrompt, type AiServerToolConfig, type IAiStreamEvent, type IChatMessage } from '../model';\nimport { parseSseEventJson, readSseEvents } from '../sseParser';\nimport { toAnthropicTools } from '../toolFormats';\nimport { type IResolvedThinkingConfig } from '../thinkingOptionsResolver';\nimport { IStreamApiConfig, openSseConnection, validateEventPayload } from './common';\n\n// ============================================================================\n// Event payload shapes\n// ============================================================================\n\n/**\n * Payload of a `content_block_start` SSE event. The `type` discriminator\n * tells us whether the block is text, a server-tool invocation, or a\n * tool result.\n *\n * @internal\n */\ninterface IAnthropicContentBlockStartPayload {\n readonly content_block: { readonly type?: string; readonly name?: string };\n}\n\n/**\n * Payload of a `content_block_delta` SSE event. The inner `delta.type`\n * discriminator is `text_delta` for the text we care about; other values\n * (e.g. `input_json_delta` for tool args) are ignored.\n *\n * @internal\n */\ninterface IAnthropicContentBlockDeltaPayload {\n readonly delta: { readonly type?: string; readonly text?: string };\n}\n\n/**\n * Payload of a `message_delta` SSE event carrying the final stop reason.\n *\n * @internal\n */\ninterface IAnthropicMessageDeltaPayload {\n readonly delta: { readonly stop_reason?: string };\n}\n\n/**\n * Payload of an `error` SSE event.\n *\n * @internal\n */\ninterface IAnthropicErrorPayload {\n readonly error?: { readonly message?: string };\n}\n\nconst anthropicContentBlockInner: Validator<{ type?: string; name?: string }> = Validators.object<{\n type?: string;\n name?: string;\n}>(\n {\n type: Validators.string.optional(),\n name: Validators.string.optional()\n },\n { options: { optionalFields: ['type', 'name'] } }\n);\n\nconst anthropicContentBlockStartPayload: Validator<IAnthropicContentBlockStartPayload> =\n Validators.object<IAnthropicContentBlockStartPayload>({\n content_block: anthropicContentBlockInner\n });\n\nconst anthropicContentBlockDeltaInner: Validator<{ type?: string; text?: string }> = Validators.object<{\n type?: string;\n text?: string;\n}>(\n {\n type: Validators.string.optional(),\n text: Validators.string.optional()\n },\n { options: { optionalFields: ['type', 'text'] } }\n);\n\nconst anthropicContentBlockDeltaPayload: Validator<IAnthropicContentBlockDeltaPayload> =\n Validators.object<IAnthropicContentBlockDeltaPayload>({\n delta: anthropicContentBlockDeltaInner\n });\n\nconst anthropicMessageDeltaInner: Validator<{ stop_reason?: string }> = Validators.object<{\n stop_reason?: string;\n}>({ stop_reason: Validators.string.optional() }, { options: { optionalFields: ['stop_reason'] } });\n\nconst anthropicMessageDeltaPayload: Validator<IAnthropicMessageDeltaPayload> =\n Validators.object<IAnthropicMessageDeltaPayload>({\n delta: anthropicMessageDeltaInner\n });\n\nconst anthropicErrorInner: Validator<{ message?: string }> = Validators.object<{ message?: string }>(\n { message: Validators.string.optional() },\n { options: { optionalFields: ['message'] } }\n);\n\nconst anthropicErrorPayload: Validator<IAnthropicErrorPayload> = Validators.object<IAnthropicErrorPayload>(\n { error: anthropicErrorInner.optional() },\n { options: { optionalFields: ['error'] } }\n);\n\n// ============================================================================\n// Stream translator\n// ============================================================================\n\n/**\n * Translates an Anthropic Messages API SSE stream into unified events.\n *\n * @internal\n */\nasync function* translateAnthropicStream(response: Response): AsyncGenerator<IAiStreamEvent> {\n let fullText = '';\n let truncated = false;\n let stopped = false;\n\n try {\n /* c8 ignore next - body is non-null at this point per openSseConnection */\n if (!response.body) return;\n for await (const message of readSseEvents(response.body)) {\n const eventName = message.event;\n if (eventName === 'content_block_start') {\n const payload = validateEventPayload(\n parseSseEventJson(message.data),\n anthropicContentBlockStartPayload\n );\n /* c8 ignore next 6 - defensive: block?.type optional chaining null branches are unreachable */\n const block = payload?.content_block;\n if (block?.type === 'server_tool_use' && block.name === 'web_search') {\n yield { type: 'tool-event', toolType: 'web_search', phase: 'started' };\n } else if (block?.type === 'web_search_tool_result') {\n yield { type: 'tool-event', toolType: 'web_search', phase: 'completed' };\n }\n } else if (eventName === 'content_block_delta') {\n const payload = validateEventPayload(\n parseSseEventJson(message.data),\n anthropicContentBlockDeltaPayload\n );\n /* c8 ignore next 1 - defensive: payload?.delta.type null branch unreachable after validation */\n if (payload?.delta.type === 'text_delta' && typeof payload.delta.text === 'string') {\n const delta = payload.delta.text;\n if (delta.length > 0) {\n fullText += delta;\n yield { type: 'text-delta', delta };\n }\n }\n } else if (eventName === 'message_delta') {\n const payload = validateEventPayload(parseSseEventJson(message.data), anthropicMessageDeltaPayload);\n /* c8 ignore next 1 - defensive: payload?.delta null branch unreachable after validation */\n if (payload?.delta.stop_reason === 'max_tokens') {\n truncated = true;\n }\n } else if (eventName === 'message_stop') {\n stopped = true;\n } else if (eventName === 'error') {\n const payload = validateEventPayload(parseSseEventJson(message.data), anthropicErrorPayload);\n yield {\n type: 'error',\n /* c8 ignore next 1 - defensive: payload?.error null branch unreachable after validation */\n message: payload?.error?.message ?? 'Anthropic stream returned an error event'\n };\n return;\n }\n }\n } catch (err: unknown) /* c8 ignore start - defensive: stream errors are always Error instances */ {\n yield { type: 'error', message: err instanceof Error ? err.message : String(err) };\n return;\n } /* c8 ignore stop */\n\n if (stopped) {\n yield { type: 'done', truncated, fullText };\n } else {\n yield { type: 'error', message: 'Anthropic stream ended without a message_stop event' };\n }\n}\n\n// ============================================================================\n// Per-format request caller\n// ============================================================================\n\n/**\n * Issues a streaming Anthropic Messages request and returns the\n * unified-event iterable on success.\n *\n * @internal\n */\nexport async function callAnthropicStream(\n config: IStreamApiConfig,\n prompt: AiPrompt,\n messagesBefore: ReadonlyArray<IChatMessage> | undefined,\n temperature: number,\n tools: ReadonlyArray<AiServerToolConfig> | undefined,\n logger?: Logging.ILogger,\n signal?: AbortSignal,\n resolvedThinking?: IResolvedThinkingConfig\n): Promise<Result<AsyncIterable<IAiStreamEvent>>> {\n const url = `${config.baseUrl}/messages`;\n const messages = buildAnthropicMessages(prompt, { head: messagesBefore });\n // When thinking is active, temperature is rejected by Anthropic (validated upstream).\n const body: Record<string, unknown> = {\n model: config.model,\n system: prompt.system,\n messages,\n max_tokens: 4096,\n ...(resolvedThinking?.anthropicEffort === undefined ? { temperature } : {}),\n stream: true\n };\n if (resolvedThinking?.anthropicEffort !== undefined) {\n body.thinking = { type: 'enabled' };\n body.output_config = { effort: resolvedThinking.anthropicEffort };\n }\n if (resolvedThinking?.otherParams !== undefined) {\n Object.assign(body, resolvedThinking.otherParams);\n }\n if (tools && tools.length > 0) {\n body.tools = toAnthropicTools(tools);\n }\n const headers: Record<string, string> = {\n 'x-api-key': config.apiKey,\n 'anthropic-version': '2023-06-01',\n 'anthropic-dangerous-direct-browser-access': 'true'\n };\n /* c8 ignore next 4 - optional logger diagnostic output */\n if (logger) {\n const toolTypes = tools && tools.length > 0 ? tools.map((t) => t.type).join(',') : 'none';\n logger.info(`Anthropic streaming: model=${config.model}, tools=${toolTypes}`);\n }\n const conn = await openSseConnection(url, headers, body, logger, signal);\n return conn.onSuccess((response) => succeed(translateAnthropicStream(response)));\n}\n"]}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Streaming adapter for the Anthropic Messages API. Handles server tool\n * use (e.g. `web_search`) as unified `tool-event` markers and client-defined\n * tool calls (type `tool_use`) with B4 thinking-block accumulation.\n *\n * The ordered accumulation buffer preserves all content blocks from the\n * assistant turn in their original stream positions. The C3 continuation\n * builder reads this buffer to reconstruct the assistant turn for the\n * follow-up request.\n *\n * @packageDocumentation\n */\n\nimport { type Logging, Result, succeed, type Validator, Validators } from '@fgv/ts-utils';\nimport { type JsonObject } from '@fgv/ts-json-base';\n\nimport { buildAnthropicMessages } from '../chatRequestBuilders';\nimport { AiPrompt, type AiToolConfig, type IAiStreamEvent, type IChatMessage } from '../model';\nimport { parseSseEventJson, readSseEvents } from '../sseParser';\nimport { toAnthropicTools } from '../toolFormats';\nimport { anthropicEffortToBudgetTokens, type IResolvedThinkingConfig } from '../thinkingOptionsResolver';\nimport {\n IStreamApiConfig,\n UNRECOGNIZED_EVENT_WARN_TAG,\n formatUnrecognizedEventPayloadPreview,\n openSseConnection,\n validateEventPayload\n} from './common';\n\n// ============================================================================\n// Accumulated block types (internal — used by C3 continuation builder)\n// ============================================================================\n\n/**\n * An accumulated `thinking` block from the assistant turn. The `thinking` text\n * and `signature` are both concatenated across their respective delta events.\n * The full block is passed to the C3 continuation builder for round-trip preservation.\n * @internal\n */\nexport interface IAccumulatedThinkingBlock {\n readonly type: 'thinking';\n thinking: string;\n signature: string;\n}\n\n/**\n * An accumulated `redacted_thinking` block from the assistant turn. The `data`\n * field is opaque and arrives complete in the `content_block_start` event — no\n * delta events follow. Passed through unmodified to the C3 continuation builder.\n * @internal\n */\nexport interface IAccumulatedRedactedThinkingBlock {\n readonly type: 'redacted_thinking';\n readonly data: string;\n}\n\n/**\n * An accumulated `text` block from the assistant turn.\n * @internal\n */\nexport interface IAccumulatedTextBlock {\n readonly type: 'text';\n text: string;\n}\n\n/**\n * An accumulated `tool_use` block from the assistant turn (client-defined tool call).\n * The `argsBuffer` is the concatenation of all `input_json_delta` chunks.\n * @internal\n */\nexport interface IAccumulatedToolUseBlock {\n readonly type: 'tool_use';\n readonly id: string;\n readonly name: string;\n argsBuffer: string;\n}\n\n/**\n * Discriminated union of all accumulated Anthropic content block types.\n * The ordered accumulation buffer is a `Map<number, IAccumulatedBlock>` keyed\n * by the SSE `index` field from `content_block_start` events.\n * @internal\n */\nexport type IAccumulatedBlock =\n | IAccumulatedThinkingBlock\n | IAccumulatedRedactedThinkingBlock\n | IAccumulatedTextBlock\n | IAccumulatedToolUseBlock;\n\n// ============================================================================\n// Event payload shapes\n// ============================================================================\n\n/**\n * Payload of a `content_block_start` SSE event with the `index` field.\n * The `index` field is optional for backward compatibility with providers that\n * omit it; absent index defaults to 0 in the stream translator.\n * @internal\n */\ninterface IAnthropicContentBlockStartPayload {\n readonly index?: number;\n readonly content_block: {\n readonly type?: string;\n readonly name?: string;\n readonly id?: string;\n readonly data?: string;\n };\n}\n\n/**\n * Payload of a `content_block_delta` SSE event. Various delta types are\n * discriminated on `delta.type`:\n * - `text_delta`: text content\n * - `input_json_delta`: tool argument accumulation\n * - `thinking_delta`: thinking text accumulation\n * - `signature_delta`: thinking signature accumulation (MUST be appended, not overwritten)\n *\n * The `index` field is optional; absent index defaults to 0 in the stream translator.\n * @internal\n */\ninterface IAnthropicContentBlockDeltaPayload {\n readonly index?: number;\n readonly delta: {\n readonly type?: string;\n readonly text?: string;\n readonly partial_json?: string;\n readonly thinking?: string;\n readonly signature?: string;\n };\n}\n\n/**\n * Payload of a `content_block_stop` SSE event.\n * The `index` field is optional; absent index defaults to 0 in the stream translator.\n * @internal\n */\ninterface IAnthropicContentBlockStopPayload {\n readonly index?: number;\n}\n\n/**\n * Payload of a `message_delta` SSE event carrying the final stop reason.\n * @internal\n */\ninterface IAnthropicMessageDeltaPayload {\n readonly delta: { readonly stop_reason?: string };\n}\n\n/**\n * Payload of an `error` SSE event.\n * @internal\n */\ninterface IAnthropicErrorPayload {\n readonly error?: { readonly message?: string };\n}\n\nconst anthropicContentBlockInner: Validator<{\n type?: string;\n name?: string;\n id?: string;\n data?: string;\n}> = Validators.object<{ type?: string; name?: string; id?: string; data?: string }>(\n {\n type: Validators.string.optional(),\n name: Validators.string.optional(),\n id: Validators.string.optional(),\n data: Validators.string.optional()\n },\n { options: { optionalFields: ['type', 'name', 'id', 'data'] } }\n);\n\nconst anthropicContentBlockStartPayload: Validator<IAnthropicContentBlockStartPayload> =\n Validators.object<IAnthropicContentBlockStartPayload>(\n {\n index: Validators.number.optional(),\n content_block: anthropicContentBlockInner\n },\n { options: { optionalFields: ['index'] } }\n );\n\nconst anthropicContentBlockDeltaInner: Validator<{\n type?: string;\n text?: string;\n partial_json?: string;\n thinking?: string;\n signature?: string;\n}> = Validators.object<{\n type?: string;\n text?: string;\n partial_json?: string;\n thinking?: string;\n signature?: string;\n}>(\n {\n type: Validators.string.optional(),\n text: Validators.string.optional(),\n partial_json: Validators.string.optional(),\n thinking: Validators.string.optional(),\n signature: Validators.string.optional()\n },\n { options: { optionalFields: ['type', 'text', 'partial_json', 'thinking', 'signature'] } }\n);\n\nconst anthropicContentBlockDeltaPayload: Validator<IAnthropicContentBlockDeltaPayload> =\n Validators.object<IAnthropicContentBlockDeltaPayload>(\n {\n index: Validators.number.optional(),\n delta: anthropicContentBlockDeltaInner\n },\n { options: { optionalFields: ['index'] } }\n );\n\nconst anthropicContentBlockStopPayload: Validator<IAnthropicContentBlockStopPayload> =\n Validators.object<IAnthropicContentBlockStopPayload>(\n { index: Validators.number.optional() },\n { options: { optionalFields: ['index'] } }\n );\n\nconst anthropicMessageDeltaInner: Validator<{ stop_reason?: string }> = Validators.object<{\n stop_reason?: string;\n}>({ stop_reason: Validators.string.optional() }, { options: { optionalFields: ['stop_reason'] } });\n\nconst anthropicMessageDeltaPayload: Validator<IAnthropicMessageDeltaPayload> =\n Validators.object<IAnthropicMessageDeltaPayload>({\n delta: anthropicMessageDeltaInner\n });\n\nconst anthropicErrorInner: Validator<{ message?: string }> = Validators.object<{ message?: string }>(\n { message: Validators.string.optional() },\n { options: { optionalFields: ['message'] } }\n);\n\nconst anthropicErrorPayload: Validator<IAnthropicErrorPayload> = Validators.object<IAnthropicErrorPayload>(\n { error: anthropicErrorInner.optional() },\n { options: { optionalFields: ['error'] } }\n);\n\n// ============================================================================\n// Stream translator\n// ============================================================================\n\n/**\n * Recognized Anthropic Messages API SSE event names. Anything not in this set surfaces a\n * one-time `logger.warn` per stream — same rationale as the OpenAI Responses adapter's\n * `RECOGNIZED_OPENAI_RESPONSES_EVENTS` allowlist in `openaiResponses.ts`. Add to this set\n * when a new event type is observed and confirmed safe to ignore.\n *\n * @internal\n */\nconst RECOGNIZED_ANTHROPIC_EVENTS: ReadonlySet<string> = new Set<string>([\n // ---- handled by the translator ----\n 'content_block_start',\n 'content_block_delta',\n 'content_block_stop',\n 'message_delta',\n 'message_stop',\n 'error',\n // ---- lifecycle / heartbeats: intentionally silent ----\n 'message_start',\n 'ping'\n]);\n\n/**\n * Translates an Anthropic Messages API SSE stream into unified events.\n *\n * Maintains an ordered accumulation buffer (keyed by SSE `index`) for all\n * content blocks: `thinking`, `redacted_thinking`, `text`, and `tool_use`.\n * The buffer is available on the returned generator via `.accumulationBuffer`.\n *\n * Unrecognized event names are reported once per stream via `logger?.warn` —\n * see {@link RECOGNIZED_ANTHROPIC_EVENTS}.\n *\n * @internal\n */\nasync function* translateAnthropicStream(\n response: Response,\n accumulationBuffer: Map<number, IAccumulatedBlock>,\n logger?: Logging.ILogger\n): AsyncGenerator<IAiStreamEvent> {\n let fullText = '';\n let truncated = false;\n let stopped = false;\n // Track unrecognized event names we have already warned about, so a hot stream of\n // an unknown event type produces exactly one log line per name per stream.\n const warnedEvents = new Set<string>();\n\n try {\n /* c8 ignore next - body is non-null at this point per openSseConnection */\n if (!response.body) return;\n for await (const message of readSseEvents(response.body)) {\n const eventName = message.event;\n\n if (eventName === 'content_block_start') {\n const payload = validateEventPayload(\n parseSseEventJson(message.data),\n anthropicContentBlockStartPayload\n );\n /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */\n if (!payload) continue;\n const { index: rawIndex, content_block: block } = payload;\n const index = rawIndex ?? 0;\n\n if (block.type === 'thinking') {\n accumulationBuffer.set(index, { type: 'thinking', thinking: '', signature: '' });\n } else if (block.type === 'redacted_thinking') {\n accumulationBuffer.set(index, {\n type: 'redacted_thinking',\n /* c8 ignore next 1 - defensive: Anthropic always provides data for redacted_thinking */\n data: block.data ?? ''\n });\n } else if (block.type === 'text') {\n accumulationBuffer.set(index, { type: 'text', text: '' });\n } else if (block.type === 'tool_use' && block.id && block.name) {\n accumulationBuffer.set(index, {\n type: 'tool_use',\n id: block.id,\n name: block.name,\n argsBuffer: ''\n });\n yield { type: 'client-tool-call-start', toolName: block.name, callId: block.id };\n } else if (block.type === 'server_tool_use' && block.name === 'web_search') {\n yield { type: 'tool-event', toolType: 'web_search', phase: 'started' };\n } else if (block.type === 'web_search_tool_result') {\n yield { type: 'tool-event', toolType: 'web_search', phase: 'completed' };\n }\n } else if (eventName === 'content_block_delta') {\n const payload = validateEventPayload(\n parseSseEventJson(message.data),\n anthropicContentBlockDeltaPayload\n );\n /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */\n if (!payload) continue;\n const { index: rawDeltaIndex, delta } = payload;\n const index = rawDeltaIndex ?? 0;\n const block = accumulationBuffer.get(index);\n\n if (delta.type === 'text_delta' && typeof delta.text === 'string') {\n /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */\n if (block?.type === 'text') {\n block.text += delta.text;\n }\n if (delta.text.length > 0) {\n fullText += delta.text;\n yield { type: 'text-delta', delta: delta.text };\n }\n } else if (delta.type === 'input_json_delta' && typeof delta.partial_json === 'string') {\n /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */\n if (block?.type === 'tool_use') {\n block.argsBuffer += delta.partial_json;\n }\n } else if (delta.type === 'thinking_delta' && typeof delta.thinking === 'string') {\n /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */\n if (block?.type === 'thinking') {\n block.thinking += delta.thinking;\n }\n } else if (delta.type === 'signature_delta' && typeof delta.signature === 'string') {\n // CRITICAL (E5): signature must be APPENDED, not overwritten.\n // The signature is base64 arriving in multiple chunks.\n // Overwriting produces a truncated signature that Anthropic rejects with HTTP 400.\n /* c8 ignore next 1 - defensive: delta arrives only after block_start sets buffer entry */\n if (block?.type === 'thinking') {\n block.signature += delta.signature;\n }\n }\n } else if (eventName === 'content_block_stop') {\n const payload = validateEventPayload(\n parseSseEventJson(message.data),\n anthropicContentBlockStopPayload\n );\n /* c8 ignore next 1 - defensive: payload null branch unreachable after validation */\n if (!payload) continue;\n /* c8 ignore next 1 - defensive: payload.index ?? 0 null branch is unreachable */\n const block = accumulationBuffer.get(payload.index ?? 0);\n /* c8 ignore next 1 - defensive: block always exists when block_stop follows block_start */\n if (block?.type === 'tool_use') {\n let args: JsonObject;\n try {\n /* c8 ignore next 1 - defensive: argsBuffer || '{}' empty-string branch unreachable in tests */\n const parsed = JSON.parse(block.argsBuffer || '{}') as unknown;\n /* c8 ignore start - defensive: non-object/malformed parse defaults to empty object */\n args =\n parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as JsonObject)\n : {};\n } catch {\n args = {};\n }\n /* c8 ignore stop */\n yield { type: 'client-tool-call-done', toolName: block.name, callId: block.id, args };\n }\n } else if (eventName === 'message_delta') {\n const payload = validateEventPayload(parseSseEventJson(message.data), anthropicMessageDeltaPayload);\n /* c8 ignore next 1 - defensive: payload?.delta null branch unreachable after validation */\n if (payload?.delta.stop_reason === 'max_tokens') {\n truncated = true;\n }\n } else if (eventName === 'message_stop') {\n stopped = true;\n } else if (eventName === 'error') {\n const payload = validateEventPayload(parseSseEventJson(message.data), anthropicErrorPayload);\n yield {\n type: 'error',\n /* c8 ignore next 1 - defensive: payload?.error null branch unreachable after validation */\n message: payload?.error?.message ?? 'Anthropic stream returned an error event'\n };\n return;\n } else if (\n typeof eventName === 'string' &&\n !RECOGNIZED_ANTHROPIC_EVENTS.has(eventName) &&\n !warnedEvents.has(eventName)\n ) {\n // Empirical drift instrument: an unrecognized Anthropic event surfaces as a one-time\n // warning per stream. Update RECOGNIZED_ANTHROPIC_EVENTS once the new event is either\n // handled or confirmed safe to ignore.\n warnedEvents.add(eventName);\n logger?.warn(\n `${UNRECOGNIZED_EVENT_WARN_TAG} Anthropic streaming adapter: unrecognized SSE event ` +\n `'${eventName}'. ` +\n `payload preview: ${formatUnrecognizedEventPayloadPreview(message.data)}. ` +\n `This may indicate provider drift — if the new event carries data the adapter ` +\n `should surface, add a handler; otherwise add the name to ` +\n `RECOGNIZED_ANTHROPIC_EVENTS.`\n );\n }\n }\n } catch (err: unknown) /* c8 ignore start - defensive: stream errors are always Error instances */ {\n yield { type: 'error', message: err instanceof Error ? err.message : String(err) };\n return;\n } /* c8 ignore stop */\n\n if (stopped) {\n yield { type: 'done', truncated, fullText };\n } else {\n yield { type: 'error', message: 'Anthropic stream ended without a message_stop event' };\n }\n}\n\n// ============================================================================\n// Per-format request caller\n// ============================================================================\n\n/**\n * Issues a streaming Anthropic Messages request and returns the\n * unified-event iterable on success.\n *\n * @internal\n */\nexport async function callAnthropicStream(\n config: IStreamApiConfig,\n prompt: AiPrompt,\n messagesBefore: ReadonlyArray<IChatMessage> | undefined,\n temperature: number,\n tools: ReadonlyArray<AiToolConfig> | undefined,\n logger?: Logging.ILogger,\n signal?: AbortSignal,\n resolvedThinking?: IResolvedThinkingConfig,\n accumulationBuffer?: Map<number, IAccumulatedBlock>,\n continuationMessages?: ReadonlyArray<JsonObject>\n): Promise<Result<AsyncIterable<IAiStreamEvent>>> {\n const url = `${config.baseUrl}/messages`;\n const messages = buildAnthropicMessages(prompt, {\n head: messagesBefore,\n rawTail: continuationMessages\n });\n // When thinking is active, temperature is rejected by Anthropic (validated upstream).\n const body: Record<string, unknown> = {\n model: config.model,\n system: prompt.system,\n messages,\n max_tokens: 4096,\n ...(resolvedThinking?.anthropicEffort === undefined ? { temperature } : {}),\n stream: true\n };\n if (resolvedThinking?.anthropicEffort !== undefined) {\n body.thinking = {\n type: 'enabled',\n budget_tokens: anthropicEffortToBudgetTokens(resolvedThinking.anthropicEffort)\n };\n }\n if (resolvedThinking?.otherParams !== undefined) {\n Object.assign(body, resolvedThinking.otherParams);\n }\n if (tools && tools.length > 0) {\n body.tools = toAnthropicTools(tools);\n }\n const headers: Record<string, string> = {\n 'x-api-key': config.apiKey,\n 'anthropic-version': '2023-06-01',\n 'anthropic-dangerous-direct-browser-access': 'true'\n };\n /* c8 ignore next 4 - optional logger diagnostic output */\n if (logger) {\n const toolTypes = tools && tools.length > 0 ? tools.map((t) => t.type).join(',') : 'none';\n logger.info(`Anthropic streaming: model=${config.model}, tools=${toolTypes}`);\n }\n const buffer = accumulationBuffer ?? new Map<number, IAccumulatedBlock>();\n const conn = await openSseConnection(url, headers, body, logger, signal);\n return conn.onSuccess((response) => succeed(translateAnthropicStream(response, buffer, logger)));\n}\n"]}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Per-provider continuation message builders and the `executeClientToolTurn`
3
+ * helper for orchestrating a single client-tool round-trip.
4
+ *
5
+ * Each provider requires a different wire format for the follow-up request:
6
+ * - **Anthropic**: assistant turn reconstructed from the ordered accumulation
7
+ * buffer (thinking / redacted_thinking / text / tool_use in original stream
8
+ * order) + user turn with `tool_result` blocks. When thinking is active, the
9
+ * follow-up request must NOT set `tool_choice: { type: 'any' }` or
10
+ * `tool_choice: { type: 'tool', ... }` (E3 / §5.4 of b4-spike-findings).
11
+ * - **OpenAI / xAI Responses API**: `function_call` input items +
12
+ * `function_call_output` input items.
13
+ * - **Gemini**: model turn with `functionCall` parts + user turn with
14
+ * `functionResponse` parts (correlation by tool name).
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ import { type Logging, Result } from '@fgv/ts-utils';
19
+ import { type JsonObject } from '@fgv/ts-json-base';
20
+ import { type AiPrompt, type AiServerToolConfig, type IAiClientTool, type IAiClientToolContinuation, type IAiClientToolTurnResult, type IAiStreamEvent, type IChatMessage, type IAiProviderDescriptor } from '../model';
21
+ import { type IResolvedThinkingConfig } from '../thinkingOptionsResolver';
22
+ import { type IAccumulatedBlock } from './anthropic';
23
+ import { type IAccumulatedFunctionCall } from './openaiResponses';
24
+ import { type IAccumulatedGeminiFunctionCall } from './gemini';
25
+ /**
26
+ * Accumulated result for a single tool call, collected during stream iteration.
27
+ * @internal
28
+ */
29
+ interface IToolCallResult {
30
+ readonly toolName: string;
31
+ readonly callId?: string;
32
+ readonly args: JsonObject;
33
+ readonly result: string;
34
+ readonly isError: boolean;
35
+ }
36
+ /**
37
+ * Builds the Anthropic follow-up messages for a client-tool round-trip.
38
+ *
39
+ * Reconstructs the assistant turn from the ordered accumulation buffer
40
+ * (all block types in original stream order) and appends a user turn
41
+ * with `tool_result` blocks for each executed tool call.
42
+ *
43
+ * **Constraint (E3):** The returned continuation does NOT include a forced
44
+ * `tool_choice` field. When thinking is active, Anthropic rejects
45
+ * `tool_choice: { type: 'any' }` and `tool_choice: { type: 'tool', ... }`
46
+ * with an HTTP 400 error. Only `tool_choice: { type: 'auto' }` (the default,
47
+ * i.e. omitted) is compatible with extended thinking.
48
+ *
49
+ * @internal
50
+ */
51
+ export declare function buildAnthropicContinuation(accBuffer: Map<number, IAccumulatedBlock>, toolResults: IToolCallResult[]): IAiClientToolContinuation;
52
+ /**
53
+ * Builds the OpenAI / xAI Responses API follow-up input items for a
54
+ * client-tool round-trip.
55
+ *
56
+ * Emits `function_call` items (the model's call) followed by
57
+ * `function_call_output` items (the harness execution result), one pair
58
+ * per executed tool call.
59
+ *
60
+ * @internal
61
+ */
62
+ export declare function buildOpenAiContinuation(calls: Map<string, IAccumulatedFunctionCall>, toolResults: IToolCallResult[]): IAiClientToolContinuation;
63
+ /**
64
+ * Builds the Gemini follow-up contents for a client-tool round-trip.
65
+ *
66
+ * Emits a model turn with `functionCall` parts (one per tool call) and a
67
+ * user turn with `functionResponse` parts (correlation by tool name, since
68
+ * Gemini does not assign call IDs).
69
+ *
70
+ * @internal
71
+ */
72
+ export declare function buildGeminiContinuation(calls: IAccumulatedGeminiFunctionCall[], toolResults: IToolCallResult[]): IAiClientToolContinuation;
73
+ /**
74
+ * Parameters for {@link AiAssist.executeClientToolTurn}.
75
+ * @public
76
+ */
77
+ export interface IExecuteClientToolTurnParams {
78
+ /** The provider descriptor for routing (Anthropic / OpenAI / Gemini). */
79
+ readonly descriptor: IAiProviderDescriptor;
80
+ /** API key for authentication. */
81
+ readonly apiKey: string;
82
+ /** The structured prompt. */
83
+ readonly prompt: AiPrompt;
84
+ /** Prior conversation history (excluding the current turn). */
85
+ readonly messagesBefore?: ReadonlyArray<IChatMessage>;
86
+ /**
87
+ * Provider-specific continuation messages to append after the prompt's user
88
+ * message. Used to supply the output of {@link AiAssist.IAiClientToolContinuation}'s
89
+ * `messages` field from a prior turn back to the provider in the follow-up request.
90
+ *
91
+ * Each provider applies its own shape guard to the supplied wire objects:
92
+ * - Anthropic: projects each entry to `{ role, content }` (sufficient for
93
+ * thinking blocks and `tool_result` arrays).
94
+ * - OpenAI / xAI Responses: passes each item verbatim (`function_call` /
95
+ * `function_call_output` items carry distinct fields per `type`); only guards
96
+ * that each entry is a JSON object.
97
+ * - Gemini: projects each entry to `{ role, parts }`.
98
+ *
99
+ * Entries that fail their provider's shape check are silently skipped.
100
+ */
101
+ readonly continuationMessages?: ReadonlyArray<JsonObject>;
102
+ /** Temperature (default: 0.7). */
103
+ readonly temperature?: number;
104
+ /** Server-side tools to include. */
105
+ readonly tools?: ReadonlyArray<AiServerToolConfig>;
106
+ /** Client-defined tools available for the model to call. */
107
+ readonly clientTools: ReadonlyArray<IAiClientTool>;
108
+ /** Optional abort signal. */
109
+ readonly signal?: AbortSignal;
110
+ /** Optional logger for diagnostics. */
111
+ readonly logger?: Logging.ILogger;
112
+ /** Optional resolved thinking config (pre-resolved by the caller). */
113
+ readonly resolvedThinking?: IResolvedThinkingConfig;
114
+ /** Resolved model string (pre-resolved by the caller). When omitted, uses the descriptor's default model. */
115
+ readonly model?: string;
116
+ }
117
+ /**
118
+ * Return value of {@link AiAssist.executeClientToolTurn}.
119
+ * @public
120
+ */
121
+ export interface IExecuteClientToolTurnResult {
122
+ /**
123
+ * The unified-event iterable. Callers iterate this to drive the streaming UI.
124
+ * The iterable forwards `text-delta`, `tool-event`, `client-tool-call-start`,
125
+ * `client-tool-call-done`, and `client-tool-result` events through.
126
+ */
127
+ readonly events: AsyncIterable<IAiStreamEvent>;
128
+ /**
129
+ * Resolves when the stream terminates. On success, carries the
130
+ * {@link AiAssist.IAiClientToolTurnResult} with the optional continuation for the
131
+ * next round. On failure, carries the error message.
132
+ */
133
+ readonly nextTurn: Promise<Result<IAiClientToolTurnResult>>;
134
+ }
135
+ /**
136
+ * Orchestrates a single client-tool streaming turn for any supported provider.
137
+ *
138
+ * Starts a streaming request, iterates the underlying provider stream, and:
139
+ * - Forwards `text-delta`, `tool-event`, `client-tool-call-start`, and
140
+ * `client-tool-call-done` events through to the consumer.
141
+ * - For each `client-tool-call-done` event: validates the raw args against the
142
+ * tool's `parametersSchema`, invokes `execute(typedArgs)`, and emits a
143
+ * `client-tool-result` event.
144
+ * - After stream completion: builds the per-provider continuation (or
145
+ * `{ continuation: undefined }` when no tool calls occurred) and resolves
146
+ * `nextTurn`.
147
+ *
148
+ * **Anthropic constraint (E3):** The continuation for Anthropic does not set
149
+ * a forced `tool_choice`. Only `tool_choice: 'auto'` (the default, i.e.
150
+ * omitted) is compatible with extended thinking.
151
+ *
152
+ * @param params - Turn parameters
153
+ * @returns `{ events, nextTurn }` — stream iterable + completion promise
154
+ * @public
155
+ */
156
+ export declare function executeClientToolTurn(params: IExecuteClientToolTurnParams): Result<IExecuteClientToolTurnResult>;
157
+ export {};
158
+ //# sourceMappingURL=clientToolContinuationBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clientToolContinuationBuilder.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.ts"],"names":[],"mappings":"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"}