@assemble-dev/providers 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -22,6 +22,7 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  AnthropicMessagesResponseSchema: () => AnthropicMessagesResponseSchema,
24
24
  AnthropicStreamEventSchema: () => AnthropicStreamEventSchema,
25
+ AzureOpenAiChatCompletionResponseSchema: () => AzureOpenAiChatCompletionResponseSchema,
25
26
  ChatMessageCacheControlSchema: () => ChatMessageCacheControlSchema,
26
27
  ChatMessageRoleSchema: () => ChatMessageRoleSchema,
27
28
  ChatMessageSchema: () => ChatMessageSchema,
@@ -32,16 +33,30 @@ __export(index_exports, {
32
33
  anthropicBatchJsonOnlySystemInstruction: () => anthropicBatchJsonOnlySystemInstruction,
33
34
  anthropicBatchTraceWorkflowName: () => anthropicBatchTraceWorkflowName,
34
35
  applyCacheControlToLastContentBlock: () => applyCacheControlToLastContentBlock,
36
+ awsSigV4Algorithm: () => awsSigV4Algorithm,
37
+ azureOpenai: () => azureOpenai,
38
+ bedrock: () => bedrock,
39
+ bedrockAnthropicVersion: () => bedrockAnthropicVersion,
35
40
  buildAnthropicCacheControl: () => buildAnthropicCacheControl,
36
41
  buildAnthropicRequestBody: () => buildAnthropicRequestBody,
42
+ buildAnthropicStructuredOutputJsonSchema: () => buildAnthropicStructuredOutputJsonSchema,
43
+ buildAzureOpenAiChatCompletionsUrl: () => buildAzureOpenAiChatCompletionsUrl,
44
+ buildAzureOpenAiChatRequestBody: () => buildAzureOpenAiChatRequestBody,
45
+ buildBedrockInvokeModelRequestBody: () => buildBedrockInvokeModelRequestBody,
46
+ buildBedrockInvokeModelUrl: () => buildBedrockInvokeModelUrl,
47
+ buildGeminiResponseSchema: () => buildGeminiResponseSchema,
37
48
  buildOpenAiRequestBody: () => buildOpenAiRequestBody,
49
+ buildOpenAiStructuredOutputJsonSchema: () => buildOpenAiStructuredOutputJsonSchema,
38
50
  buildProviderCanceledError: () => buildProviderCanceledError,
39
51
  calculateProviderRetryDelayMs: () => calculateProviderRetryDelayMs,
52
+ convertZodSchemaToJsonSchema: () => convertZodSchemaToJsonSchema,
40
53
  createAnthropicBatchClient: () => createAnthropicBatchClient,
41
54
  defaultAnthropicBaseUrl: () => defaultAnthropicBaseUrl,
42
55
  defaultAnthropicBatchPollIntervalMs: () => defaultAnthropicBatchPollIntervalMs,
43
56
  defaultAnthropicBatchTimeoutMs: () => defaultAnthropicBatchTimeoutMs,
44
57
  defaultAnthropicMaxOutputTokens: () => defaultAnthropicMaxOutputTokens,
58
+ defaultAzureOpenAiApiVersion: () => defaultAzureOpenAiApiVersion,
59
+ defaultBedrockMaxOutputTokens: () => defaultBedrockMaxOutputTokens,
45
60
  defaultGeminiBaseUrl: () => defaultGeminiBaseUrl,
46
61
  defaultOpenAiBaseUrl: () => defaultOpenAiBaseUrl,
47
62
  defaultProviderRetryInitialDelayMs: () => defaultProviderRetryInitialDelayMs,
@@ -52,6 +67,7 @@ __export(index_exports, {
52
67
  executeProviderCallWithModelFallback: () => executeProviderCallWithModelFallback,
53
68
  executeProviderCallWithRetry: () => executeProviderCallWithRetry,
54
69
  extractAnthropicTextContent: () => extractAnthropicTextContent,
70
+ extractAnthropicThinkingText: () => extractAnthropicThinkingText,
55
71
  extractAnthropicToolCalls: () => extractAnthropicToolCalls,
56
72
  extractMessageText: () => extractMessageText,
57
73
  gemini: () => gemini,
@@ -60,6 +76,8 @@ __export(index_exports, {
60
76
  joinSystemMessageText: () => joinSystemMessageText,
61
77
  mapAnthropicResponseToChatCompletionResult: () => mapAnthropicResponseToChatCompletionResult,
62
78
  mapAnthropicUsageToTokenUsage: () => mapAnthropicUsageToTokenUsage,
79
+ mapAzureOpenAiResponseToChatCompletionResult: () => mapAzureOpenAiResponseToChatCompletionResult,
80
+ mapAzureOpenAiUsageToTokenUsage: () => mapAzureOpenAiUsageToTokenUsage,
63
81
  mapChatMessageToAnthropicRequestMessage: () => mapChatMessageToAnthropicRequestMessage,
64
82
  mapChatMessageToOpenAiRequestMessage: () => mapChatMessageToOpenAiRequestMessage,
65
83
  mapModelToolChoiceToAnthropicToolChoice: () => mapModelToolChoiceToAnthropicToolChoice,
@@ -69,13 +87,23 @@ __export(index_exports, {
69
87
  mergeProviderRequestExtraBody: () => mergeProviderRequestExtraBody,
70
88
  mockModel: () => mockModel,
71
89
  normalizeAnthropicStopReason: () => normalizeAnthropicStopReason,
90
+ normalizeAzureOpenAiFinishReason: () => normalizeAzureOpenAiFinishReason,
91
+ openAiStructuredOutputSchemaName: () => openAiStructuredOutputSchemaName,
72
92
  openai: () => openai,
73
93
  parseAnthropicBatchStructuredContent: () => parseAnthropicBatchStructuredContent,
74
94
  parseAnthropicStreamEvents: () => parseAnthropicStreamEvents,
75
95
  parseAnthropicToolInputJson: () => parseAnthropicToolInputJson,
96
+ parseAzureOpenAiStreamEvents: () => parseAzureOpenAiStreamEvents,
97
+ parseAzureOpenAiToolArgumentsJson: () => parseAzureOpenAiToolArgumentsJson,
76
98
  resolveAnthropicPromptCachingSettings: () => resolveAnthropicPromptCachingSettings,
99
+ resolveBedrockCredentials: () => resolveBedrockCredentials,
77
100
  resolveProviderApiKey: () => resolveProviderApiKey,
78
- streamAnthropicChatCompletion: () => streamAnthropicChatCompletion
101
+ sanitizeJsonSchemaForAnthropicStructuredOutput: () => sanitizeJsonSchemaForAnthropicStructuredOutput,
102
+ sanitizeJsonSchemaForGeminiResponseSchema: () => sanitizeJsonSchemaForGeminiResponseSchema,
103
+ sanitizeJsonSchemaForOpenAiStructuredOutput: () => sanitizeJsonSchemaForOpenAiStructuredOutput,
104
+ signAwsRequestWithSigV4: () => signAwsRequestWithSigV4,
105
+ streamAnthropicChatCompletion: () => streamAnthropicChatCompletion,
106
+ streamAzureOpenAiChatCompletion: () => streamAzureOpenAiChatCompletion
79
107
  });
80
108
  module.exports = __toCommonJS(index_exports);
81
109
 
@@ -134,14 +162,222 @@ function extractMessageText(message) {
134
162
  }
135
163
 
136
164
  // src/openai-adapter.ts
137
- var import_zod3 = require("zod");
138
- var import_errors14 = require("@assemble-dev/shared-types/errors");
139
- var import_json3 = require("@assemble-dev/shared-types/json");
140
- var import_errors15 = require("@assemble-dev/shared-utils/errors");
165
+ var import_zod4 = require("zod");
166
+ var import_errors16 = require("@assemble-dev/shared-types/errors");
167
+ var import_json4 = require("@assemble-dev/shared-types/json");
168
+ var import_errors17 = require("@assemble-dev/shared-utils/errors");
141
169
 
142
170
  // src/openai-request-mapping.ts
171
+ var import_errors3 = require("@assemble-dev/shared-types/errors");
172
+ var import_errors4 = require("@assemble-dev/shared-utils/errors");
173
+
174
+ // src/structured-output-json-schema.ts
175
+ var import_zod2 = require("zod");
143
176
  var import_errors = require("@assemble-dev/shared-types/errors");
177
+ var import_json2 = require("@assemble-dev/shared-types/json");
144
178
  var import_errors2 = require("@assemble-dev/shared-utils/errors");
179
+
180
+ // src/json-schema-tree.ts
181
+ var schemaMapKeywords = ["properties", "$defs"];
182
+ var schemaListKeywords = ["anyOf", "oneOf", "allOf", "prefixItems"];
183
+ var schemaValueKeywords = [
184
+ "items",
185
+ "additionalProperties",
186
+ "not",
187
+ "if",
188
+ "then",
189
+ "else",
190
+ "contains",
191
+ "propertyNames"
192
+ ];
193
+ function isJsonObject(value) {
194
+ return typeof value === "object" && value !== null && !Array.isArray(value);
195
+ }
196
+ function transformJsonSchemaNode(node, transformNode) {
197
+ const result = { ...transformNode({ ...node }) };
198
+ for (const keyword of schemaMapKeywords) {
199
+ const mapValue = result[keyword];
200
+ if (mapValue !== void 0 && isJsonObject(mapValue)) {
201
+ result[keyword] = transformJsonSchemaMap(mapValue, transformNode);
202
+ }
203
+ }
204
+ for (const keyword of schemaListKeywords) {
205
+ const listValue = result[keyword];
206
+ if (Array.isArray(listValue)) {
207
+ result[keyword] = listValue.map(
208
+ (entry) => isJsonObject(entry) ? transformJsonSchemaNode(entry, transformNode) : entry
209
+ );
210
+ }
211
+ }
212
+ for (const keyword of schemaValueKeywords) {
213
+ const schemaValue = result[keyword];
214
+ if (schemaValue !== void 0 && isJsonObject(schemaValue)) {
215
+ result[keyword] = transformJsonSchemaNode(schemaValue, transformNode);
216
+ }
217
+ }
218
+ return result;
219
+ }
220
+ function transformJsonSchemaMap(schemaMap, transformNode) {
221
+ const result = {};
222
+ for (const [schemaName, schemaValue] of Object.entries(schemaMap)) {
223
+ result[schemaName] = isJsonObject(schemaValue) ? transformJsonSchemaNode(schemaValue, transformNode) : schemaValue;
224
+ }
225
+ return result;
226
+ }
227
+ function inlineJsonSchemaReferences(root) {
228
+ const rootDefinitions = root["$defs"];
229
+ const definitions = rootDefinitions !== void 0 && isJsonObject(rootDefinitions) ? rootDefinitions : {};
230
+ const resolvedRoot = resolveJsonSchemaReferences(
231
+ root,
232
+ definitions,
233
+ /* @__PURE__ */ new Set()
234
+ );
235
+ return isJsonObject(resolvedRoot) ? resolvedRoot : {};
236
+ }
237
+ function resolveJsonSchemaReferences(value, definitions, activeReferences) {
238
+ if (Array.isArray(value)) {
239
+ return value.map(
240
+ (entry) => resolveJsonSchemaReferences(entry, definitions, activeReferences)
241
+ );
242
+ }
243
+ if (!isJsonObject(value)) {
244
+ return value;
245
+ }
246
+ const referenceTarget = value["$ref"];
247
+ if (typeof referenceTarget === "string") {
248
+ return resolveJsonSchemaReferenceTarget(
249
+ referenceTarget,
250
+ definitions,
251
+ activeReferences
252
+ );
253
+ }
254
+ const result = {};
255
+ for (const [key, entryValue] of Object.entries(value)) {
256
+ if (key !== "$defs") {
257
+ result[key] = resolveJsonSchemaReferences(
258
+ entryValue,
259
+ definitions,
260
+ activeReferences
261
+ );
262
+ }
263
+ }
264
+ return result;
265
+ }
266
+ function resolveJsonSchemaReferenceTarget(referenceTarget, definitions, activeReferences) {
267
+ if (activeReferences.has(referenceTarget)) {
268
+ return {};
269
+ }
270
+ const definitionsPrefix = "#/$defs/";
271
+ if (!referenceTarget.startsWith(definitionsPrefix)) {
272
+ return {};
273
+ }
274
+ const definition = definitions[referenceTarget.slice(definitionsPrefix.length)];
275
+ if (definition === void 0 || !isJsonObject(definition)) {
276
+ return {};
277
+ }
278
+ return resolveJsonSchemaReferences(
279
+ definition,
280
+ definitions,
281
+ /* @__PURE__ */ new Set([...activeReferences, referenceTarget])
282
+ );
283
+ }
284
+ function removeJsonSchemaKeywords(node, keywords) {
285
+ const result = {};
286
+ for (const [key, value] of Object.entries(node)) {
287
+ if (!keywords.includes(key)) {
288
+ result[key] = value;
289
+ }
290
+ }
291
+ return result;
292
+ }
293
+
294
+ // src/structured-output-json-schema.ts
295
+ var openAiStructuredOutputSchemaName = "structured_output";
296
+ var schemaMetadataKeywords = ["$schema", "$id"];
297
+ var anthropicUnsupportedSchemaKeywords = [
298
+ ...schemaMetadataKeywords,
299
+ "minimum",
300
+ "maximum",
301
+ "exclusiveMinimum",
302
+ "exclusiveMaximum",
303
+ "minLength",
304
+ "maxLength",
305
+ "multipleOf"
306
+ ];
307
+ var openAiUnsupportedSchemaKeywords = [
308
+ ...anthropicUnsupportedSchemaKeywords,
309
+ "pattern",
310
+ "format",
311
+ "minItems",
312
+ "maxItems",
313
+ "uniqueItems",
314
+ "default"
315
+ ];
316
+ function convertZodSchemaToJsonSchema(schema) {
317
+ try {
318
+ return import_json2.JsonObjectSchema.parse(import_zod2.z.toJSONSchema(schema, { io: "input" }));
319
+ } catch (error) {
320
+ throw new import_errors2.AppError({
321
+ code: import_errors.AppErrorCode.BadRequest,
322
+ message: "Structured output schema could not be converted to JSON Schema",
323
+ statusCode: 400,
324
+ cause: error instanceof Error ? error : void 0
325
+ });
326
+ }
327
+ }
328
+ function buildAnthropicStructuredOutputJsonSchema(schema) {
329
+ return sanitizeJsonSchemaForAnthropicStructuredOutput(
330
+ convertZodSchemaToJsonSchema(schema)
331
+ );
332
+ }
333
+ function sanitizeJsonSchemaForAnthropicStructuredOutput(jsonSchema) {
334
+ return transformJsonSchemaNode(
335
+ inlineJsonSchemaReferences(jsonSchema),
336
+ sanitizeAnthropicSchemaNode
337
+ );
338
+ }
339
+ function buildOpenAiStructuredOutputJsonSchema(schema) {
340
+ return sanitizeJsonSchemaForOpenAiStructuredOutput(
341
+ convertZodSchemaToJsonSchema(schema)
342
+ );
343
+ }
344
+ function sanitizeJsonSchemaForOpenAiStructuredOutput(jsonSchema) {
345
+ return transformJsonSchemaNode(jsonSchema, sanitizeOpenAiSchemaNode);
346
+ }
347
+ function sanitizeAnthropicSchemaNode(node) {
348
+ const sanitized = removeJsonSchemaKeywords(
349
+ node,
350
+ anthropicUnsupportedSchemaKeywords
351
+ );
352
+ if (sanitized["type"] === "object") {
353
+ sanitized["additionalProperties"] = false;
354
+ }
355
+ return sanitized;
356
+ }
357
+ function sanitizeOpenAiSchemaNode(node) {
358
+ const sanitized = removeJsonSchemaKeywords(
359
+ node,
360
+ openAiUnsupportedSchemaKeywords
361
+ );
362
+ if (sanitized["type"] !== "object") {
363
+ return sanitized;
364
+ }
365
+ sanitized["additionalProperties"] = false;
366
+ const propertyNames = listSchemaPropertyNames(sanitized);
367
+ if (propertyNames.length > 0) {
368
+ sanitized["required"] = propertyNames;
369
+ }
370
+ return sanitized;
371
+ }
372
+ function listSchemaPropertyNames(node) {
373
+ const properties = node["properties"];
374
+ if (properties === void 0 || !isJsonObject(properties)) {
375
+ return [];
376
+ }
377
+ return Object.keys(properties);
378
+ }
379
+
380
+ // src/openai-request-mapping.ts
145
381
  function buildOpenAiRequestBody(model, input) {
146
382
  const requestBody = {
147
383
  model,
@@ -153,7 +389,16 @@ function buildOpenAiRequestBody(model, input) {
153
389
  if (input.maxOutputTokens !== void 0) {
154
390
  requestBody.max_tokens = input.maxOutputTokens;
155
391
  }
156
- if (input.requireJsonObjectResponse) {
392
+ if (input.structuredOutputJsonSchema !== void 0) {
393
+ requestBody.response_format = {
394
+ type: "json_schema",
395
+ json_schema: {
396
+ name: openAiStructuredOutputSchemaName,
397
+ strict: true,
398
+ schema: input.structuredOutputJsonSchema
399
+ }
400
+ };
401
+ } else if (input.requireJsonObjectResponse === true) {
157
402
  requestBody.response_format = { type: "json_object" };
158
403
  }
159
404
  if (input.tools !== void 0 && input.tools.length > 0) {
@@ -239,17 +484,17 @@ function mapMessageContentBlockToOpenAiContentPart(contentBlock) {
239
484
  }
240
485
  };
241
486
  }
242
- throw new import_errors2.AppError({
243
- code: import_errors.AppErrorCode.ValidationFailed,
487
+ throw new import_errors4.AppError({
488
+ code: import_errors3.AppErrorCode.ValidationFailed,
244
489
  message: "OpenAI adapter does not support document content blocks in chat messages",
245
490
  statusCode: 400
246
491
  });
247
492
  }
248
493
 
249
494
  // src/parse-structured-json.ts
250
- var import_errors3 = require("@assemble-dev/shared-types/errors");
251
- var import_json2 = require("@assemble-dev/shared-types/json");
252
- var import_errors4 = require("@assemble-dev/shared-utils/errors");
495
+ var import_errors5 = require("@assemble-dev/shared-types/errors");
496
+ var import_json3 = require("@assemble-dev/shared-types/json");
497
+ var import_errors6 = require("@assemble-dev/shared-utils/errors");
253
498
  var markdownCodeFencePattern = /^```[A-Za-z]*\s*\n?([\s\S]*?)\n?```$/;
254
499
  function parseStructuredJsonText(text, schema) {
255
500
  return schema.parse(parseJsonText(stripMarkdownCodeFences(text)));
@@ -264,10 +509,10 @@ function stripMarkdownCodeFences(text) {
264
509
  }
265
510
  function parseJsonText(text) {
266
511
  try {
267
- return import_json2.JsonValueSchema.parse(JSON.parse(text));
512
+ return import_json3.JsonValueSchema.parse(JSON.parse(text));
268
513
  } catch (error) {
269
- throw new import_errors4.AppError({
270
- code: import_errors3.AppErrorCode.ValidationFailed,
514
+ throw new import_errors6.AppError({
515
+ code: import_errors5.AppErrorCode.ValidationFailed,
271
516
  message: "Structured output was not valid JSON",
272
517
  statusCode: 422,
273
518
  cause: error instanceof Error ? error : void 0
@@ -276,9 +521,9 @@ function parseJsonText(text) {
276
521
  }
277
522
 
278
523
  // src/provider-api-key.ts
279
- var import_zod2 = require("zod");
280
- var import_errors5 = require("@assemble-dev/shared-types/errors");
281
- var import_errors6 = require("@assemble-dev/shared-utils/errors");
524
+ var import_zod3 = require("zod");
525
+ var import_errors7 = require("@assemble-dev/shared-types/errors");
526
+ var import_errors8 = require("@assemble-dev/shared-utils/errors");
282
527
  var import_provider_keys = require("@assemble-dev/shared-utils/provider-keys");
283
528
  function resolveProviderApiKey(input) {
284
529
  if (input.apiKey !== void 0 && input.apiKey.length > 0) {
@@ -291,8 +536,8 @@ function resolveProviderApiKey(input) {
291
536
  }
292
537
  function resolveNamedProviderApiKeyFromEnv(input, apiKeyName) {
293
538
  if (!(0, import_provider_keys.validateProviderApiKeyName)(apiKeyName)) {
294
- throw new import_errors6.AppError({
295
- code: import_errors5.AppErrorCode.BadRequest,
539
+ throw new import_errors8.AppError({
540
+ code: import_errors7.AppErrorCode.BadRequest,
296
541
  message: `Invalid ${input.providerLabel} apiKeyName "${apiKeyName}". Expected ${import_provider_keys.expectedProviderApiKeyNameFormat}.`,
297
542
  statusCode: 400
298
543
  });
@@ -300,8 +545,8 @@ function resolveNamedProviderApiKeyFromEnv(input, apiKeyName) {
300
545
  const envVarName = (0, import_provider_keys.buildNamedApiKeyEnvVarName)(input.baseEnvVarName, apiKeyName);
301
546
  const envApiKey = readEnvironmentVariable(envVarName);
302
547
  if (envApiKey === void 0 || envApiKey.length === 0) {
303
- throw new import_errors6.AppError({
304
- code: import_errors5.AppErrorCode.Unauthorized,
548
+ throw new import_errors8.AppError({
549
+ code: import_errors7.AppErrorCode.Unauthorized,
305
550
  message: `${input.providerLabel} API key named "${apiKeyName}" is missing. Set the ${envVarName} environment variable or pass apiKey to ${input.adapterFunctionName}.`,
306
551
  statusCode: 401
307
552
  });
@@ -311,8 +556,8 @@ function resolveNamedProviderApiKeyFromEnv(input, apiKeyName) {
311
556
  function resolveBaseProviderApiKeyFromEnv(input) {
312
557
  const envApiKey = readEnvironmentVariable(input.baseEnvVarName);
313
558
  if (envApiKey === void 0 || envApiKey.length === 0) {
314
- throw new import_errors6.AppError({
315
- code: import_errors5.AppErrorCode.Unauthorized,
559
+ throw new import_errors8.AppError({
560
+ code: import_errors7.AppErrorCode.Unauthorized,
316
561
  message: `${input.providerLabel} API key is missing. Pass apiKey to ${input.adapterFunctionName} or set the ${input.baseEnvVarName} environment variable.`,
317
562
  statusCode: 401
318
563
  });
@@ -320,19 +565,19 @@ function resolveBaseProviderApiKeyFromEnv(input) {
320
565
  return envApiKey;
321
566
  }
322
567
  function readEnvironmentVariable(envVarName) {
323
- const parsedEnv = import_zod2.z.object({ [envVarName]: import_zod2.z.string().optional() }).parse(process.env);
568
+ const parsedEnv = import_zod3.z.object({ [envVarName]: import_zod3.z.string().optional() }).parse(process.env);
324
569
  return parsedEnv[envVarName];
325
570
  }
326
571
 
327
572
  // src/provider-cancellation.ts
328
- var import_errors7 = require("@assemble-dev/shared-types/errors");
329
- var import_errors8 = require("@assemble-dev/shared-utils/errors");
573
+ var import_errors9 = require("@assemble-dev/shared-types/errors");
574
+ var import_errors10 = require("@assemble-dev/shared-utils/errors");
330
575
  function isAbortError(error) {
331
576
  return error.name === "AbortError";
332
577
  }
333
578
  function buildProviderCanceledError(providerLabel) {
334
- return new import_errors8.AppError({
335
- code: import_errors7.AppErrorCode.Canceled,
579
+ return new import_errors10.AppError({
580
+ code: import_errors9.AppErrorCode.Canceled,
336
581
  message: `${providerLabel} request was canceled`,
337
582
  statusCode: 499
338
583
  });
@@ -358,18 +603,18 @@ function mergeProviderRequestExtraBody(requestBody, adapterExtraBody, requestExt
358
603
  }
359
604
 
360
605
  // src/provider-fallback.ts
361
- var import_errors11 = require("@assemble-dev/shared-utils/errors");
606
+ var import_errors13 = require("@assemble-dev/shared-utils/errors");
362
607
 
363
608
  // src/provider-retry.ts
364
- var import_errors9 = require("@assemble-dev/shared-types/errors");
365
- var import_errors10 = require("@assemble-dev/shared-utils/errors");
609
+ var import_errors11 = require("@assemble-dev/shared-types/errors");
610
+ var import_errors12 = require("@assemble-dev/shared-utils/errors");
366
611
  var defaultProviderRetryMaxAttempts = 3;
367
612
  var defaultProviderRetryInitialDelayMs = 500;
368
613
  var defaultProviderRetryMaxDelayMs = 8e3;
369
614
  var retryableAppErrorCodes = /* @__PURE__ */ new Set([
370
- import_errors9.AppErrorCode.RateLimited,
371
- import_errors9.AppErrorCode.ServiceUnavailable,
372
- import_errors9.AppErrorCode.InternalServerError
615
+ import_errors11.AppErrorCode.RateLimited,
616
+ import_errors11.AppErrorCode.ServiceUnavailable,
617
+ import_errors11.AppErrorCode.InternalServerError
373
618
  ]);
374
619
  function isRetryableProviderAppError(appError) {
375
620
  return retryableAppErrorCodes.has(appError.code);
@@ -384,7 +629,7 @@ async function executeProviderCallWithRetry(retryOptions, executeCall, waitFor)
384
629
  try {
385
630
  return await executeCall();
386
631
  } catch (error) {
387
- if (error instanceof import_errors10.AppError && !isRetryableProviderAppError(error)) {
632
+ if (error instanceof import_errors12.AppError && !isRetryableProviderAppError(error)) {
388
633
  throw error;
389
634
  }
390
635
  if (error instanceof Error && isAbortError(error)) {
@@ -418,7 +663,7 @@ async function executeProviderCallWithModelFallback(fallbackModel, executePrimar
418
663
  if (fallbackModel === void 0) {
419
664
  throw error;
420
665
  }
421
- if (error instanceof import_errors11.AppError && !isRetryableProviderAppError(error)) {
666
+ if (error instanceof import_errors13.AppError && !isRetryableProviderAppError(error)) {
422
667
  throw error;
423
668
  }
424
669
  if (error instanceof Error && isAbortError(error)) {
@@ -429,11 +674,11 @@ async function executeProviderCallWithModelFallback(fallbackModel, executePrimar
429
674
  }
430
675
 
431
676
  // src/provider-status-error.ts
432
- var import_errors12 = require("@assemble-dev/shared-types/errors");
433
- var import_errors13 = require("@assemble-dev/shared-utils/errors");
677
+ var import_errors14 = require("@assemble-dev/shared-types/errors");
678
+ var import_errors15 = require("@assemble-dev/shared-utils/errors");
434
679
  function buildProviderStatusError(providerLabel, providerStatus) {
435
680
  const code = mapProviderStatusToAppErrorCode(providerStatus);
436
- return new import_errors13.AppError({
681
+ return new import_errors15.AppError({
437
682
  code,
438
683
  message: `${providerLabel} request failed with status ${String(providerStatus)}`,
439
684
  statusCode: mapAppErrorCodeToStatusCode(code),
@@ -441,44 +686,44 @@ function buildProviderStatusError(providerLabel, providerStatus) {
441
686
  });
442
687
  }
443
688
  function buildProviderInvalidResponseError(providerLabel, expectedShapeDescription) {
444
- return new import_errors13.AppError({
445
- code: import_errors12.AppErrorCode.ValidationFailed,
689
+ return new import_errors15.AppError({
690
+ code: import_errors14.AppErrorCode.ValidationFailed,
446
691
  message: `${providerLabel} response did not match the expected ${expectedShapeDescription} shape`,
447
692
  statusCode: 502
448
693
  });
449
694
  }
450
695
  function mapProviderStatusToAppErrorCode(providerStatus) {
451
696
  if (providerStatus === 400) {
452
- return import_errors12.AppErrorCode.BadRequest;
697
+ return import_errors14.AppErrorCode.BadRequest;
453
698
  }
454
699
  if (providerStatus === 401) {
455
- return import_errors12.AppErrorCode.Unauthorized;
700
+ return import_errors14.AppErrorCode.Unauthorized;
456
701
  }
457
702
  if (providerStatus === 403) {
458
- return import_errors12.AppErrorCode.Forbidden;
703
+ return import_errors14.AppErrorCode.Forbidden;
459
704
  }
460
705
  if (providerStatus === 404) {
461
- return import_errors12.AppErrorCode.NotFound;
706
+ return import_errors14.AppErrorCode.NotFound;
462
707
  }
463
708
  if (providerStatus === 429) {
464
- return import_errors12.AppErrorCode.RateLimited;
709
+ return import_errors14.AppErrorCode.RateLimited;
465
710
  }
466
- return import_errors12.AppErrorCode.InternalServerError;
711
+ return import_errors14.AppErrorCode.InternalServerError;
467
712
  }
468
713
  function mapAppErrorCodeToStatusCode(code) {
469
- if (code === import_errors12.AppErrorCode.BadRequest) {
714
+ if (code === import_errors14.AppErrorCode.BadRequest) {
470
715
  return 400;
471
716
  }
472
- if (code === import_errors12.AppErrorCode.Unauthorized) {
717
+ if (code === import_errors14.AppErrorCode.Unauthorized) {
473
718
  return 401;
474
719
  }
475
- if (code === import_errors12.AppErrorCode.Forbidden) {
720
+ if (code === import_errors14.AppErrorCode.Forbidden) {
476
721
  return 403;
477
722
  }
478
- if (code === import_errors12.AppErrorCode.NotFound) {
723
+ if (code === import_errors14.AppErrorCode.NotFound) {
479
724
  return 404;
480
725
  }
481
- if (code === import_errors12.AppErrorCode.RateLimited) {
726
+ if (code === import_errors14.AppErrorCode.RateLimited) {
482
727
  return 429;
483
728
  }
484
729
  return 500;
@@ -486,33 +731,29 @@ function mapAppErrorCodeToStatusCode(code) {
486
731
 
487
732
  // src/openai-adapter.ts
488
733
  var defaultOpenAiBaseUrl = "https://api.openai.com/v1";
489
- var OpenAiResponseToolCallSchema = import_zod3.z.object({
490
- id: import_zod3.z.string(),
491
- function: import_zod3.z.object({
492
- name: import_zod3.z.string(),
493
- arguments: import_zod3.z.string()
734
+ var OpenAiResponseToolCallSchema = import_zod4.z.object({
735
+ id: import_zod4.z.string(),
736
+ function: import_zod4.z.object({
737
+ name: import_zod4.z.string(),
738
+ arguments: import_zod4.z.string()
494
739
  })
495
740
  });
496
- var OpenAiChatCompletionResponseSchema = import_zod3.z.object({
497
- choices: import_zod3.z.array(
498
- import_zod3.z.object({
499
- message: import_zod3.z.object({
500
- content: import_zod3.z.string().nullable(),
501
- tool_calls: import_zod3.z.array(OpenAiResponseToolCallSchema).optional()
741
+ var OpenAiChatCompletionResponseSchema = import_zod4.z.object({
742
+ choices: import_zod4.z.array(
743
+ import_zod4.z.object({
744
+ message: import_zod4.z.object({
745
+ content: import_zod4.z.string().nullable(),
746
+ tool_calls: import_zod4.z.array(OpenAiResponseToolCallSchema).optional()
502
747
  }),
503
- finish_reason: import_zod3.z.string().nullable().optional()
748
+ finish_reason: import_zod4.z.string().nullable().optional()
504
749
  })
505
750
  ).min(1),
506
- usage: import_zod3.z.object({
507
- prompt_tokens: import_zod3.z.number().int().nonnegative(),
508
- completion_tokens: import_zod3.z.number().int().nonnegative(),
509
- total_tokens: import_zod3.z.number().int().nonnegative()
751
+ usage: import_zod4.z.object({
752
+ prompt_tokens: import_zod4.z.number().int().nonnegative(),
753
+ completion_tokens: import_zod4.z.number().int().nonnegative(),
754
+ total_tokens: import_zod4.z.number().int().nonnegative()
510
755
  })
511
756
  });
512
- var structuredOutputSystemMessage = {
513
- role: "system",
514
- content: "Respond with a single JSON object that satisfies the caller's requested structure. Output only valid JSON with no surrounding text."
515
- };
516
757
  function openai(options) {
517
758
  return {
518
759
  name: `openai:${options.model}`,
@@ -521,7 +762,6 @@ function openai(options) {
521
762
  messages: request.messages,
522
763
  temperature: request.temperature ?? options.temperature,
523
764
  maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
524
- requireJsonObjectResponse: false,
525
765
  tools: request.tools,
526
766
  toolChoice: request.toolChoice,
527
767
  abortSignal: request.abortSignal,
@@ -530,10 +770,12 @@ function openai(options) {
530
770
  },
531
771
  async generateStructuredOutput(request) {
532
772
  const completion = await executeOpenAiAdapterCall(options, {
533
- messages: [structuredOutputSystemMessage, ...request.messages],
773
+ messages: request.messages,
534
774
  temperature: request.temperature ?? options.temperature,
535
775
  maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
536
- requireJsonObjectResponse: true,
776
+ structuredOutputJsonSchema: buildOpenAiStructuredOutputJsonSchema(
777
+ request.schema
778
+ ),
537
779
  abortSignal: request.abortSignal
538
780
  });
539
781
  return {
@@ -626,10 +868,10 @@ function parseOpenAiToolArgumentsJson(argumentsJsonText) {
626
868
  return {};
627
869
  }
628
870
  try {
629
- return import_json3.JsonValueSchema.parse(JSON.parse(argumentsJsonText));
871
+ return import_json4.JsonValueSchema.parse(JSON.parse(argumentsJsonText));
630
872
  } catch (error) {
631
- throw new import_errors15.AppError({
632
- code: import_errors14.AppErrorCode.ValidationFailed,
873
+ throw new import_errors17.AppError({
874
+ code: import_errors16.AppErrorCode.ValidationFailed,
633
875
  message: "OpenAI tool call arguments were not valid JSON",
634
876
  statusCode: 502,
635
877
  cause: error instanceof Error ? error : void 0
@@ -651,8 +893,8 @@ function extractOpenAiMessageContent(response, allowEmptyContent) {
651
893
  if (allowEmptyContent) {
652
894
  return "";
653
895
  }
654
- throw new import_errors15.AppError({
655
- code: import_errors14.AppErrorCode.ValidationFailed,
896
+ throw new import_errors17.AppError({
897
+ code: import_errors16.AppErrorCode.ValidationFailed,
656
898
  message: "OpenAI response contained no message content",
657
899
  statusCode: 502
658
900
  });
@@ -716,6 +958,11 @@ function buildAnthropicRequestBody(settings, input) {
716
958
  budget_tokens: settings.thinking.budgetTokens
717
959
  };
718
960
  }
961
+ if (input.structuredOutputJsonSchema !== void 0) {
962
+ requestBody.output_config = {
963
+ format: { type: "json_schema", schema: input.structuredOutputJsonSchema }
964
+ };
965
+ }
719
966
  return requestBody;
720
967
  }
721
968
  function applyAnthropicSystemField(requestBody, settings, input) {
@@ -872,44 +1119,45 @@ function mapMessageContentBlockToAnthropic(contentBlock) {
872
1119
  }
873
1120
 
874
1121
  // src/anthropic-response-parsing.ts
875
- var import_zod4 = require("zod");
876
- var import_errors16 = require("@assemble-dev/shared-types/errors");
877
- var import_json4 = require("@assemble-dev/shared-types/json");
878
- var import_errors17 = require("@assemble-dev/shared-utils/errors");
879
- var AnthropicUsageSchema = import_zod4.z.object({
880
- input_tokens: import_zod4.z.number().int().nonnegative(),
881
- output_tokens: import_zod4.z.number().int().nonnegative(),
882
- cache_creation_input_tokens: import_zod4.z.number().int().nonnegative().optional(),
883
- cache_read_input_tokens: import_zod4.z.number().int().nonnegative().optional()
1122
+ var import_zod5 = require("zod");
1123
+ var import_errors18 = require("@assemble-dev/shared-types/errors");
1124
+ var import_json5 = require("@assemble-dev/shared-types/json");
1125
+ var import_errors19 = require("@assemble-dev/shared-utils/errors");
1126
+ var AnthropicUsageSchema = import_zod5.z.object({
1127
+ input_tokens: import_zod5.z.number().int().nonnegative(),
1128
+ output_tokens: import_zod5.z.number().int().nonnegative(),
1129
+ cache_creation_input_tokens: import_zod5.z.number().int().nonnegative().optional(),
1130
+ cache_read_input_tokens: import_zod5.z.number().int().nonnegative().optional()
884
1131
  });
885
- var AnthropicContentBlockSchema = import_zod4.z.discriminatedUnion("type", [
886
- import_zod4.z.object({
887
- type: import_zod4.z.literal("text"),
888
- text: import_zod4.z.string()
1132
+ var AnthropicContentBlockSchema = import_zod5.z.discriminatedUnion("type", [
1133
+ import_zod5.z.object({
1134
+ type: import_zod5.z.literal("text"),
1135
+ text: import_zod5.z.string()
889
1136
  }),
890
- import_zod4.z.object({
891
- type: import_zod4.z.literal("tool_use"),
892
- id: import_zod4.z.string(),
893
- name: import_zod4.z.string(),
894
- input: import_json4.JsonValueSchema
1137
+ import_zod5.z.object({
1138
+ type: import_zod5.z.literal("tool_use"),
1139
+ id: import_zod5.z.string(),
1140
+ name: import_zod5.z.string(),
1141
+ input: import_json5.JsonValueSchema
895
1142
  }),
896
- import_zod4.z.object({
897
- type: import_zod4.z.literal("thinking"),
898
- thinking: import_zod4.z.string().optional(),
899
- signature: import_zod4.z.string().optional()
1143
+ import_zod5.z.object({
1144
+ type: import_zod5.z.literal("thinking"),
1145
+ thinking: import_zod5.z.string().optional(),
1146
+ signature: import_zod5.z.string().optional()
900
1147
  }),
901
- import_zod4.z.object({
902
- type: import_zod4.z.literal("redacted_thinking"),
903
- data: import_zod4.z.string().optional()
1148
+ import_zod5.z.object({
1149
+ type: import_zod5.z.literal("redacted_thinking"),
1150
+ data: import_zod5.z.string().optional()
904
1151
  })
905
1152
  ]);
906
- var AnthropicMessagesResponseSchema = import_zod4.z.object({
907
- content: import_zod4.z.array(AnthropicContentBlockSchema),
908
- stop_reason: import_zod4.z.string().nullable().optional(),
1153
+ var AnthropicMessagesResponseSchema = import_zod5.z.object({
1154
+ content: import_zod5.z.array(AnthropicContentBlockSchema),
1155
+ stop_reason: import_zod5.z.string().nullable().optional(),
909
1156
  usage: AnthropicUsageSchema
910
1157
  });
911
1158
  function mapAnthropicResponseToChatCompletionResult(response, latencyMs) {
912
1159
  const toolCalls = extractAnthropicToolCalls(response);
1160
+ const thinkingText = extractAnthropicThinkingText(response);
913
1161
  const result = {
914
1162
  content: extractAnthropicTextContent(response, toolCalls.length > 0),
915
1163
  tokenUsage: mapAnthropicUsageToTokenUsage(response.usage),
@@ -918,6 +1166,9 @@ function mapAnthropicResponseToChatCompletionResult(response, latencyMs) {
918
1166
  if (toolCalls.length > 0) {
919
1167
  result.toolCalls = toolCalls;
920
1168
  }
1169
+ if (thinkingText.length > 0) {
1170
+ result.thinkingText = thinkingText;
1171
+ }
921
1172
  if (response.stop_reason !== null && response.stop_reason !== void 0) {
922
1173
  result.stopReason = normalizeAnthropicStopReason(response.stop_reason);
923
1174
  }
@@ -930,13 +1181,16 @@ function extractAnthropicToolCalls(response) {
930
1181
  input: contentBlock.input
931
1182
  }));
932
1183
  }
1184
+ function extractAnthropicThinkingText(response) {
1185
+ return response.content.filter((contentBlock) => contentBlock.type === "thinking").map((contentBlock) => contentBlock.thinking ?? "").join("");
1186
+ }
933
1187
  function extractAnthropicTextContent(response, allowEmptyText) {
934
1188
  const textBlocks = response.content.filter(
935
1189
  (contentBlock) => contentBlock.type === "text"
936
1190
  );
937
1191
  if (textBlocks.length === 0 && !allowEmptyText) {
938
- throw new import_errors17.AppError({
939
- code: import_errors16.AppErrorCode.ValidationFailed,
1192
+ throw new import_errors19.AppError({
1193
+ code: import_errors18.AppErrorCode.ValidationFailed,
940
1194
  message: "Anthropic response contained no text content",
941
1195
  statusCode: 502
942
1196
  });
@@ -973,58 +1227,68 @@ function mapAnthropicUsageToTokenUsage(usage) {
973
1227
  }
974
1228
 
975
1229
  // src/anthropic-stream.ts
976
- var import_errors18 = require("@assemble-dev/shared-types/errors");
977
- var import_json5 = require("@assemble-dev/shared-types/json");
978
- var import_errors19 = require("@assemble-dev/shared-utils/errors");
1230
+ var import_errors20 = require("@assemble-dev/shared-types/errors");
1231
+ var import_json6 = require("@assemble-dev/shared-types/json");
1232
+ var import_errors21 = require("@assemble-dev/shared-utils/errors");
979
1233
 
980
1234
  // src/anthropic-stream-events.ts
981
- var import_zod5 = require("zod");
982
- var AnthropicStreamEventSchema = import_zod5.z.discriminatedUnion("type", [
983
- import_zod5.z.object({
984
- type: import_zod5.z.literal("message_start"),
985
- message: import_zod5.z.object({
986
- usage: import_zod5.z.object({
987
- input_tokens: import_zod5.z.number().int().nonnegative(),
988
- output_tokens: import_zod5.z.number().int().nonnegative().optional(),
989
- cache_creation_input_tokens: import_zod5.z.number().int().nonnegative().optional(),
990
- cache_read_input_tokens: import_zod5.z.number().int().nonnegative().optional()
1235
+ var import_zod6 = require("zod");
1236
+ var AnthropicStreamEventSchema = import_zod6.z.discriminatedUnion("type", [
1237
+ import_zod6.z.object({
1238
+ type: import_zod6.z.literal("message_start"),
1239
+ message: import_zod6.z.object({
1240
+ usage: import_zod6.z.object({
1241
+ input_tokens: import_zod6.z.number().int().nonnegative(),
1242
+ output_tokens: import_zod6.z.number().int().nonnegative().optional(),
1243
+ cache_creation_input_tokens: import_zod6.z.number().int().nonnegative().optional(),
1244
+ cache_read_input_tokens: import_zod6.z.number().int().nonnegative().optional()
991
1245
  })
992
1246
  })
993
1247
  }),
994
- import_zod5.z.object({
995
- type: import_zod5.z.literal("content_block_start"),
996
- index: import_zod5.z.number().int().nonnegative(),
997
- content_block: import_zod5.z.discriminatedUnion("type", [
998
- import_zod5.z.object({ type: import_zod5.z.literal("text"), text: import_zod5.z.string().optional() }),
999
- import_zod5.z.object({
1000
- type: import_zod5.z.literal("tool_use"),
1001
- id: import_zod5.z.string(),
1002
- name: import_zod5.z.string()
1248
+ import_zod6.z.object({
1249
+ type: import_zod6.z.literal("content_block_start"),
1250
+ index: import_zod6.z.number().int().nonnegative(),
1251
+ content_block: import_zod6.z.discriminatedUnion("type", [
1252
+ import_zod6.z.object({ type: import_zod6.z.literal("text"), text: import_zod6.z.string().optional() }),
1253
+ import_zod6.z.object({
1254
+ type: import_zod6.z.literal("thinking"),
1255
+ thinking: import_zod6.z.string().optional()
1256
+ }),
1257
+ import_zod6.z.object({
1258
+ type: import_zod6.z.literal("redacted_thinking"),
1259
+ data: import_zod6.z.string().optional()
1260
+ }),
1261
+ import_zod6.z.object({
1262
+ type: import_zod6.z.literal("tool_use"),
1263
+ id: import_zod6.z.string(),
1264
+ name: import_zod6.z.string()
1003
1265
  })
1004
1266
  ])
1005
1267
  }),
1006
- import_zod5.z.object({
1007
- type: import_zod5.z.literal("content_block_delta"),
1008
- index: import_zod5.z.number().int().nonnegative(),
1009
- delta: import_zod5.z.discriminatedUnion("type", [
1010
- import_zod5.z.object({ type: import_zod5.z.literal("text_delta"), text: import_zod5.z.string() }),
1011
- import_zod5.z.object({
1012
- type: import_zod5.z.literal("input_json_delta"),
1013
- partial_json: import_zod5.z.string()
1268
+ import_zod6.z.object({
1269
+ type: import_zod6.z.literal("content_block_delta"),
1270
+ index: import_zod6.z.number().int().nonnegative(),
1271
+ delta: import_zod6.z.discriminatedUnion("type", [
1272
+ import_zod6.z.object({ type: import_zod6.z.literal("text_delta"), text: import_zod6.z.string() }),
1273
+ import_zod6.z.object({ type: import_zod6.z.literal("thinking_delta"), thinking: import_zod6.z.string() }),
1274
+ import_zod6.z.object({ type: import_zod6.z.literal("signature_delta"), signature: import_zod6.z.string() }),
1275
+ import_zod6.z.object({
1276
+ type: import_zod6.z.literal("input_json_delta"),
1277
+ partial_json: import_zod6.z.string()
1014
1278
  })
1015
1279
  ])
1016
1280
  }),
1017
- import_zod5.z.object({ type: import_zod5.z.literal("content_block_stop") }),
1018
- import_zod5.z.object({
1019
- type: import_zod5.z.literal("message_delta"),
1020
- delta: import_zod5.z.object({ stop_reason: import_zod5.z.string().nullable().optional() }),
1021
- usage: import_zod5.z.object({ output_tokens: import_zod5.z.number().int().nonnegative() }).optional()
1281
+ import_zod6.z.object({ type: import_zod6.z.literal("content_block_stop") }),
1282
+ import_zod6.z.object({
1283
+ type: import_zod6.z.literal("message_delta"),
1284
+ delta: import_zod6.z.object({ stop_reason: import_zod6.z.string().nullable().optional() }),
1285
+ usage: import_zod6.z.object({ output_tokens: import_zod6.z.number().int().nonnegative() }).optional()
1022
1286
  }),
1023
- import_zod5.z.object({ type: import_zod5.z.literal("message_stop") }),
1024
- import_zod5.z.object({ type: import_zod5.z.literal("ping") }),
1025
- import_zod5.z.object({
1026
- type: import_zod5.z.literal("error"),
1027
- error: import_zod5.z.object({ message: import_zod5.z.string() })
1287
+ import_zod6.z.object({ type: import_zod6.z.literal("message_stop") }),
1288
+ import_zod6.z.object({ type: import_zod6.z.literal("ping") }),
1289
+ import_zod6.z.object({
1290
+ type: import_zod6.z.literal("error"),
1291
+ error: import_zod6.z.object({ message: import_zod6.z.string() })
1028
1292
  })
1029
1293
  ]);
1030
1294
 
@@ -1110,6 +1374,7 @@ async function* readServerSentEventDataLines(body, abortSignal) {
1110
1374
  function createAnthropicStreamAccumulator() {
1111
1375
  return {
1112
1376
  contentText: "",
1377
+ thinkingText: "",
1113
1378
  toolCallsByBlockIndex: /* @__PURE__ */ new Map(),
1114
1379
  inputTokens: 0,
1115
1380
  outputTokens: 0
@@ -1117,8 +1382,8 @@ function createAnthropicStreamAccumulator() {
1117
1382
  }
1118
1383
  function* applyAnthropicStreamEvent(event, accumulator) {
1119
1384
  if (event.type === "error") {
1120
- throw new import_errors19.AppError({
1121
- code: import_errors18.AppErrorCode.InternalServerError,
1385
+ throw new import_errors21.AppError({
1386
+ code: import_errors20.AppErrorCode.InternalServerError,
1122
1387
  message: `Anthropic stream reported an error: ${event.error.message}`,
1123
1388
  statusCode: 502
1124
1389
  });
@@ -1154,6 +1419,17 @@ function* applyAnthropicContentBlockStart(event, accumulator) {
1154
1419
  }
1155
1420
  return;
1156
1421
  }
1422
+ if (event.content_block.type === "thinking") {
1423
+ const initialThinkingText = event.content_block.thinking ?? "";
1424
+ if (initialThinkingText.length > 0) {
1425
+ accumulator.thinkingText += initialThinkingText;
1426
+ yield { type: "thinking_delta", text: initialThinkingText };
1427
+ }
1428
+ return;
1429
+ }
1430
+ if (event.content_block.type === "redacted_thinking") {
1431
+ return;
1432
+ }
1157
1433
  accumulator.toolCallsByBlockIndex.set(event.index, {
1158
1434
  id: event.content_block.id,
1159
1435
  toolName: event.content_block.name,
@@ -1171,6 +1447,14 @@ function* applyAnthropicContentBlockDelta(event, accumulator) {
1171
1447
  yield { type: "text_delta", text: event.delta.text };
1172
1448
  return;
1173
1449
  }
1450
+ if (event.delta.type === "thinking_delta") {
1451
+ accumulator.thinkingText += event.delta.thinking;
1452
+ yield { type: "thinking_delta", text: event.delta.thinking };
1453
+ return;
1454
+ }
1455
+ if (event.delta.type === "signature_delta") {
1456
+ return;
1457
+ }
1174
1458
  const toolCallAccumulation = accumulator.toolCallsByBlockIndex.get(
1175
1459
  event.index
1176
1460
  );
@@ -1217,6 +1501,9 @@ function buildAnthropicStreamResult(accumulator, latencyMs) {
1217
1501
  if (accumulator.stopReason !== void 0) {
1218
1502
  result.stopReason = accumulator.stopReason;
1219
1503
  }
1504
+ if (accumulator.thinkingText.length > 0) {
1505
+ result.thinkingText = accumulator.thinkingText;
1506
+ }
1220
1507
  return result;
1221
1508
  }
1222
1509
  function mapAccumulatedToolCallToModelToolCall(toolCallAccumulation) {
@@ -1231,10 +1518,10 @@ function parseAnthropicToolInputJson(inputJsonText) {
1231
1518
  return {};
1232
1519
  }
1233
1520
  try {
1234
- return import_json5.JsonValueSchema.parse(JSON.parse(inputJsonText));
1521
+ return import_json6.JsonValueSchema.parse(JSON.parse(inputJsonText));
1235
1522
  } catch (error) {
1236
- throw new import_errors19.AppError({
1237
- code: import_errors18.AppErrorCode.ValidationFailed,
1523
+ throw new import_errors21.AppError({
1524
+ code: import_errors20.AppErrorCode.ValidationFailed,
1238
1525
  message: "Anthropic tool input was not valid JSON",
1239
1526
  statusCode: 502,
1240
1527
  cause: error instanceof Error ? error : void 0
@@ -1246,10 +1533,6 @@ function parseAnthropicToolInputJson(inputJsonText) {
1246
1533
  var defaultAnthropicBaseUrl = "https://api.anthropic.com";
1247
1534
  var defaultAnthropicMaxOutputTokens = 1024;
1248
1535
  var anthropicApiVersion = "2023-06-01";
1249
- var structuredOutputSystemMessage2 = {
1250
- role: "system",
1251
- content: "Respond with a single JSON object that satisfies the caller's requested structure. Output only valid JSON with no surrounding text."
1252
- };
1253
1536
  function anthropic(options) {
1254
1537
  return {
1255
1538
  name: `anthropic:${options.model}`,
@@ -1261,9 +1544,12 @@ function anthropic(options) {
1261
1544
  },
1262
1545
  async generateStructuredOutput(request) {
1263
1546
  const completion = await executeAnthropicAdapterCall(options, {
1264
- messages: [structuredOutputSystemMessage2, ...request.messages],
1547
+ messages: request.messages,
1265
1548
  temperature: request.temperature ?? options.temperature,
1266
1549
  maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
1550
+ structuredOutputJsonSchema: buildAnthropicStructuredOutputJsonSchema(
1551
+ request.schema
1552
+ ),
1267
1553
  abortSignal: request.abortSignal
1268
1554
  });
1269
1555
  return {
@@ -1379,28 +1665,116 @@ function resolveAnthropicFetch(options) {
1379
1665
  }
1380
1666
 
1381
1667
  // src/gemini-adapter.ts
1382
- var import_zod6 = require("zod");
1383
- var import_errors20 = require("@assemble-dev/shared-types/errors");
1384
- var import_errors21 = require("@assemble-dev/shared-utils/errors");
1668
+ var import_zod7 = require("zod");
1669
+ var import_errors22 = require("@assemble-dev/shared-types/errors");
1670
+ var import_errors23 = require("@assemble-dev/shared-utils/errors");
1671
+
1672
+ // src/gemini-response-schema.ts
1673
+ var geminiAllowedSchemaKeywords = [
1674
+ "type",
1675
+ "format",
1676
+ "description",
1677
+ "nullable",
1678
+ "enum",
1679
+ "properties",
1680
+ "required",
1681
+ "items",
1682
+ "minItems",
1683
+ "maxItems",
1684
+ "anyOf"
1685
+ ];
1686
+ var geminiAllowedFormats = [
1687
+ "date-time",
1688
+ "int32",
1689
+ "int64",
1690
+ "float",
1691
+ "double"
1692
+ ];
1693
+ function buildGeminiResponseSchema(schema) {
1694
+ return sanitizeJsonSchemaForGeminiResponseSchema(
1695
+ convertZodSchemaToJsonSchema(schema)
1696
+ );
1697
+ }
1698
+ function sanitizeJsonSchemaForGeminiResponseSchema(jsonSchema) {
1699
+ return transformJsonSchemaNode(
1700
+ inlineJsonSchemaReferences(jsonSchema),
1701
+ sanitizeGeminiSchemaNode
1702
+ );
1703
+ }
1704
+ function sanitizeGeminiSchemaNode(node) {
1705
+ const normalized = normalizeGeminiNullableType(
1706
+ mergeNullUnionIntoNullableNode(node)
1707
+ );
1708
+ const sanitized = {};
1709
+ for (const [key, value] of Object.entries(normalized)) {
1710
+ if (geminiAllowedSchemaKeywords.includes(key)) {
1711
+ sanitized[key] = value;
1712
+ }
1713
+ }
1714
+ return removeUnsupportedGeminiFormat(sanitized);
1715
+ }
1716
+ function mergeNullUnionIntoNullableNode(node) {
1717
+ const unionKeyword = Array.isArray(node["anyOf"]) ? "anyOf" : "oneOf";
1718
+ const unionMembers = node[unionKeyword];
1719
+ if (!Array.isArray(unionMembers)) {
1720
+ return node;
1721
+ }
1722
+ const nonNullMembers = unionMembers.filter(
1723
+ (member) => !isNullTypeSchemaNode(member)
1724
+ );
1725
+ if (nonNullMembers.length === unionMembers.length) {
1726
+ return node;
1727
+ }
1728
+ const merged = { ...node };
1729
+ delete merged[unionKeyword];
1730
+ const singleMember = nonNullMembers.length === 1 ? nonNullMembers[0] : void 0;
1731
+ if (singleMember !== void 0 && isJsonObject(singleMember)) {
1732
+ return { ...merged, ...singleMember, nullable: true };
1733
+ }
1734
+ return { ...merged, anyOf: nonNullMembers, nullable: true };
1735
+ }
1736
+ function normalizeGeminiNullableType(node) {
1737
+ const typeValue = node["type"];
1738
+ if (!Array.isArray(typeValue)) {
1739
+ return node;
1740
+ }
1741
+ const nonNullTypes = typeValue.filter((typeName) => typeName !== "null");
1742
+ const normalized = { ...node };
1743
+ if (nonNullTypes.length < typeValue.length) {
1744
+ normalized["nullable"] = true;
1745
+ }
1746
+ normalized["type"] = nonNullTypes[0] ?? "string";
1747
+ return normalized;
1748
+ }
1749
+ function removeUnsupportedGeminiFormat(node) {
1750
+ const formatValue = node["format"];
1751
+ if (typeof formatValue === "string" && !geminiAllowedFormats.includes(formatValue)) {
1752
+ const withoutFormat = { ...node };
1753
+ delete withoutFormat["format"];
1754
+ return withoutFormat;
1755
+ }
1756
+ return node;
1757
+ }
1758
+ function isNullTypeSchemaNode(value) {
1759
+ return isJsonObject(value) && value["type"] === "null";
1760
+ }
1761
+
1762
+ // src/gemini-adapter.ts
1385
1763
  var defaultGeminiBaseUrl = "https://generativelanguage.googleapis.com";
1386
- var GeminiGenerateContentResponseSchema = import_zod6.z.object({
1387
- candidates: import_zod6.z.array(
1388
- import_zod6.z.object({
1389
- content: import_zod6.z.object({
1390
- parts: import_zod6.z.array(import_zod6.z.object({ text: import_zod6.z.string() }))
1764
+ var GeminiGenerateContentResponseSchema = import_zod7.z.object({
1765
+ candidates: import_zod7.z.array(
1766
+ import_zod7.z.object({
1767
+ content: import_zod7.z.object({
1768
+ parts: import_zod7.z.array(import_zod7.z.object({ text: import_zod7.z.string() }))
1391
1769
  })
1392
1770
  })
1393
1771
  ).optional(),
1394
- usageMetadata: import_zod6.z.object({
1395
- promptTokenCount: import_zod6.z.number().int().nonnegative().optional(),
1396
- candidatesTokenCount: import_zod6.z.number().int().nonnegative().optional(),
1397
- totalTokenCount: import_zod6.z.number().int().nonnegative().optional()
1772
+ usageMetadata: import_zod7.z.object({
1773
+ promptTokenCount: import_zod7.z.number().int().nonnegative().optional(),
1774
+ candidatesTokenCount: import_zod7.z.number().int().nonnegative().optional(),
1775
+ totalTokenCount: import_zod7.z.number().int().nonnegative().optional()
1398
1776
  }).optional()
1399
1777
  });
1400
- var structuredOutputSystemMessage3 = {
1401
- role: "system",
1402
- content: "Respond with a single JSON object that satisfies the caller's requested structure. Output only valid JSON with no surrounding text."
1403
- };
1404
1778
  function gemini(options) {
1405
1779
  return {
1406
1780
  name: `gemini:${options.model}`,
@@ -1410,17 +1784,16 @@ function gemini(options) {
1410
1784
  messages: request.messages,
1411
1785
  temperature: request.temperature ?? options.temperature,
1412
1786
  maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
1413
- requireJsonResponse: false,
1414
1787
  abortSignal: request.abortSignal,
1415
1788
  extraBody: request.extraBody
1416
1789
  });
1417
1790
  },
1418
1791
  async generateStructuredOutput(request) {
1419
1792
  const completion = await executeGeminiAdapterCall(options, {
1420
- messages: [structuredOutputSystemMessage3, ...request.messages],
1793
+ messages: request.messages,
1421
1794
  temperature: request.temperature ?? options.temperature,
1422
1795
  maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
1423
- requireJsonResponse: true,
1796
+ responseSchema: buildGeminiResponseSchema(request.schema),
1424
1797
  abortSignal: request.abortSignal
1425
1798
  });
1426
1799
  return {
@@ -1507,8 +1880,8 @@ function ensureGeminiRequestHasNoTools(request) {
1507
1880
  if (request.tools === void 0 || request.tools.length === 0) {
1508
1881
  return;
1509
1882
  }
1510
- throw new import_errors21.AppError({
1511
- code: import_errors20.AppErrorCode.ValidationFailed,
1883
+ throw new import_errors23.AppError({
1884
+ code: import_errors22.AppErrorCode.ValidationFailed,
1512
1885
  message: "gemini adapter does not support model-driven tool use; remove tools from the request or use another adapter",
1513
1886
  statusCode: 400
1514
1887
  });
@@ -1545,8 +1918,9 @@ function buildGeminiGenerationConfig(input) {
1545
1918
  if (input.maxOutputTokens !== void 0) {
1546
1919
  generationConfig.maxOutputTokens = input.maxOutputTokens;
1547
1920
  }
1548
- if (input.requireJsonResponse) {
1921
+ if (input.responseSchema !== void 0) {
1549
1922
  generationConfig.responseMimeType = "application/json";
1923
+ generationConfig.responseSchema = input.responseSchema;
1550
1924
  }
1551
1925
  if (Object.keys(generationConfig).length === 0) {
1552
1926
  return void 0;
@@ -1556,8 +1930,8 @@ function buildGeminiGenerationConfig(input) {
1556
1930
  function extractGeminiCandidateText(response) {
1557
1931
  const firstCandidate = response.candidates?.[0];
1558
1932
  if (firstCandidate === void 0) {
1559
- throw new import_errors21.AppError({
1560
- code: import_errors20.AppErrorCode.ValidationFailed,
1933
+ throw new import_errors23.AppError({
1934
+ code: import_errors22.AppErrorCode.ValidationFailed,
1561
1935
  message: "Gemini response contained no candidates",
1562
1936
  statusCode: 502
1563
1937
  });
@@ -1576,8 +1950,8 @@ function mapGeminiUsageToTokenUsage(response) {
1576
1950
  }
1577
1951
 
1578
1952
  // src/mock-adapter.ts
1579
- var import_errors22 = require("@assemble-dev/shared-types/errors");
1580
- var import_errors23 = require("@assemble-dev/shared-utils/errors");
1953
+ var import_errors24 = require("@assemble-dev/shared-types/errors");
1954
+ var import_errors25 = require("@assemble-dev/shared-utils/errors");
1581
1955
  var mockStreamChunkCount = 3;
1582
1956
  function mockModel(options = {}) {
1583
1957
  const remainingScriptedResponses = [...options.scriptedResponses ?? []];
@@ -1657,8 +2031,8 @@ function resolveNextMockResponseText(request, remainingScriptedResponses, respon
1657
2031
  if (respond !== void 0) {
1658
2032
  return respond(request);
1659
2033
  }
1660
- throw new import_errors23.AppError({
1661
- code: import_errors22.AppErrorCode.BadRequest,
2034
+ throw new import_errors25.AppError({
2035
+ code: import_errors24.AppErrorCode.BadRequest,
1662
2036
  message: "Mock model has no scripted responses left and no respond function was provided",
1663
2037
  statusCode: 400
1664
2038
  });
@@ -1746,24 +2120,24 @@ function calculateModelCallCostUsd(pricing, tokenUsage) {
1746
2120
  }
1747
2121
 
1748
2122
  // src/anthropic-batch.ts
2123
+ var import_errors28 = require("@assemble-dev/shared-types/errors");
2124
+ var import_json8 = require("@assemble-dev/shared-types/json");
2125
+ var import_errors29 = require("@assemble-dev/shared-utils/errors");
2126
+
2127
+ // src/anthropic-batch-structured.ts
1749
2128
  var import_errors26 = require("@assemble-dev/shared-types/errors");
1750
2129
  var import_json7 = require("@assemble-dev/shared-types/json");
1751
2130
  var import_errors27 = require("@assemble-dev/shared-utils/errors");
1752
-
1753
- // src/anthropic-batch-structured.ts
1754
- var import_errors24 = require("@assemble-dev/shared-types/errors");
1755
- var import_json6 = require("@assemble-dev/shared-types/json");
1756
- var import_errors25 = require("@assemble-dev/shared-utils/errors");
1757
2131
  var anthropicBatchJsonOnlySystemInstruction = "Respond with a single JSON object that satisfies the caller's requested structure. Output only valid JSON with no surrounding text.";
1758
2132
  function parseAnthropicBatchStructuredContent(content, schema) {
1759
2133
  const jsonValue = parseStructuredJsonText(
1760
2134
  content,
1761
- import_json6.JsonValueSchema
2135
+ import_json7.JsonValueSchema
1762
2136
  );
1763
2137
  const validationResult = schema.safeParse(jsonValue);
1764
2138
  if (!validationResult.success) {
1765
- throw new import_errors25.AppError({
1766
- code: import_errors24.AppErrorCode.ValidationFailed,
2139
+ throw new import_errors27.AppError({
2140
+ code: import_errors26.AppErrorCode.ValidationFailed,
1767
2141
  message: "Anthropic batch structured output did not match the expected schema",
1768
2142
  statusCode: 422,
1769
2143
  details: { validationErrorMessage: validationResult.error.message }
@@ -1780,11 +2154,25 @@ function mapBatchMessageRequestToApiBatchRequest(request) {
1780
2154
  messages: request.messages.filter((message) => message.role !== "system").map(mapChatMessageToBatchApiRequestMessage)
1781
2155
  };
1782
2156
  applyBatchSystemField(params, request);
2157
+ applyBatchStructuredOutputConfig(params, request);
1783
2158
  if (request.temperature !== void 0) {
1784
2159
  params.temperature = request.temperature;
1785
2160
  }
1786
2161
  return { custom_id: request.customId, params };
1787
2162
  }
2163
+ function applyBatchStructuredOutputConfig(params, request) {
2164
+ if (request.structuredOutputJsonSchema === void 0) {
2165
+ return;
2166
+ }
2167
+ params.output_config = {
2168
+ format: {
2169
+ type: "json_schema",
2170
+ schema: sanitizeJsonSchemaForAnthropicStructuredOutput(
2171
+ request.structuredOutputJsonSchema
2172
+ )
2173
+ }
2174
+ };
2175
+ }
1788
2176
  function applyBatchSystemField(params, request) {
1789
2177
  const systemText = buildBatchSystemText(request);
1790
2178
  if (systemText.length === 0) {
@@ -1800,7 +2188,7 @@ function applyBatchSystemField(params, request) {
1800
2188
  }
1801
2189
  function buildBatchSystemText(request) {
1802
2190
  const joinedSystemText = joinBatchSystemMessageText(request.messages);
1803
- if (request.requireJsonResponse !== true) {
2191
+ if (request.requireJsonResponse !== true || request.structuredOutputJsonSchema !== void 0) {
1804
2192
  return joinedSystemText;
1805
2193
  }
1806
2194
  if (joinedSystemText.length === 0) {
@@ -1951,55 +2339,55 @@ function buildBatchResultEvent(eventBase, batchId, result, modelName) {
1951
2339
  }
1952
2340
 
1953
2341
  // src/anthropic-batch-types.ts
1954
- var import_zod7 = require("zod");
1955
- var AnthropicMessageBatchResponseSchema = import_zod7.z.object({
1956
- id: import_zod7.z.string(),
1957
- processing_status: import_zod7.z.enum(["in_progress", "canceling", "ended"]),
1958
- request_counts: import_zod7.z.object({
1959
- processing: import_zod7.z.number().int().nonnegative(),
1960
- succeeded: import_zod7.z.number().int().nonnegative(),
1961
- errored: import_zod7.z.number().int().nonnegative(),
1962
- canceled: import_zod7.z.number().int().nonnegative(),
1963
- expired: import_zod7.z.number().int().nonnegative()
2342
+ var import_zod8 = require("zod");
2343
+ var AnthropicMessageBatchResponseSchema = import_zod8.z.object({
2344
+ id: import_zod8.z.string(),
2345
+ processing_status: import_zod8.z.enum(["in_progress", "canceling", "ended"]),
2346
+ request_counts: import_zod8.z.object({
2347
+ processing: import_zod8.z.number().int().nonnegative(),
2348
+ succeeded: import_zod8.z.number().int().nonnegative(),
2349
+ errored: import_zod8.z.number().int().nonnegative(),
2350
+ canceled: import_zod8.z.number().int().nonnegative(),
2351
+ expired: import_zod8.z.number().int().nonnegative()
1964
2352
  }),
1965
- results_url: import_zod7.z.string().nullable(),
1966
- created_at: import_zod7.z.string(),
1967
- ended_at: import_zod7.z.string().nullable()
2353
+ results_url: import_zod8.z.string().nullable(),
2354
+ created_at: import_zod8.z.string(),
2355
+ ended_at: import_zod8.z.string().nullable()
1968
2356
  });
1969
- var AnthropicBatchContentBlockSchema = import_zod7.z.discriminatedUnion("type", [
1970
- import_zod7.z.object({
1971
- type: import_zod7.z.literal("text"),
1972
- text: import_zod7.z.string()
2357
+ var AnthropicBatchContentBlockSchema = import_zod8.z.discriminatedUnion("type", [
2358
+ import_zod8.z.object({
2359
+ type: import_zod8.z.literal("text"),
2360
+ text: import_zod8.z.string()
1973
2361
  }),
1974
- import_zod7.z.object({
1975
- type: import_zod7.z.literal("thinking"),
1976
- thinking: import_zod7.z.string().optional(),
1977
- signature: import_zod7.z.string().optional()
2362
+ import_zod8.z.object({
2363
+ type: import_zod8.z.literal("thinking"),
2364
+ thinking: import_zod8.z.string().optional(),
2365
+ signature: import_zod8.z.string().optional()
1978
2366
  }),
1979
- import_zod7.z.object({
1980
- type: import_zod7.z.literal("redacted_thinking"),
1981
- data: import_zod7.z.string().optional()
2367
+ import_zod8.z.object({
2368
+ type: import_zod8.z.literal("redacted_thinking"),
2369
+ data: import_zod8.z.string().optional()
1982
2370
  })
1983
2371
  ]);
1984
- var AnthropicBatchResultLineSchema = import_zod7.z.object({
1985
- custom_id: import_zod7.z.string(),
1986
- result: import_zod7.z.discriminatedUnion("type", [
1987
- import_zod7.z.object({
1988
- type: import_zod7.z.literal("succeeded"),
1989
- message: import_zod7.z.object({
1990
- content: import_zod7.z.array(AnthropicBatchContentBlockSchema),
2372
+ var AnthropicBatchResultLineSchema = import_zod8.z.object({
2373
+ custom_id: import_zod8.z.string(),
2374
+ result: import_zod8.z.discriminatedUnion("type", [
2375
+ import_zod8.z.object({
2376
+ type: import_zod8.z.literal("succeeded"),
2377
+ message: import_zod8.z.object({
2378
+ content: import_zod8.z.array(AnthropicBatchContentBlockSchema),
1991
2379
  usage: AnthropicUsageSchema
1992
2380
  })
1993
2381
  }),
1994
- import_zod7.z.object({
1995
- type: import_zod7.z.literal("errored"),
1996
- error: import_zod7.z.object({
1997
- type: import_zod7.z.string(),
1998
- message: import_zod7.z.string()
2382
+ import_zod8.z.object({
2383
+ type: import_zod8.z.literal("errored"),
2384
+ error: import_zod8.z.object({
2385
+ type: import_zod8.z.string(),
2386
+ message: import_zod8.z.string()
1999
2387
  })
2000
2388
  }),
2001
- import_zod7.z.object({ type: import_zod7.z.literal("canceled") }),
2002
- import_zod7.z.object({ type: import_zod7.z.literal("expired") })
2389
+ import_zod8.z.object({ type: import_zod8.z.literal("canceled") }),
2390
+ import_zod8.z.object({ type: import_zod8.z.literal("expired") })
2003
2391
  ])
2004
2392
  });
2005
2393
  function mapAnthropicMessageBatchResponseToMessageBatch(response) {
@@ -2149,8 +2537,8 @@ async function parseAnthropicMessageBatchHttpResponse(response) {
2149
2537
  async function listAnthropicMessageBatchResults(clientContext, batchId) {
2150
2538
  const batch = await fetchAnthropicMessageBatch(clientContext, batchId);
2151
2539
  if (batch.resultsUrl === null) {
2152
- throw new import_errors27.AppError({
2153
- code: import_errors26.AppErrorCode.Conflict,
2540
+ throw new import_errors29.AppError({
2541
+ code: import_errors28.AppErrorCode.Conflict,
2154
2542
  message: `Anthropic message batch ${batchId} has no results because processing has not ended`,
2155
2543
  statusCode: 409,
2156
2544
  details: { batchId, processingStatus: batch.processingStatus }
@@ -2187,7 +2575,7 @@ function parseAnthropicBatchResultLine(line) {
2187
2575
  }
2188
2576
  function parseAnthropicBatchResultLineJson(line) {
2189
2577
  try {
2190
- return import_json7.JsonValueSchema.parse(JSON.parse(line));
2578
+ return import_json8.JsonValueSchema.parse(JSON.parse(line));
2191
2579
  } catch {
2192
2580
  throw buildProviderInvalidResponseError(
2193
2581
  "Anthropic",
@@ -2211,17 +2599,761 @@ async function waitForAnthropicMessageBatchCompletion(clientContext, batchId, wa
2211
2599
  return batch;
2212
2600
  }
2213
2601
  function buildAnthropicBatchTimeoutError(batchId, timeoutMs) {
2214
- return new import_errors27.AppError({
2215
- code: import_errors26.AppErrorCode.ServiceUnavailable,
2602
+ return new import_errors29.AppError({
2603
+ code: import_errors28.AppErrorCode.ServiceUnavailable,
2216
2604
  message: `Anthropic message batch ${batchId} did not complete within ${String(timeoutMs)}ms`,
2217
2605
  statusCode: 504,
2218
2606
  details: { batchId, timeoutMs }
2219
2607
  });
2220
2608
  }
2609
+
2610
+ // src/azure-openai-adapter.ts
2611
+ var import_errors32 = require("@assemble-dev/shared-types/errors");
2612
+ var import_errors33 = require("@assemble-dev/shared-utils/errors");
2613
+
2614
+ // src/azure-openai-response-parsing.ts
2615
+ var import_zod9 = require("zod");
2616
+ var import_errors30 = require("@assemble-dev/shared-types/errors");
2617
+ var import_json9 = require("@assemble-dev/shared-types/json");
2618
+ var import_errors31 = require("@assemble-dev/shared-utils/errors");
2619
+ var AzureOpenAiUsageSchema = import_zod9.z.object({
2620
+ prompt_tokens: import_zod9.z.number().int().nonnegative(),
2621
+ completion_tokens: import_zod9.z.number().int().nonnegative(),
2622
+ total_tokens: import_zod9.z.number().int().nonnegative()
2623
+ });
2624
+ var AzureOpenAiResponseToolCallSchema = import_zod9.z.object({
2625
+ id: import_zod9.z.string(),
2626
+ function: import_zod9.z.object({
2627
+ name: import_zod9.z.string(),
2628
+ arguments: import_zod9.z.string()
2629
+ })
2630
+ });
2631
+ var AzureOpenAiChatCompletionResponseSchema = import_zod9.z.object({
2632
+ choices: import_zod9.z.array(
2633
+ import_zod9.z.object({
2634
+ message: import_zod9.z.object({
2635
+ content: import_zod9.z.string().nullable(),
2636
+ tool_calls: import_zod9.z.array(AzureOpenAiResponseToolCallSchema).optional()
2637
+ }),
2638
+ finish_reason: import_zod9.z.string().nullable().optional()
2639
+ })
2640
+ ).min(1),
2641
+ usage: AzureOpenAiUsageSchema
2642
+ });
2643
+ function mapAzureOpenAiResponseToChatCompletionResult(response, latencyMs) {
2644
+ const toolCalls = extractAzureOpenAiToolCalls(response);
2645
+ const result = {
2646
+ content: extractAzureOpenAiMessageContent(response, toolCalls.length > 0),
2647
+ tokenUsage: mapAzureOpenAiUsageToTokenUsage(response.usage),
2648
+ latencyMs
2649
+ };
2650
+ const finishReason = response.choices[0]?.finish_reason;
2651
+ if (toolCalls.length > 0) {
2652
+ result.toolCalls = toolCalls;
2653
+ }
2654
+ if (finishReason !== null && finishReason !== void 0) {
2655
+ result.stopReason = normalizeAzureOpenAiFinishReason(finishReason);
2656
+ }
2657
+ return result;
2658
+ }
2659
+ function extractAzureOpenAiToolCalls(response) {
2660
+ const responseToolCalls = response.choices[0]?.message.tool_calls ?? [];
2661
+ return responseToolCalls.map((responseToolCall) => ({
2662
+ id: responseToolCall.id,
2663
+ toolName: responseToolCall.function.name,
2664
+ input: parseAzureOpenAiToolArgumentsJson(responseToolCall.function.arguments)
2665
+ }));
2666
+ }
2667
+ function parseAzureOpenAiToolArgumentsJson(argumentsJsonText) {
2668
+ if (argumentsJsonText.trim().length === 0) {
2669
+ return {};
2670
+ }
2671
+ try {
2672
+ return import_json9.JsonValueSchema.parse(JSON.parse(argumentsJsonText));
2673
+ } catch (error) {
2674
+ throw new import_errors31.AppError({
2675
+ code: import_errors30.AppErrorCode.ValidationFailed,
2676
+ message: "Azure OpenAI tool call arguments were not valid JSON",
2677
+ statusCode: 502,
2678
+ cause: error instanceof Error ? error : void 0
2679
+ });
2680
+ }
2681
+ }
2682
+ function normalizeAzureOpenAiFinishReason(finishReason) {
2683
+ if (finishReason === "tool_calls") {
2684
+ return "tool_use";
2685
+ }
2686
+ if (finishReason === "length") {
2687
+ return "max_tokens";
2688
+ }
2689
+ return "end_turn";
2690
+ }
2691
+ function extractAzureOpenAiMessageContent(response, allowEmptyContent) {
2692
+ const content = response.choices[0]?.message.content;
2693
+ if (content === void 0 || content === null) {
2694
+ if (allowEmptyContent) {
2695
+ return "";
2696
+ }
2697
+ throw new import_errors31.AppError({
2698
+ code: import_errors30.AppErrorCode.ValidationFailed,
2699
+ message: "Azure OpenAI response contained no message content",
2700
+ statusCode: 502
2701
+ });
2702
+ }
2703
+ return content;
2704
+ }
2705
+ function mapAzureOpenAiUsageToTokenUsage(usage) {
2706
+ return {
2707
+ inputTokens: usage.prompt_tokens,
2708
+ outputTokens: usage.completion_tokens,
2709
+ totalTokens: usage.total_tokens
2710
+ };
2711
+ }
2712
+
2713
+ // src/azure-openai-stream.ts
2714
+ var import_zod10 = require("zod");
2715
+ var AzureOpenAiStreamToolCallDeltaSchema = import_zod10.z.object({
2716
+ index: import_zod10.z.number().int().nonnegative(),
2717
+ id: import_zod10.z.string().optional(),
2718
+ function: import_zod10.z.object({
2719
+ name: import_zod10.z.string().optional(),
2720
+ arguments: import_zod10.z.string().optional()
2721
+ }).optional()
2722
+ });
2723
+ var AzureOpenAiStreamChunkSchema = import_zod10.z.object({
2724
+ choices: import_zod10.z.array(
2725
+ import_zod10.z.object({
2726
+ delta: import_zod10.z.object({
2727
+ content: import_zod10.z.string().nullable().optional(),
2728
+ tool_calls: import_zod10.z.array(AzureOpenAiStreamToolCallDeltaSchema).optional()
2729
+ }).optional(),
2730
+ finish_reason: import_zod10.z.string().nullable().optional()
2731
+ })
2732
+ ).optional(),
2733
+ usage: AzureOpenAiUsageSchema.nullable().optional()
2734
+ });
2735
+ async function* streamAzureOpenAiChatCompletion(input) {
2736
+ const startedAt = Date.now();
2737
+ const response = await establishAzureOpenAiStreamResponse(input);
2738
+ if (response.body === null) {
2739
+ throw buildProviderInvalidResponseError("Azure OpenAI", "stream body");
2740
+ }
2741
+ yield* parseAzureOpenAiStreamEvents(
2742
+ response.body,
2743
+ startedAt,
2744
+ input.abortSignal
2745
+ );
2746
+ }
2747
+ async function establishAzureOpenAiStreamResponse(input) {
2748
+ return await executeProviderCallWithRetry(input.retry, async () => {
2749
+ const response = await executeAbortableProviderFetch(
2750
+ "Azure OpenAI",
2751
+ async () => await input.fetchImplementation(input.url, {
2752
+ method: "POST",
2753
+ headers: input.headers,
2754
+ body: JSON.stringify(input.body),
2755
+ signal: input.abortSignal
2756
+ })
2757
+ );
2758
+ if (!response.ok) {
2759
+ throw buildProviderStatusError("Azure OpenAI", response.status);
2760
+ }
2761
+ return response;
2762
+ });
2763
+ }
2764
+ async function* parseAzureOpenAiStreamEvents(body, startedAt, abortSignal) {
2765
+ const accumulator = createAzureOpenAiStreamAccumulator();
2766
+ for await (const dataText of readServerSentEventDataLines2(body, abortSignal)) {
2767
+ if (dataText === "[DONE]") {
2768
+ yield {
2769
+ type: "completed",
2770
+ result: buildAzureOpenAiStreamResult(
2771
+ accumulator,
2772
+ Date.now() - startedAt
2773
+ )
2774
+ };
2775
+ return;
2776
+ }
2777
+ const parsedChunk = AzureOpenAiStreamChunkSchema.safeParse(
2778
+ JSON.parse(dataText)
2779
+ );
2780
+ if (!parsedChunk.success) {
2781
+ continue;
2782
+ }
2783
+ yield* applyAzureOpenAiStreamChunk(parsedChunk.data, accumulator);
2784
+ }
2785
+ throw buildProviderInvalidResponseError("Azure OpenAI", "stream termination");
2786
+ }
2787
+ async function* readServerSentEventDataLines2(body, abortSignal) {
2788
+ const reader = body.getReader();
2789
+ const decoder = new TextDecoder();
2790
+ let bufferedText = "";
2791
+ try {
2792
+ for (; ; ) {
2793
+ if (abortSignal?.aborted === true) {
2794
+ await reader.cancel();
2795
+ throw buildProviderCanceledError("Azure OpenAI");
2796
+ }
2797
+ const readResult = await reader.read();
2798
+ if (readResult.done) {
2799
+ return;
2800
+ }
2801
+ bufferedText += decoder.decode(readResult.value, { stream: true });
2802
+ const lines = bufferedText.split("\n");
2803
+ bufferedText = lines.pop() ?? "";
2804
+ for (const line of lines) {
2805
+ if (line.startsWith("data:")) {
2806
+ const dataText = line.slice("data:".length).trim();
2807
+ if (dataText.length > 0) {
2808
+ yield dataText;
2809
+ }
2810
+ }
2811
+ }
2812
+ }
2813
+ } catch (error) {
2814
+ if (error instanceof Error && isAbortError(error)) {
2815
+ throw buildProviderCanceledError("Azure OpenAI");
2816
+ }
2817
+ throw error;
2818
+ }
2819
+ }
2820
+ function createAzureOpenAiStreamAccumulator() {
2821
+ return {
2822
+ contentText: "",
2823
+ toolCallsByIndex: /* @__PURE__ */ new Map()
2824
+ };
2825
+ }
2826
+ function* applyAzureOpenAiStreamChunk(chunk, accumulator) {
2827
+ if (chunk.usage !== null && chunk.usage !== void 0) {
2828
+ accumulator.usage = chunk.usage;
2829
+ }
2830
+ const choice = chunk.choices?.[0];
2831
+ if (choice === void 0) {
2832
+ return;
2833
+ }
2834
+ if (choice.finish_reason !== null && choice.finish_reason !== void 0) {
2835
+ accumulator.finishReason = choice.finish_reason;
2836
+ }
2837
+ if (choice.delta === void 0) {
2838
+ return;
2839
+ }
2840
+ const contentDelta = choice.delta.content;
2841
+ if (contentDelta !== null && contentDelta !== void 0 && contentDelta.length > 0) {
2842
+ accumulator.contentText += contentDelta;
2843
+ yield { type: "text_delta", text: contentDelta };
2844
+ }
2845
+ for (const toolCallDelta of choice.delta.tool_calls ?? []) {
2846
+ yield* applyAzureOpenAiToolCallDelta(toolCallDelta, accumulator);
2847
+ }
2848
+ }
2849
+ function* applyAzureOpenAiToolCallDelta(toolCallDelta, accumulator) {
2850
+ const existingToolCall = accumulator.toolCallsByIndex.get(toolCallDelta.index);
2851
+ if (existingToolCall === void 0) {
2852
+ yield* startAzureOpenAiToolCallAccumulation(toolCallDelta, accumulator);
2853
+ return;
2854
+ }
2855
+ const argumentsDelta = toolCallDelta.function?.arguments;
2856
+ if (argumentsDelta !== void 0 && argumentsDelta.length > 0) {
2857
+ existingToolCall.argumentsJsonText += argumentsDelta;
2858
+ yield {
2859
+ type: "tool_call_input_delta",
2860
+ id: existingToolCall.id,
2861
+ inputJsonText: argumentsDelta
2862
+ };
2863
+ }
2864
+ }
2865
+ function* startAzureOpenAiToolCallAccumulation(toolCallDelta, accumulator) {
2866
+ const toolName = toolCallDelta.function?.name;
2867
+ if (toolCallDelta.id === void 0 || toolName === void 0) {
2868
+ throw buildProviderInvalidResponseError(
2869
+ "Azure OpenAI",
2870
+ "stream tool call start"
2871
+ );
2872
+ }
2873
+ const startedToolCall = {
2874
+ id: toolCallDelta.id,
2875
+ toolName,
2876
+ argumentsJsonText: toolCallDelta.function?.arguments ?? ""
2877
+ };
2878
+ accumulator.toolCallsByIndex.set(toolCallDelta.index, startedToolCall);
2879
+ yield {
2880
+ type: "tool_call_started",
2881
+ id: startedToolCall.id,
2882
+ toolName: startedToolCall.toolName
2883
+ };
2884
+ if (startedToolCall.argumentsJsonText.length > 0) {
2885
+ yield {
2886
+ type: "tool_call_input_delta",
2887
+ id: startedToolCall.id,
2888
+ inputJsonText: startedToolCall.argumentsJsonText
2889
+ };
2890
+ }
2891
+ }
2892
+ function buildAzureOpenAiStreamResult(accumulator, latencyMs) {
2893
+ const result = {
2894
+ content: accumulator.contentText,
2895
+ tokenUsage: mapAzureOpenAiUsageToTokenUsage(
2896
+ accumulator.usage ?? {
2897
+ prompt_tokens: 0,
2898
+ completion_tokens: 0,
2899
+ total_tokens: 0
2900
+ }
2901
+ ),
2902
+ latencyMs
2903
+ };
2904
+ const toolCalls = [...accumulator.toolCallsByIndex.values()].map(
2905
+ mapAccumulatedToolCallToModelToolCall2
2906
+ );
2907
+ if (toolCalls.length > 0) {
2908
+ result.toolCalls = toolCalls;
2909
+ }
2910
+ if (accumulator.finishReason !== void 0) {
2911
+ result.stopReason = normalizeAzureOpenAiFinishReason(
2912
+ accumulator.finishReason
2913
+ );
2914
+ }
2915
+ return result;
2916
+ }
2917
+ function mapAccumulatedToolCallToModelToolCall2(toolCallAccumulation) {
2918
+ return {
2919
+ id: toolCallAccumulation.id,
2920
+ toolName: toolCallAccumulation.toolName,
2921
+ input: parseAzureOpenAiToolArgumentsJson(
2922
+ toolCallAccumulation.argumentsJsonText
2923
+ )
2924
+ };
2925
+ }
2926
+
2927
+ // src/azure-openai-adapter.ts
2928
+ var defaultAzureOpenAiApiVersion = "2024-10-21";
2929
+ var azureDeploymentModelPlaceholder = "azure-deployment";
2930
+ function azureOpenai(options) {
2931
+ return {
2932
+ name: `azure-openai:${options.deployment}`,
2933
+ async generateChatCompletion(request) {
2934
+ return await executeAzureOpenAiAdapterCall(options, {
2935
+ messages: request.messages,
2936
+ temperature: request.temperature ?? options.temperature,
2937
+ maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
2938
+ tools: request.tools,
2939
+ toolChoice: request.toolChoice,
2940
+ abortSignal: request.abortSignal,
2941
+ extraBody: request.extraBody
2942
+ });
2943
+ },
2944
+ async generateStructuredOutput(request) {
2945
+ const completion = await executeAzureOpenAiAdapterCall(options, {
2946
+ messages: request.messages,
2947
+ temperature: request.temperature ?? options.temperature,
2948
+ maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
2949
+ structuredOutputJsonSchema: buildOpenAiStructuredOutputJsonSchema(
2950
+ request.schema
2951
+ ),
2952
+ abortSignal: request.abortSignal
2953
+ });
2954
+ return {
2955
+ value: parseStructuredJsonText(completion.content, request.schema),
2956
+ tokenUsage: completion.tokenUsage,
2957
+ latencyMs: completion.latencyMs
2958
+ };
2959
+ },
2960
+ streamChatCompletion(request) {
2961
+ return streamAzureOpenAiChatCompletion(
2962
+ buildAzureOpenAiStreamInput(options, request)
2963
+ );
2964
+ }
2965
+ };
2966
+ }
2967
+ function buildAzureOpenAiChatCompletionsUrl(options) {
2968
+ const endpoint = resolveAzureOpenAiEndpoint(options);
2969
+ const apiVersion = options.apiVersion ?? defaultAzureOpenAiApiVersion;
2970
+ return `${endpoint}/openai/deployments/${encodeURIComponent(options.deployment)}/chat/completions?api-version=${encodeURIComponent(apiVersion)}`;
2971
+ }
2972
+ function resolveAzureOpenAiEndpoint(options) {
2973
+ if (options.baseURL !== void 0 && options.baseURL.length > 0) {
2974
+ return options.baseURL.replace(/\/+$/, "");
2975
+ }
2976
+ if (options.resourceName !== void 0 && options.resourceName.length > 0) {
2977
+ return `https://${options.resourceName}.openai.azure.com`;
2978
+ }
2979
+ throw new import_errors33.AppError({
2980
+ code: import_errors32.AppErrorCode.BadRequest,
2981
+ message: "Azure OpenAI endpoint is missing. Pass resourceName or baseURL to azureOpenai().",
2982
+ statusCode: 400
2983
+ });
2984
+ }
2985
+ function buildAzureOpenAiRequestHeaders(options) {
2986
+ return {
2987
+ "content-type": "application/json",
2988
+ "api-key": resolveProviderApiKey({
2989
+ providerLabel: "Azure OpenAI",
2990
+ adapterFunctionName: "azureOpenai()",
2991
+ baseEnvVarName: "AZURE_OPENAI_API_KEY",
2992
+ apiKey: options.apiKey,
2993
+ apiKeyName: options.apiKeyName
2994
+ })
2995
+ };
2996
+ }
2997
+ function buildAzureOpenAiChatRequestBody(input) {
2998
+ const requestBody = buildOpenAiRequestBody(
2999
+ azureDeploymentModelPlaceholder,
3000
+ input
3001
+ );
3002
+ const { model: ignoredModel, ...requestBodyWithoutModel } = requestBody;
3003
+ void ignoredModel;
3004
+ return requestBodyWithoutModel;
3005
+ }
3006
+ async function executeAzureOpenAiAdapterCall(options, input) {
3007
+ return await executeProviderCallWithRetry(
3008
+ options.retry,
3009
+ async () => await requestAzureOpenAiChatCompletion(options, input)
3010
+ );
3011
+ }
3012
+ async function requestAzureOpenAiChatCompletion(options, input) {
3013
+ const fetchImplementation = options.fetchImplementation ?? fetch;
3014
+ const requestBody = mergeProviderRequestExtraBody(
3015
+ buildAzureOpenAiChatRequestBody(input),
3016
+ options.extraBody,
3017
+ input.extraBody
3018
+ );
3019
+ const startedAt = Date.now();
3020
+ const response = await executeAbortableProviderFetch(
3021
+ "Azure OpenAI",
3022
+ async () => await fetchImplementation(buildAzureOpenAiChatCompletionsUrl(options), {
3023
+ method: "POST",
3024
+ headers: buildAzureOpenAiRequestHeaders(options),
3025
+ body: JSON.stringify(requestBody),
3026
+ signal: input.abortSignal
3027
+ })
3028
+ );
3029
+ const latencyMs = Date.now() - startedAt;
3030
+ if (!response.ok) {
3031
+ throw buildProviderStatusError("Azure OpenAI", response.status);
3032
+ }
3033
+ const parseResult = AzureOpenAiChatCompletionResponseSchema.safeParse(
3034
+ await response.json()
3035
+ );
3036
+ if (!parseResult.success) {
3037
+ throw buildProviderInvalidResponseError("Azure OpenAI", "chat completion");
3038
+ }
3039
+ return mapAzureOpenAiResponseToChatCompletionResult(
3040
+ parseResult.data,
3041
+ latencyMs
3042
+ );
3043
+ }
3044
+ function buildAzureOpenAiStreamInput(options, request) {
3045
+ const requestBody = mergeProviderRequestExtraBody(
3046
+ buildAzureOpenAiChatRequestBody({
3047
+ messages: request.messages,
3048
+ temperature: request.temperature ?? options.temperature,
3049
+ maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
3050
+ tools: request.tools,
3051
+ toolChoice: request.toolChoice,
3052
+ abortSignal: request.abortSignal,
3053
+ extraBody: request.extraBody
3054
+ }),
3055
+ options.extraBody,
3056
+ request.extraBody
3057
+ );
3058
+ return {
3059
+ url: buildAzureOpenAiChatCompletionsUrl(options),
3060
+ headers: buildAzureOpenAiRequestHeaders(options),
3061
+ body: {
3062
+ ...requestBody,
3063
+ stream: true,
3064
+ stream_options: { include_usage: true }
3065
+ },
3066
+ fetchImplementation: options.fetchImplementation ?? fetch,
3067
+ retry: options.retry,
3068
+ abortSignal: request.abortSignal
3069
+ };
3070
+ }
3071
+
3072
+ // src/bedrock-adapter.ts
3073
+ var import_zod11 = require("zod");
3074
+ var import_errors34 = require("@assemble-dev/shared-types/errors");
3075
+ var import_errors35 = require("@assemble-dev/shared-utils/errors");
3076
+
3077
+ // src/bedrock-sigv4.ts
3078
+ var awsSigV4Algorithm = "AWS4-HMAC-SHA256";
3079
+ async function signAwsRequestWithSigV4(input) {
3080
+ const amzDate = formatAmzDateTime(input.signingDate ?? /* @__PURE__ */ new Date());
3081
+ const dateStamp = amzDate.slice(0, 8);
3082
+ const headersToSign = buildHeadersToSign(input, amzDate);
3083
+ const canonicalHeaderEntries = buildCanonicalHeaderEntries(headersToSign);
3084
+ const signedHeaderNames = canonicalHeaderEntries.map(([headerName]) => headerName).join(";");
3085
+ const credentialScope = `${dateStamp}/${input.region}/${input.service}/aws4_request`;
3086
+ const signatureHex = await computeAwsSigV4Signature(
3087
+ input,
3088
+ amzDate,
3089
+ credentialScope,
3090
+ canonicalHeaderEntries,
3091
+ signedHeaderNames
3092
+ );
3093
+ return {
3094
+ ...headersToSign,
3095
+ authorization: `${awsSigV4Algorithm} Credential=${input.credentials.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaderNames}, Signature=${signatureHex}`
3096
+ };
3097
+ }
3098
+ async function computeAwsSigV4Signature(input, amzDate, credentialScope, canonicalHeaderEntries, signedHeaderNames) {
3099
+ const canonicalRequest = await buildCanonicalRequest(
3100
+ input,
3101
+ canonicalHeaderEntries,
3102
+ signedHeaderNames
3103
+ );
3104
+ const stringToSign = [
3105
+ awsSigV4Algorithm,
3106
+ amzDate,
3107
+ credentialScope,
3108
+ await hashSha256Hex(canonicalRequest)
3109
+ ].join("\n");
3110
+ const signingKey = await deriveAwsSigningKey(
3111
+ input.credentials.secretAccessKey,
3112
+ amzDate.slice(0, 8),
3113
+ input.region,
3114
+ input.service
3115
+ );
3116
+ return bytesToHex(await computeHmacSha256(signingKey, stringToSign));
3117
+ }
3118
+ function buildHeadersToSign(input, amzDate) {
3119
+ const headersToSign = {};
3120
+ for (const [headerName, headerValue] of Object.entries(input.headers)) {
3121
+ headersToSign[headerName.toLowerCase()] = headerValue;
3122
+ }
3123
+ headersToSign.host = input.url.host;
3124
+ headersToSign["x-amz-date"] = amzDate;
3125
+ if (input.credentials.sessionToken !== void 0) {
3126
+ headersToSign["x-amz-security-token"] = input.credentials.sessionToken;
3127
+ }
3128
+ return headersToSign;
3129
+ }
3130
+ function buildCanonicalHeaderEntries(headersToSign) {
3131
+ return Object.entries(headersToSign).map(([headerName, headerValue]) => [
3132
+ headerName.toLowerCase(),
3133
+ headerValue.trim().replace(/\s+/g, " ")
3134
+ ]).sort(([leftName], [rightName]) => leftName.localeCompare(rightName));
3135
+ }
3136
+ async function buildCanonicalRequest(input, canonicalHeaderEntries, signedHeaderNames) {
3137
+ const canonicalHeadersText = canonicalHeaderEntries.map(([headerName, headerValue]) => `${headerName}:${headerValue}`).join("\n");
3138
+ return [
3139
+ input.method.toUpperCase(),
3140
+ buildCanonicalUri(input.url.pathname),
3141
+ buildCanonicalQueryString(input.url.searchParams),
3142
+ `${canonicalHeadersText}
3143
+ `,
3144
+ signedHeaderNames,
3145
+ await hashSha256Hex(input.bodyText)
3146
+ ].join("\n");
3147
+ }
3148
+ function buildCanonicalUri(pathname) {
3149
+ if (pathname.length === 0) {
3150
+ return "/";
3151
+ }
3152
+ return pathname.split("/").map(encodeRfc3986UriComponent).join("/");
3153
+ }
3154
+ function buildCanonicalQueryString(searchParams) {
3155
+ const encodedEntries = [];
3156
+ searchParams.forEach((parameterValue, parameterName) => {
3157
+ encodedEntries.push([
3158
+ encodeRfc3986UriComponent(parameterName),
3159
+ encodeRfc3986UriComponent(parameterValue)
3160
+ ]);
3161
+ });
3162
+ return encodedEntries.sort(
3163
+ ([leftName, leftValue], [rightName, rightValue]) => leftName.localeCompare(rightName) || leftValue.localeCompare(rightValue)
3164
+ ).map(([parameterName, parameterValue]) => `${parameterName}=${parameterValue}`).join("&");
3165
+ }
3166
+ function encodeRfc3986UriComponent(value) {
3167
+ return encodeURIComponent(value).replace(
3168
+ /[!'()*]/g,
3169
+ (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`
3170
+ );
3171
+ }
3172
+ function formatAmzDateTime(date) {
3173
+ return date.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
3174
+ }
3175
+ async function deriveAwsSigningKey(secretAccessKey, dateStamp, region, service) {
3176
+ const dateKey = await computeHmacSha256(
3177
+ new TextEncoder().encode(`AWS4${secretAccessKey}`),
3178
+ dateStamp
3179
+ );
3180
+ const regionKey = await computeHmacSha256(dateKey, region);
3181
+ const serviceKey = await computeHmacSha256(regionKey, service);
3182
+ return await computeHmacSha256(serviceKey, "aws4_request");
3183
+ }
3184
+ async function hashSha256Hex(text) {
3185
+ const digest = await crypto.subtle.digest(
3186
+ "SHA-256",
3187
+ new TextEncoder().encode(text)
3188
+ );
3189
+ return bytesToHex(new Uint8Array(digest));
3190
+ }
3191
+ async function computeHmacSha256(keyBytes, text) {
3192
+ const hmacKey = await crypto.subtle.importKey(
3193
+ "raw",
3194
+ keyBytes,
3195
+ { name: "HMAC", hash: "SHA-256" },
3196
+ false,
3197
+ ["sign"]
3198
+ );
3199
+ const signature = await crypto.subtle.sign(
3200
+ "HMAC",
3201
+ hmacKey,
3202
+ new TextEncoder().encode(text)
3203
+ );
3204
+ return new Uint8Array(signature);
3205
+ }
3206
+ function bytesToHex(bytes) {
3207
+ return Array.from(bytes).map((byteValue) => byteValue.toString(16).padStart(2, "0")).join("");
3208
+ }
3209
+
3210
+ // src/bedrock-adapter.ts
3211
+ var bedrockAnthropicVersion = "bedrock-2023-05-31";
3212
+ var defaultBedrockMaxOutputTokens = 1024;
3213
+ var bedrockSigningServiceName = "bedrock";
3214
+ var bedrockModelPlaceholder = "bedrock-invoke-model";
3215
+ var BedrockEnvCredentialsSchema = import_zod11.z.object({
3216
+ AWS_ACCESS_KEY_ID: import_zod11.z.string().optional(),
3217
+ AWS_SECRET_ACCESS_KEY: import_zod11.z.string().optional(),
3218
+ AWS_SESSION_TOKEN: import_zod11.z.string().optional()
3219
+ });
3220
+ function bedrock(options) {
3221
+ return {
3222
+ name: `bedrock:${options.modelId}`,
3223
+ async generateChatCompletion(request) {
3224
+ return await executeBedrockAdapterCall(options, {
3225
+ messages: request.messages,
3226
+ temperature: request.temperature ?? options.temperature,
3227
+ maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
3228
+ tools: request.tools,
3229
+ toolChoice: request.toolChoice,
3230
+ abortSignal: request.abortSignal,
3231
+ extraBody: request.extraBody
3232
+ });
3233
+ },
3234
+ async generateStructuredOutput(request) {
3235
+ const completion = await executeBedrockAdapterCall(options, {
3236
+ messages: [
3237
+ buildBedrockStructuredOutputSystemMessage(request.schema),
3238
+ ...request.messages
3239
+ ],
3240
+ temperature: request.temperature ?? options.temperature,
3241
+ maxOutputTokens: request.maxOutputTokens ?? options.maxOutputTokens,
3242
+ abortSignal: request.abortSignal
3243
+ });
3244
+ return {
3245
+ value: parseStructuredJsonText(completion.content, request.schema),
3246
+ tokenUsage: completion.tokenUsage,
3247
+ latencyMs: completion.latencyMs
3248
+ };
3249
+ }
3250
+ };
3251
+ }
3252
+ function buildBedrockInvokeModelUrl(region, modelId) {
3253
+ return `https://bedrock-runtime.${region}.amazonaws.com/model/${encodeURIComponent(modelId)}/invoke`;
3254
+ }
3255
+ function resolveBedrockCredentials(options) {
3256
+ if (options.credentials !== void 0) {
3257
+ return options.credentials;
3258
+ }
3259
+ const parsedEnv = BedrockEnvCredentialsSchema.parse(process.env);
3260
+ const accessKeyId = parsedEnv.AWS_ACCESS_KEY_ID;
3261
+ const secretAccessKey = parsedEnv.AWS_SECRET_ACCESS_KEY;
3262
+ if (accessKeyId === void 0 || accessKeyId.length === 0 || secretAccessKey === void 0 || secretAccessKey.length === 0) {
3263
+ throw new import_errors35.AppError({
3264
+ code: import_errors34.AppErrorCode.Unauthorized,
3265
+ message: "AWS credentials are missing. Pass credentials to bedrock() or set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.",
3266
+ statusCode: 401
3267
+ });
3268
+ }
3269
+ const credentials = { accessKeyId, secretAccessKey };
3270
+ const sessionToken = parsedEnv.AWS_SESSION_TOKEN;
3271
+ if (sessionToken !== void 0 && sessionToken.length > 0) {
3272
+ credentials.sessionToken = sessionToken;
3273
+ }
3274
+ return credentials;
3275
+ }
3276
+ async function executeBedrockAdapterCall(options, input) {
3277
+ return await executeProviderCallWithRetry(
3278
+ options.retry,
3279
+ async () => await requestBedrockInvokeModel(options, input)
3280
+ );
3281
+ }
3282
+ async function requestBedrockInvokeModel(options, input) {
3283
+ const credentials = resolveBedrockCredentials(options);
3284
+ const fetchImplementation = options.fetchImplementation ?? fetch;
3285
+ const requestBody = mergeProviderRequestExtraBody(
3286
+ buildBedrockInvokeModelRequestBody(input),
3287
+ options.extraBody,
3288
+ input.extraBody
3289
+ );
3290
+ const bodyText = JSON.stringify(requestBody);
3291
+ const url = new URL(buildBedrockInvokeModelUrl(options.region, options.modelId));
3292
+ const signedHeaders = await signAwsRequestWithSigV4({
3293
+ method: "POST",
3294
+ url,
3295
+ headers: { "content-type": "application/json" },
3296
+ bodyText,
3297
+ region: options.region,
3298
+ service: bedrockSigningServiceName,
3299
+ credentials
3300
+ });
3301
+ const startedAt = Date.now();
3302
+ const response = await executeAbortableProviderFetch(
3303
+ "Bedrock",
3304
+ async () => await fetchImplementation(url.toString(), {
3305
+ method: "POST",
3306
+ headers: signedHeaders,
3307
+ body: bodyText,
3308
+ signal: input.abortSignal
3309
+ })
3310
+ );
3311
+ const latencyMs = Date.now() - startedAt;
3312
+ if (!response.ok) {
3313
+ throw buildProviderStatusError("Bedrock", response.status);
3314
+ }
3315
+ const parseResult = AnthropicMessagesResponseSchema.safeParse(
3316
+ await response.json()
3317
+ );
3318
+ if (!parseResult.success) {
3319
+ throw buildProviderInvalidResponseError("Bedrock", "invoke model");
3320
+ }
3321
+ return mapAnthropicResponseToChatCompletionResult(parseResult.data, latencyMs);
3322
+ }
3323
+ function buildBedrockInvokeModelRequestBody(input) {
3324
+ const anthropicRequestBody = buildAnthropicRequestBody(
3325
+ {
3326
+ model: bedrockModelPlaceholder,
3327
+ defaultMaxOutputTokens: defaultBedrockMaxOutputTokens
3328
+ },
3329
+ input
3330
+ );
3331
+ const {
3332
+ model: ignoredModel,
3333
+ stream: ignoredStream,
3334
+ ...requestBodyWithoutModel
3335
+ } = anthropicRequestBody;
3336
+ void ignoredModel;
3337
+ void ignoredStream;
3338
+ return {
3339
+ ...requestBodyWithoutModel,
3340
+ anthropic_version: bedrockAnthropicVersion
3341
+ };
3342
+ }
3343
+ function buildBedrockStructuredOutputSystemMessage(schema) {
3344
+ return {
3345
+ role: "system",
3346
+ content: `Respond with a single JSON object that satisfies the following JSON Schema. Output only valid JSON with no surrounding text.
3347
+
3348
+ JSON Schema:
3349
+ ${JSON.stringify(convertZodSchemaToJsonSchema(schema))}`
3350
+ };
3351
+ }
2221
3352
  // Annotate the CommonJS export names for ESM import in node:
2222
3353
  0 && (module.exports = {
2223
3354
  AnthropicMessagesResponseSchema,
2224
3355
  AnthropicStreamEventSchema,
3356
+ AzureOpenAiChatCompletionResponseSchema,
2225
3357
  ChatMessageCacheControlSchema,
2226
3358
  ChatMessageRoleSchema,
2227
3359
  ChatMessageSchema,
@@ -2232,16 +3364,30 @@ function buildAnthropicBatchTimeoutError(batchId, timeoutMs) {
2232
3364
  anthropicBatchJsonOnlySystemInstruction,
2233
3365
  anthropicBatchTraceWorkflowName,
2234
3366
  applyCacheControlToLastContentBlock,
3367
+ awsSigV4Algorithm,
3368
+ azureOpenai,
3369
+ bedrock,
3370
+ bedrockAnthropicVersion,
2235
3371
  buildAnthropicCacheControl,
2236
3372
  buildAnthropicRequestBody,
3373
+ buildAnthropicStructuredOutputJsonSchema,
3374
+ buildAzureOpenAiChatCompletionsUrl,
3375
+ buildAzureOpenAiChatRequestBody,
3376
+ buildBedrockInvokeModelRequestBody,
3377
+ buildBedrockInvokeModelUrl,
3378
+ buildGeminiResponseSchema,
2237
3379
  buildOpenAiRequestBody,
3380
+ buildOpenAiStructuredOutputJsonSchema,
2238
3381
  buildProviderCanceledError,
2239
3382
  calculateProviderRetryDelayMs,
3383
+ convertZodSchemaToJsonSchema,
2240
3384
  createAnthropicBatchClient,
2241
3385
  defaultAnthropicBaseUrl,
2242
3386
  defaultAnthropicBatchPollIntervalMs,
2243
3387
  defaultAnthropicBatchTimeoutMs,
2244
3388
  defaultAnthropicMaxOutputTokens,
3389
+ defaultAzureOpenAiApiVersion,
3390
+ defaultBedrockMaxOutputTokens,
2245
3391
  defaultGeminiBaseUrl,
2246
3392
  defaultOpenAiBaseUrl,
2247
3393
  defaultProviderRetryInitialDelayMs,
@@ -2252,6 +3398,7 @@ function buildAnthropicBatchTimeoutError(batchId, timeoutMs) {
2252
3398
  executeProviderCallWithModelFallback,
2253
3399
  executeProviderCallWithRetry,
2254
3400
  extractAnthropicTextContent,
3401
+ extractAnthropicThinkingText,
2255
3402
  extractAnthropicToolCalls,
2256
3403
  extractMessageText,
2257
3404
  gemini,
@@ -2260,6 +3407,8 @@ function buildAnthropicBatchTimeoutError(batchId, timeoutMs) {
2260
3407
  joinSystemMessageText,
2261
3408
  mapAnthropicResponseToChatCompletionResult,
2262
3409
  mapAnthropicUsageToTokenUsage,
3410
+ mapAzureOpenAiResponseToChatCompletionResult,
3411
+ mapAzureOpenAiUsageToTokenUsage,
2263
3412
  mapChatMessageToAnthropicRequestMessage,
2264
3413
  mapChatMessageToOpenAiRequestMessage,
2265
3414
  mapModelToolChoiceToAnthropicToolChoice,
@@ -2269,11 +3418,21 @@ function buildAnthropicBatchTimeoutError(batchId, timeoutMs) {
2269
3418
  mergeProviderRequestExtraBody,
2270
3419
  mockModel,
2271
3420
  normalizeAnthropicStopReason,
3421
+ normalizeAzureOpenAiFinishReason,
3422
+ openAiStructuredOutputSchemaName,
2272
3423
  openai,
2273
3424
  parseAnthropicBatchStructuredContent,
2274
3425
  parseAnthropicStreamEvents,
2275
3426
  parseAnthropicToolInputJson,
3427
+ parseAzureOpenAiStreamEvents,
3428
+ parseAzureOpenAiToolArgumentsJson,
2276
3429
  resolveAnthropicPromptCachingSettings,
3430
+ resolveBedrockCredentials,
2277
3431
  resolveProviderApiKey,
2278
- streamAnthropicChatCompletion
3432
+ sanitizeJsonSchemaForAnthropicStructuredOutput,
3433
+ sanitizeJsonSchemaForGeminiResponseSchema,
3434
+ sanitizeJsonSchemaForOpenAiStructuredOutput,
3435
+ signAwsRequestWithSigV4,
3436
+ streamAnthropicChatCompletion,
3437
+ streamAzureOpenAiChatCompletion
2279
3438
  });