@jerome-benoit/sap-ai-provider-v2 5.0.2 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +44 -24
  2. package/dist/chunk-4ILJD6PI.js +333 -0
  3. package/dist/chunk-4ILJD6PI.js.map +1 -0
  4. package/dist/chunk-BHA5MIN6.js +224 -0
  5. package/dist/chunk-BHA5MIN6.js.map +1 -0
  6. package/dist/{chunk-LEME2MFD.js → chunk-DLGBK3C3.js} +91 -7
  7. package/dist/chunk-DLGBK3C3.js.map +1 -0
  8. package/dist/{chunk-NLMWIVG7.js → chunk-EUBI5ENK.js} +54 -27
  9. package/dist/chunk-EUBI5ENK.js.map +1 -0
  10. package/dist/{chunk-YP3AADWD.js → chunk-FKHOJ3ZC.js} +24 -3
  11. package/dist/chunk-FKHOJ3ZC.js.map +1 -0
  12. package/dist/{chunk-77JSAAPE.js → chunk-QFMHNGLB.js} +56 -218
  13. package/dist/chunk-QFMHNGLB.js.map +1 -0
  14. package/dist/{chunk-U6WJSLR7.js → chunk-QQQYMQPU.js} +19 -10
  15. package/dist/chunk-QQQYMQPU.js.map +1 -0
  16. package/dist/{chunk-QZOZ3PZT.js → chunk-ZOBD7PXJ.js} +118 -22
  17. package/dist/chunk-ZOBD7PXJ.js.map +1 -0
  18. package/dist/{foundation-models-embedding-model-strategy-A3WDDAYK.js → foundation-models-embedding-model-strategy-3WAKJXBY.js} +5 -4
  19. package/dist/{foundation-models-embedding-model-strategy-A3WDDAYK.js.map → foundation-models-embedding-model-strategy-3WAKJXBY.js.map} +1 -1
  20. package/dist/{foundation-models-language-model-strategy-6U6KK6KH.js → foundation-models-language-model-strategy-PJ26VXEA.js} +22 -9
  21. package/dist/foundation-models-language-model-strategy-PJ26VXEA.js.map +1 -0
  22. package/dist/index.cjs +1903 -384
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +798 -185
  25. package/dist/index.d.ts +798 -185
  26. package/dist/index.js +148 -24
  27. package/dist/index.js.map +1 -1
  28. package/dist/{orchestration-embedding-model-strategy-JO3QH5MR.js → orchestration-embedding-model-strategy-AZ76XLMD.js} +6 -5
  29. package/dist/{orchestration-embedding-model-strategy-JO3QH5MR.js.map → orchestration-embedding-model-strategy-AZ76XLMD.js.map} +1 -1
  30. package/dist/{orchestration-language-model-strategy-MBVA7BYX.js → orchestration-language-model-strategy-CT6RHCYO.js} +57 -19
  31. package/dist/orchestration-language-model-strategy-CT6RHCYO.js.map +1 -0
  32. package/dist/responses-language-model-strategy-UYTV6TPM.js +738 -0
  33. package/dist/responses-language-model-strategy-UYTV6TPM.js.map +1 -0
  34. package/dist/sap-ai-error-UPKYWPSS.js +16 -0
  35. package/dist/sap-ai-error-UPKYWPSS.js.map +1 -0
  36. package/package.json +79 -39
  37. package/dist/chunk-77JSAAPE.js.map +0 -1
  38. package/dist/chunk-LEME2MFD.js.map +0 -1
  39. package/dist/chunk-NLMWIVG7.js.map +0 -1
  40. package/dist/chunk-QZOZ3PZT.js.map +0 -1
  41. package/dist/chunk-U6WJSLR7.js.map +0 -1
  42. package/dist/chunk-YP3AADWD.js.map +0 -1
  43. package/dist/foundation-models-language-model-strategy-6U6KK6KH.js.map +0 -1
  44. package/dist/orchestration-language-model-strategy-MBVA7BYX.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -5,8 +5,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __esm = (fn, res) => function __init() {
9
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ var __esm = (fn, res, err) => function __init() {
9
+ if (err) throw err[0];
10
+ try {
11
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
+ } catch (e) {
13
+ throw err = [e], e;
14
+ }
10
15
  };
11
16
  var __export = (target, all) => {
12
17
  for (var name in all)
@@ -30,6 +35,181 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
35
  ));
31
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
37
 
38
+ // src/sap-ai-provider-options.ts
39
+ function getProviderName(providerIdentifier) {
40
+ const dotIndex = providerIdentifier.indexOf(".");
41
+ return dotIndex === -1 ? providerIdentifier : providerIdentifier.slice(0, dotIndex);
42
+ }
43
+ function validateEmbeddingModelParamsSettings(modelParams) {
44
+ return embeddingModelParamsSchema.parse(modelParams);
45
+ }
46
+ function validateModelParamsSettings(modelParams) {
47
+ return modelParamsSchema.parse(modelParams);
48
+ }
49
+ function validateModelParamsWithWarnings(params, warnings) {
50
+ const result = modelParamsSchema.safeParse(params);
51
+ if (!result.success) {
52
+ for (const issue of result.error.issues) {
53
+ const path = issue.path.join(".");
54
+ const value = path ? params[path] : void 0;
55
+ warnings.push({
56
+ message: `${path}=${String(value)} is invalid: ${issue.message}. The API may reject this value.`,
57
+ type: "other"
58
+ });
59
+ }
60
+ }
61
+ }
62
+ function parseSAPPartProviderOptions(providerOptions, warnings) {
63
+ if (!providerOptions || typeof providerOptions !== "object") {
64
+ return void 0;
65
+ }
66
+ const block = providerOptions[SAP_AI_PROVIDER_NAME];
67
+ if (block === void 0) {
68
+ return void 0;
69
+ }
70
+ const parsed = sapAIPartProviderOptionsSchema.safeParse(block);
71
+ if (parsed.success) {
72
+ return parsed.data;
73
+ }
74
+ if (warnings) {
75
+ for (const issue of parsed.error.issues) {
76
+ const path = issue.path.join(".");
77
+ const message = `providerOptions['sap-ai']${path ? `.${path}` : ""} is invalid: ${issue.message}. The directive was dropped.`;
78
+ if (!warnings.some((w) => w.message === message)) {
79
+ warnings.push({ message, type: "other" });
80
+ }
81
+ }
82
+ }
83
+ return void 0;
84
+ }
85
+ var import_provider_utils, import_zod, SAP_AI_PROVIDER_NAME, modelParamsSchema, embeddingModelParamsSchema, sapAIApiTypeSchema, cacheControlSchema, sapAIPartProviderOptionsSchema, orchestrationReasoningBlockSchema, promptTemplateScopeSchema, promptTemplateRefByIdSchema, promptTemplateRefByScenarioNameVersionSchema, promptTemplateRefSchema, orchestrationConfigRefOverrideSchema, orchestrationConfigRefByIdSchema, orchestrationConfigRefByScenarioNameVersionSchema, orchestrationConfigRefSchema, responsesModelOptionsSchema, dropUnsupportedParamsSchema, sapAILanguageModelProviderOptions, sapAIEmbeddingProviderOptions;
86
+ var init_sap_ai_provider_options = __esm({
87
+ "src/sap-ai-provider-options.ts"() {
88
+ "use strict";
89
+ import_provider_utils = require("@ai-sdk/provider-utils");
90
+ import_zod = require("zod");
91
+ SAP_AI_PROVIDER_NAME = "sap-ai";
92
+ modelParamsSchema = import_zod.z.object({
93
+ frequencyPenalty: import_zod.z.number().min(-2).max(2).optional(),
94
+ maxTokens: import_zod.z.number().int().positive().optional(),
95
+ n: import_zod.z.number().int().positive().optional(),
96
+ parallel_tool_calls: import_zod.z.boolean().optional(),
97
+ presencePenalty: import_zod.z.number().min(-2).max(2).optional(),
98
+ temperature: import_zod.z.number().min(0).max(2).optional(),
99
+ topP: import_zod.z.number().min(0).max(1).optional()
100
+ }).catchall(import_zod.z.unknown());
101
+ embeddingModelParamsSchema = import_zod.z.object({
102
+ dimensions: import_zod.z.number().int().positive().optional(),
103
+ encoding_format: import_zod.z.enum(["base64", "binary", "float"]).optional(),
104
+ normalize: import_zod.z.boolean().optional()
105
+ }).catchall(import_zod.z.unknown());
106
+ sapAIApiTypeSchema = import_zod.z.enum(["orchestration", "foundation-models", "responses"]);
107
+ cacheControlSchema = import_zod.z.object({
108
+ ttl: import_zod.z.enum(["5m", "1h"]).optional(),
109
+ type: import_zod.z.literal("ephemeral")
110
+ });
111
+ sapAIPartProviderOptionsSchema = import_zod.z.object({
112
+ cacheControl: cacheControlSchema.optional()
113
+ });
114
+ orchestrationReasoningBlockSchema = import_zod.z.object({
115
+ content: import_zod.z.string().optional(),
116
+ signature: import_zod.z.string().optional()
117
+ }).strict();
118
+ promptTemplateScopeSchema = import_zod.z.enum(["tenant", "resource_group"]);
119
+ promptTemplateRefByIdSchema = import_zod.z.object({
120
+ id: import_zod.z.string().min(1, "Template ID cannot be empty"),
121
+ scope: promptTemplateScopeSchema.optional()
122
+ });
123
+ promptTemplateRefByScenarioNameVersionSchema = import_zod.z.object({
124
+ name: import_zod.z.string().min(1, "Template name cannot be empty"),
125
+ scenario: import_zod.z.string().min(1, "Scenario cannot be empty"),
126
+ scope: promptTemplateScopeSchema.optional(),
127
+ version: import_zod.z.string().min(1, "Version cannot be empty")
128
+ });
129
+ promptTemplateRefSchema = import_zod.z.union([
130
+ promptTemplateRefByIdSchema,
131
+ promptTemplateRefByScenarioNameVersionSchema
132
+ ]);
133
+ orchestrationConfigRefOverrideSchema = import_zod.z.custom(
134
+ (value) => typeof value === "object" && value !== null && !Array.isArray(value),
135
+ { message: "overrideConfig must be an object" }
136
+ ).refine(
137
+ (value) => {
138
+ let stream;
139
+ try {
140
+ stream = value.stream;
141
+ } catch {
142
+ return false;
143
+ }
144
+ return stream === void 0 || Boolean(stream) && typeof stream === "object" && !Array.isArray(stream);
145
+ },
146
+ { message: "overrideConfig.stream must be an object" }
147
+ ).refine(
148
+ (value) => {
149
+ let stream;
150
+ try {
151
+ stream = value.stream;
152
+ } catch {
153
+ return true;
154
+ }
155
+ if (stream === void 0 || stream === null || typeof stream !== "object") {
156
+ return true;
157
+ }
158
+ try {
159
+ return !("enabled" in stream);
160
+ } catch {
161
+ return false;
162
+ }
163
+ },
164
+ {
165
+ message: "stream.enabled is not allowed in overrideConfig: it is controlled by the call site (stream() or chatCompletion())"
166
+ }
167
+ );
168
+ orchestrationConfigRefByIdSchema = import_zod.z.object({
169
+ id: import_zod.z.string().min(1, "Config ID cannot be empty"),
170
+ overrideConfig: orchestrationConfigRefOverrideSchema.optional()
171
+ });
172
+ orchestrationConfigRefByScenarioNameVersionSchema = import_zod.z.object({
173
+ name: import_zod.z.string().min(1, "Config name cannot be empty"),
174
+ overrideConfig: orchestrationConfigRefOverrideSchema.optional(),
175
+ scenario: import_zod.z.string().min(1, "Scenario cannot be empty"),
176
+ version: import_zod.z.string().min(1, "Version cannot be empty")
177
+ });
178
+ orchestrationConfigRefSchema = import_zod.z.union([
179
+ orchestrationConfigRefByIdSchema,
180
+ orchestrationConfigRefByScenarioNameVersionSchema
181
+ ]);
182
+ responsesModelOptionsSchema = import_zod.z.object({
183
+ metadata: import_zod.z.record(import_zod.z.string(), import_zod.z.string()).nullable().optional()
184
+ }).catchall(import_zod.z.json());
185
+ dropUnsupportedParamsSchema = import_zod.z.boolean();
186
+ sapAILanguageModelProviderOptions = (0, import_provider_utils.lazySchema)(
187
+ () => (0, import_provider_utils.zodSchema)(
188
+ import_zod.z.object({
189
+ api: sapAIApiTypeSchema.optional(),
190
+ dropUnsupportedParams: dropUnsupportedParamsSchema.optional(),
191
+ escapeTemplatePlaceholders: import_zod.z.boolean().optional(),
192
+ includeReasoning: import_zod.z.boolean().optional(),
193
+ modelParams: modelParamsSchema.optional(),
194
+ orchestrationConfigRef: orchestrationConfigRefSchema.optional(),
195
+ placeholderValues: import_zod.z.record(import_zod.z.string(), import_zod.z.string()).optional(),
196
+ promptTemplateRef: promptTemplateRefSchema.optional(),
197
+ responses: responsesModelOptionsSchema.optional()
198
+ })
199
+ )
200
+ );
201
+ sapAIEmbeddingProviderOptions = (0, import_provider_utils.lazySchema)(
202
+ () => (0, import_provider_utils.zodSchema)(
203
+ import_zod.z.object({
204
+ api: sapAIApiTypeSchema.optional(),
205
+ modelParams: embeddingModelParamsSchema.optional(),
206
+ type: import_zod.z.enum(["document", "query", "text"]).optional()
207
+ })
208
+ )
209
+ );
210
+ }
211
+ });
212
+
33
213
  // src/convert-to-sap-messages.ts
34
214
  function getURLHref(value) {
35
215
  if (typeof value !== "object" || value === null || URL_HREF_DESCRIPTOR?.get === void 0) {
@@ -171,6 +351,7 @@ function convertToSAPMessages(prompt, options = {}) {
171
351
  let text = "";
172
352
  const textParts = parser ? [] : void 0;
173
353
  let anyCacheControl = false;
354
+ let reasoningContent;
174
355
  const toolCalls = [];
175
356
  for (const part of message.content) {
176
357
  switch (part.type) {
@@ -182,6 +363,21 @@ function convertToSAPMessages(prompt, options = {}) {
182
363
  break;
183
364
  }
184
365
  case "reasoning": {
366
+ const nativeNamespace = options.nativeReasoningProviderName;
367
+ const nativeOptions = nativeNamespace === void 0 ? void 0 : part.providerOptions?.[nativeNamespace];
368
+ if (nativeOptions !== null && typeof nativeOptions === "object" && !Array.isArray(nativeOptions) && Object.hasOwn(nativeOptions, "reasoningContent")) {
369
+ const parsed = orchestrationReasoningBlockSchema.safeParse(
370
+ nativeOptions.reasoningContent
371
+ );
372
+ if (!parsed.success) {
373
+ throw new import_provider.InvalidPromptError({
374
+ message: "Invalid native Orchestration reasoning metadata.",
375
+ prompt
376
+ });
377
+ }
378
+ (reasoningContent ??= []).push(parsed.data);
379
+ break;
380
+ }
185
381
  if (includeReasoning && part.text) {
186
382
  const reasoning = `<think>${part.text}</think>`;
187
383
  text += reasoning;
@@ -228,11 +424,12 @@ function convertToSAPMessages(prompt, options = {}) {
228
424
  }
229
425
  }
230
426
  }
231
- if (text || toolCalls.length > 0) {
427
+ if (text || toolCalls.length > 0 || reasoningContent?.length) {
232
428
  const assistantMessage = {
233
429
  content: anyCacheControl && textParts ? textParts.map((p) => wrapAsTextContent(maybeEscape(p.text), p.cacheControl)) : maybeEscape(text),
234
430
  role: "assistant",
235
- tool_calls: toolCalls.length > 0 ? toolCalls : void 0
431
+ tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
432
+ ...reasoningContent && { reasoning_content: reasoningContent }
236
433
  };
237
434
  messages.push(assistantMessage);
238
435
  }
@@ -388,6 +585,7 @@ var init_convert_to_sap_messages = __esm({
388
585
  "src/convert-to-sap-messages.ts"() {
389
586
  "use strict";
390
587
  import_provider = require("@ai-sdk/provider");
588
+ init_sap_ai_provider_options();
391
589
  ZERO_WIDTH_SPACE = "\u200B";
392
590
  ARRAY_BUFFER_BYTE_LENGTH_DESCRIPTOR = Object.getOwnPropertyDescriptor(
393
591
  ArrayBuffer.prototype,
@@ -408,211 +606,15 @@ var init_convert_to_sap_messages = __esm({
408
606
  }
409
607
  });
410
608
 
411
- // src/sap-ai-provider-options.ts
412
- function getProviderName(providerIdentifier) {
413
- const dotIndex = providerIdentifier.indexOf(".");
414
- return dotIndex === -1 ? providerIdentifier : providerIdentifier.slice(0, dotIndex);
415
- }
416
- function validateEmbeddingModelParamsSettings(modelParams) {
417
- return embeddingModelParamsSchema.parse(modelParams);
418
- }
419
- function validateModelParamsSettings(modelParams) {
420
- return modelParamsSchema.parse(modelParams);
421
- }
422
- function validateModelParamsWithWarnings(params, warnings) {
423
- const result = modelParamsSchema.safeParse(params);
424
- if (!result.success) {
425
- for (const issue of result.error.issues) {
426
- const path = issue.path.join(".");
427
- const value = path ? params[path] : void 0;
428
- warnings.push({
429
- message: `${path}=${String(value)} is invalid: ${issue.message}. The API may reject this value.`,
430
- type: "other"
431
- });
432
- }
433
- }
434
- }
435
- function parseSAPPartProviderOptions(providerOptions, warnings) {
436
- if (!providerOptions || typeof providerOptions !== "object") {
437
- return void 0;
438
- }
439
- const block = providerOptions[SAP_AI_PROVIDER_NAME];
440
- if (block === void 0) {
441
- return void 0;
442
- }
443
- const parsed = sapAIPartProviderOptionsSchema.safeParse(block);
444
- if (parsed.success) {
445
- return parsed.data;
446
- }
447
- if (warnings) {
448
- for (const issue of parsed.error.issues) {
449
- const path = issue.path.join(".");
450
- const message = `providerOptions['sap-ai']${path ? `.${path}` : ""} is invalid: ${issue.message}. The directive was dropped.`;
451
- if (!warnings.some((w) => w.message === message)) {
452
- warnings.push({ message, type: "other" });
453
- }
454
- }
455
- }
456
- return void 0;
457
- }
458
- var import_provider_utils, import_zod, SAP_AI_PROVIDER_NAME, modelParamsSchema, embeddingModelParamsSchema, sapAIApiTypeSchema, cacheControlSchema, sapAIPartProviderOptionsSchema, promptTemplateScopeSchema, promptTemplateRefByIdSchema, promptTemplateRefByScenarioNameVersionSchema, promptTemplateRefSchema, orchestrationConfigRefOverrideSchema, orchestrationConfigRefByIdSchema, orchestrationConfigRefByScenarioNameVersionSchema, orchestrationConfigRefSchema, sapAILanguageModelProviderOptions, sapAIEmbeddingProviderOptions;
459
- var init_sap_ai_provider_options = __esm({
460
- "src/sap-ai-provider-options.ts"() {
461
- "use strict";
462
- import_provider_utils = require("@ai-sdk/provider-utils");
463
- import_zod = require("zod");
464
- SAP_AI_PROVIDER_NAME = "sap-ai";
465
- modelParamsSchema = import_zod.z.object({
466
- frequencyPenalty: import_zod.z.number().min(-2).max(2).optional(),
467
- maxTokens: import_zod.z.number().int().positive().optional(),
468
- n: import_zod.z.number().int().positive().optional(),
469
- parallel_tool_calls: import_zod.z.boolean().optional(),
470
- presencePenalty: import_zod.z.number().min(-2).max(2).optional(),
471
- temperature: import_zod.z.number().min(0).max(2).optional(),
472
- topP: import_zod.z.number().min(0).max(1).optional()
473
- }).catchall(import_zod.z.unknown());
474
- embeddingModelParamsSchema = import_zod.z.object({
475
- dimensions: import_zod.z.number().int().positive().optional(),
476
- encoding_format: import_zod.z.enum(["base64", "binary", "float"]).optional(),
477
- normalize: import_zod.z.boolean().optional()
478
- }).catchall(import_zod.z.unknown());
479
- sapAIApiTypeSchema = import_zod.z.enum(["orchestration", "foundation-models"]);
480
- cacheControlSchema = import_zod.z.object({
481
- ttl: import_zod.z.enum(["5m", "1h"]).optional(),
482
- type: import_zod.z.literal("ephemeral")
483
- });
484
- sapAIPartProviderOptionsSchema = import_zod.z.object({
485
- cacheControl: cacheControlSchema.optional()
486
- });
487
- promptTemplateScopeSchema = import_zod.z.enum(["tenant", "resource_group"]);
488
- promptTemplateRefByIdSchema = import_zod.z.object({
489
- id: import_zod.z.string().min(1, "Template ID cannot be empty"),
490
- scope: promptTemplateScopeSchema.optional()
491
- });
492
- promptTemplateRefByScenarioNameVersionSchema = import_zod.z.object({
493
- name: import_zod.z.string().min(1, "Template name cannot be empty"),
494
- scenario: import_zod.z.string().min(1, "Scenario cannot be empty"),
495
- scope: promptTemplateScopeSchema.optional(),
496
- version: import_zod.z.string().min(1, "Version cannot be empty")
497
- });
498
- promptTemplateRefSchema = import_zod.z.union([
499
- promptTemplateRefByIdSchema,
500
- promptTemplateRefByScenarioNameVersionSchema
501
- ]);
502
- orchestrationConfigRefOverrideSchema = import_zod.z.custom(
503
- (value) => typeof value === "object" && value !== null && !Array.isArray(value),
504
- { message: "overrideConfig must be an object" }
505
- ).refine(
506
- (value) => {
507
- let stream;
508
- try {
509
- stream = value.stream;
510
- } catch {
511
- return false;
512
- }
513
- return stream === void 0 || Boolean(stream) && typeof stream === "object" && !Array.isArray(stream);
514
- },
515
- { message: "overrideConfig.stream must be an object" }
516
- ).refine(
517
- (value) => {
518
- let stream;
519
- try {
520
- stream = value.stream;
521
- } catch {
522
- return true;
523
- }
524
- if (stream === void 0 || stream === null || typeof stream !== "object") {
525
- return true;
526
- }
527
- try {
528
- return !("enabled" in stream);
529
- } catch {
530
- return false;
531
- }
532
- },
533
- {
534
- message: "stream.enabled is not allowed in overrideConfig: it is controlled by the call site (stream() or chatCompletion())"
535
- }
536
- );
537
- orchestrationConfigRefByIdSchema = import_zod.z.object({
538
- id: import_zod.z.string().min(1, "Config ID cannot be empty"),
539
- overrideConfig: orchestrationConfigRefOverrideSchema.optional()
540
- });
541
- orchestrationConfigRefByScenarioNameVersionSchema = import_zod.z.object({
542
- name: import_zod.z.string().min(1, "Config name cannot be empty"),
543
- overrideConfig: orchestrationConfigRefOverrideSchema.optional(),
544
- scenario: import_zod.z.string().min(1, "Scenario cannot be empty"),
545
- version: import_zod.z.string().min(1, "Version cannot be empty")
546
- });
547
- orchestrationConfigRefSchema = import_zod.z.union([
548
- orchestrationConfigRefByIdSchema,
549
- orchestrationConfigRefByScenarioNameVersionSchema
550
- ]);
551
- sapAILanguageModelProviderOptions = (0, import_provider_utils.lazySchema)(
552
- () => (0, import_provider_utils.zodSchema)(
553
- import_zod.z.object({
554
- api: sapAIApiTypeSchema.optional(),
555
- escapeTemplatePlaceholders: import_zod.z.boolean().optional(),
556
- includeReasoning: import_zod.z.boolean().optional(),
557
- modelParams: modelParamsSchema.optional(),
558
- orchestrationConfigRef: orchestrationConfigRefSchema.optional(),
559
- placeholderValues: import_zod.z.record(import_zod.z.string(), import_zod.z.string()).optional(),
560
- promptTemplateRef: promptTemplateRefSchema.optional()
561
- })
562
- )
563
- );
564
- sapAIEmbeddingProviderOptions = (0, import_provider_utils.lazySchema)(
565
- () => (0, import_provider_utils.zodSchema)(
566
- import_zod.z.object({
567
- api: sapAIApiTypeSchema.optional(),
568
- modelParams: embeddingModelParamsSchema.optional(),
569
- type: import_zod.z.enum(["document", "query", "text"]).optional()
570
- })
571
- )
572
- );
573
- }
574
- });
575
-
576
- // src/deep-merge.ts
577
- function deepMerge(...sources) {
578
- const result = {};
579
- for (const source of sources) {
580
- if (source != null) mergeInto(result, source, /* @__PURE__ */ new Set(), 0);
581
- }
582
- return result;
583
- }
584
- function isPlainObject(value) {
585
- if (value === null || typeof value !== "object") return false;
586
- const proto = Object.getPrototypeOf(value);
587
- return proto === Object.prototype || proto === null;
588
- }
589
- function mergeInto(target, source, ancestors, depth) {
590
- if (depth > MAX_DEPTH) throw new Error("Maximum merge depth exceeded");
591
- if (ancestors.has(source)) throw new Error("Circular reference detected during deep merge");
592
- ancestors.add(source);
593
- for (const key of Object.keys(source)) {
594
- const sourceValue = source[key];
595
- const targetValue = Object.hasOwn(target, key) ? target[key] : void 0;
596
- const value = isPlainObject(sourceValue) ? mergeInto(isPlainObject(targetValue) ? targetValue : {}, sourceValue, ancestors, depth + 1) : sourceValue;
597
- Object.defineProperty(target, key, {
598
- configurable: true,
599
- enumerable: true,
600
- value,
601
- writable: true
602
- });
603
- }
604
- ancestors.delete(source);
605
- return target;
606
- }
607
- var MAX_DEPTH;
608
- var init_deep_merge = __esm({
609
- "src/deep-merge.ts"() {
610
- "use strict";
611
- MAX_DEPTH = 100;
612
- }
613
- });
614
-
615
609
  // src/sap-ai-error.ts
610
+ var sap_ai_error_exports = {};
611
+ __export(sap_ai_error_exports, {
612
+ ApiSwitchError: () => ApiSwitchError,
613
+ UnsupportedFeatureError: () => UnsupportedFeatureError,
614
+ convertSAPErrorToAPICallError: () => convertSAPErrorToAPICallError,
615
+ convertToAISDKError: () => convertToAISDKError,
616
+ normalizeHeaders: () => normalizeHeaders
617
+ });
616
618
  function convertSAPErrorToAPICallError(errorResponse, context) {
617
619
  const { code, location, message, requestId } = extractErrorFields(errorResponse);
618
620
  const statusCode = getStatusCodeFromSAPError(code, context?.httpStatusCode);
@@ -631,7 +633,7 @@ function convertSAPErrorToAPICallError(errorResponse, context) {
631
633
  enhancedMessage += `
632
634
  Request ID: ${requestId}`;
633
635
  }
634
- return new import_provider2.LoadAPIKeyError({
636
+ return new import_provider3.LoadAPIKeyError({
635
637
  message: enhancedMessage
636
638
  });
637
639
  }
@@ -642,7 +644,7 @@ Request ID: ${requestId}`;
642
644
  Request ID: ${requestId}`;
643
645
  }
644
646
  const modelId = context?.modelId ?? extractModelIdentifier(message, location);
645
- return new import_provider2.NoSuchModelError({
647
+ return new import_provider3.NoSuchModelError({
646
648
  message: enhancedMessage,
647
649
  modelId: modelId ?? "unknown",
648
650
  modelType: context?.modelType ?? "languageModel"
@@ -661,7 +663,7 @@ Error location: ${location}`;
661
663
  enhancedMessage += `
662
664
  Request ID: ${requestId}`;
663
665
  }
664
- return new import_provider2.APICallError({
666
+ return new import_provider3.APICallError({
665
667
  isRetryable: isRetryable(statusCode),
666
668
  message: enhancedMessage,
667
669
  requestBodyValues: context?.requestBody,
@@ -672,14 +674,21 @@ Request ID: ${requestId}`;
672
674
  });
673
675
  }
674
676
  function convertToAISDKError(error, context) {
675
- if (import_provider2.APICallError.isInstance(error) || import_provider2.LoadAPIKeyError.isInstance(error) || import_provider2.NoSuchModelError.isInstance(error) || import_provider2.InvalidPromptError.isInstance(error) || import_provider2.UnsupportedFunctionalityError.isInstance(error)) {
677
+ if (import_provider3.APICallError.isInstance(error) || import_provider3.LoadAPIKeyError.isInstance(error) || import_provider3.NoSuchModelError.isInstance(error) || import_provider3.InvalidPromptError.isInstance(error) || import_provider3.UnsupportedFunctionalityError.isInstance(error)) {
676
678
  return error;
677
679
  }
678
- const { aborted, response, rootError } = inspectError(error);
680
+ const { aborted, networkCode, noMatchingDeployment, response, rootError, syntaxError } = inspectError(error);
681
+ if (noMatchingDeployment && !aborted) {
682
+ return new import_provider3.NoSuchModelError({
683
+ message: "SAP AI Core has no running deployment matching the requested model. Check the model ID, model version, resource group, and deployment status in your SAP AI Core instance.",
684
+ modelId: context?.modelId ?? "unknown",
685
+ modelType: context?.modelType ?? "languageModel"
686
+ });
687
+ }
679
688
  const responseHeaders = context?.responseHeaders ?? normalizeHeaders(response?.headers);
680
689
  if (!aborted) {
681
690
  const errorResponse = findStructuredErrorResponse(
682
- rootError instanceof SyntaxError ? void 0 : rootError,
691
+ syntaxError ? void 0 : rootError,
683
692
  response?.data
684
693
  );
685
694
  if (errorResponse) {
@@ -697,7 +706,8 @@ function convertToAISDKError(error, context) {
697
706
  };
698
707
  if (aborted) {
699
708
  return createAPICallError(
700
- error,
709
+ // Preserve cancellation priority without retaining credential-bearing criteria.
710
+ noMatchingDeployment ? void 0 : error,
701
711
  {
702
712
  isRetryable: false,
703
713
  message: "Request was aborted by the client",
@@ -706,33 +716,44 @@ function convertToAISDKError(error, context) {
706
716
  resolvedContext
707
717
  );
708
718
  }
709
- if (isHttpStatus(response?.status)) {
719
+ if (isHttpStatus(response?.status) && (networkCode === void 0 || syntaxError !== void 0 || response.status < 200 || response.status >= 300)) {
710
720
  return createAPICallError(
711
721
  error,
712
722
  {
713
723
  isRetryable: isRetryable(response.status),
714
- message: rootError instanceof SyntaxError && error instanceof Error ? error.message : rootError instanceof Error ? rootError.message : "SAP AI Core request failed",
724
+ message: syntaxError && error instanceof Error ? error.message : rootError instanceof Error ? rootError.message : "SAP AI Core request failed",
715
725
  statusCode: response.status
716
726
  },
717
727
  resolvedContext
718
728
  );
719
729
  }
720
- if (rootError instanceof SyntaxError) {
730
+ if (syntaxError) {
721
731
  return createAPICallError(
722
732
  error,
723
733
  {
724
734
  isRetryable: false,
725
- message: error instanceof Error && error !== rootError ? error.message : "Failed to parse SAP AI Core data.",
735
+ message: error instanceof Error && error !== syntaxError ? error.message : "Failed to parse SAP AI Core data.",
726
736
  statusCode: HTTP_STATUS.INTERNAL_ERROR
727
737
  },
728
738
  resolvedContext
729
739
  );
730
740
  }
741
+ if (networkCode) {
742
+ return createAPICallError(
743
+ error,
744
+ {
745
+ isRetryable: true,
746
+ message: `SAP AI Core network error (${networkCode})`,
747
+ statusCode: HTTP_STATUS.SERVICE_UNAVAILABLE
748
+ },
749
+ resolvedContext
750
+ );
751
+ }
731
752
  if (rootError instanceof Error) {
732
753
  const errorMsg = rootError.message.toLowerCase();
733
754
  const originalErrorMsg = rootError.message;
734
755
  if (AUTHENTICATION_ERROR_KEYWORDS.some((keyword) => errorMsg.includes(keyword))) {
735
- return new import_provider2.LoadAPIKeyError({
756
+ return new import_provider3.LoadAPIKeyError({
736
757
  message: `SAP AI Core authentication failed: ${originalErrorMsg}
737
758
 
738
759
  Make sure your AICORE_SERVICE_KEY environment variable is set correctly.
@@ -741,7 +762,7 @@ See: https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-serv
741
762
  }
742
763
  if (DEPLOYMENT_ERROR_KEYWORDS.some((keyword) => errorMsg.includes(keyword))) {
743
764
  const modelId = context?.modelId ?? extractModelIdentifier(originalErrorMsg);
744
- return new import_provider2.NoSuchModelError({
765
+ return new import_provider3.NoSuchModelError({
745
766
  message: `SAP AI Core deployment error: ${originalErrorMsg}
746
767
 
747
768
  Make sure you have a running orchestration deployment in your SAP AI Core instance.
@@ -813,7 +834,7 @@ function normalizeHeaders(headers) {
813
834
  return Object.fromEntries(entries);
814
835
  }
815
836
  function createAPICallError(error, options, context) {
816
- return new import_provider2.APICallError({
837
+ return new import_provider3.APICallError({
817
838
  cause: error,
818
839
  isRetryable: options.isRetryable,
819
840
  message: options.message,
@@ -887,10 +908,18 @@ function inspectError(error) {
887
908
  let current = error;
888
909
  let response;
889
910
  let aborted = false;
911
+ let networkCode;
912
+ let noMatchingDeployment = false;
913
+ let syntaxError;
890
914
  while (typeof current === "object" && current !== null && !seen.has(current)) {
891
915
  seen.add(current);
892
916
  rootError = current;
917
+ noMatchingDeployment ||= current instanceof Error && current.message.startsWith("No deployment matched the given criteria:");
893
918
  aborted ||= isAbortError(current);
919
+ if (current instanceof SyntaxError) syntaxError ??= current;
920
+ if (current instanceof Error && "code" in current && typeof current.code === "string") {
921
+ if (RETRYABLE_NETWORK_CODES.has(current.code)) networkCode ??= current.code;
922
+ }
894
923
  const entry = current;
895
924
  if (response === void 0 && entry.isAxiosError === true) response = entry.response;
896
925
  const cause = "cause" in entry ? entry.cause : current instanceof Error && (0, import_util.isErrorWithCause)(current) ? current.rootCause : void 0;
@@ -900,7 +929,7 @@ function inspectError(error) {
900
929
  rootError = cause;
901
930
  current = cause;
902
931
  }
903
- return { aborted, response, rootError };
932
+ return { aborted, networkCode, noMatchingDeployment, response, rootError, syntaxError };
904
933
  }
905
934
  function isAbortError(error) {
906
935
  if (error instanceof DOMException && error.name === "AbortError") {
@@ -1009,11 +1038,11 @@ function tryExtractSAPErrorFromMessage(message) {
1009
1038
  return null;
1010
1039
  }
1011
1040
  }
1012
- var import_provider2, import_util, HTTP_STATUS, ERROR_MATCHERS, AUTHENTICATION_ERROR_KEYWORDS, DEPLOYMENT_ERROR_KEYWORDS, ApiSwitchError, UnsupportedFeatureError;
1041
+ var import_provider3, import_util, HTTP_STATUS, RETRYABLE_NETWORK_CODES, ERROR_MATCHERS, AUTHENTICATION_ERROR_KEYWORDS, DEPLOYMENT_ERROR_KEYWORDS, ApiSwitchError, UnsupportedFeatureError;
1013
1042
  var init_sap_ai_error = __esm({
1014
1043
  "src/sap-ai-error.ts"() {
1015
1044
  "use strict";
1016
- import_provider2 = require("@ai-sdk/provider");
1045
+ import_provider3 = require("@ai-sdk/provider");
1017
1046
  import_util = require("@sap-cloud-sdk/util");
1018
1047
  HTTP_STATUS = {
1019
1048
  BAD_REQUEST: 400,
@@ -1027,6 +1056,17 @@ var init_sap_ai_error = __esm({
1027
1056
  SERVICE_UNAVAILABLE: 503,
1028
1057
  UNAUTHORIZED: 401
1029
1058
  };
1059
+ RETRYABLE_NETWORK_CODES = /* @__PURE__ */ new Set([
1060
+ "EAI_AGAIN",
1061
+ "ECONNABORTED",
1062
+ "ECONNREFUSED",
1063
+ "ECONNRESET",
1064
+ "EHOSTUNREACH",
1065
+ "ENETUNREACH",
1066
+ "ENOTFOUND",
1067
+ "EPIPE",
1068
+ "ETIMEDOUT"
1069
+ ]);
1030
1070
  ERROR_MATCHERS = [
1031
1071
  {
1032
1072
  category: "network",
@@ -1160,8 +1200,13 @@ The model's response was blocked by content safety filters. Try a different prom
1160
1200
  * @param suggestedApi - The API that supports this feature.
1161
1201
  */
1162
1202
  constructor(feature, api, suggestedApi) {
1163
- const apiName = api === "foundation-models" ? "Foundation Models" : "Orchestration";
1164
- const suggestedApiName = suggestedApi === "foundation-models" ? "Foundation Models" : "Orchestration";
1203
+ const names = {
1204
+ "foundation-models": "Foundation Models",
1205
+ orchestration: "Orchestration",
1206
+ responses: "Responses"
1207
+ };
1208
+ const apiName = names[api];
1209
+ const suggestedApiName = names[suggestedApi];
1165
1210
  super(`${feature} is not supported by ${apiName} API. Use ${suggestedApiName} API instead.`);
1166
1211
  this.feature = feature;
1167
1212
  this.api = api;
@@ -1175,6 +1220,98 @@ The model's response was blocked by content safety filters. Try a different prom
1175
1220
  }
1176
1221
  });
1177
1222
 
1223
+ // src/abort-utils.ts
1224
+ function createAbortError(reason) {
1225
+ const error = new Error("The operation was aborted.", { cause: reason });
1226
+ error.name = "AbortError";
1227
+ return error;
1228
+ }
1229
+ function throwIfAborted(signal) {
1230
+ if (signal?.aborted) throw createAbortError(signal.reason);
1231
+ }
1232
+ function waitWithAbort(pending, signal, onAbortedValue) {
1233
+ if (!signal) return pending;
1234
+ return new Promise((resolve, reject) => {
1235
+ let listening = true;
1236
+ const cleanup = () => {
1237
+ if (!listening) return;
1238
+ listening = false;
1239
+ signal.removeEventListener("abort", onAbort);
1240
+ };
1241
+ const onAbort = () => {
1242
+ cleanup();
1243
+ reject(createAbortError(signal.reason));
1244
+ };
1245
+ signal.addEventListener("abort", onAbort, { once: true });
1246
+ void pending.then(
1247
+ (value) => {
1248
+ cleanup();
1249
+ if (signal.aborted) {
1250
+ try {
1251
+ onAbortedValue?.(value);
1252
+ } finally {
1253
+ reject(createAbortError(signal.reason));
1254
+ }
1255
+ } else {
1256
+ resolve(value);
1257
+ }
1258
+ },
1259
+ (error) => {
1260
+ cleanup();
1261
+ reject(error);
1262
+ }
1263
+ ).catch((error) => {
1264
+ cleanup();
1265
+ reject(error);
1266
+ });
1267
+ if (signal.aborted) onAbort();
1268
+ });
1269
+ }
1270
+ var init_abort_utils = __esm({
1271
+ "src/abort-utils.ts"() {
1272
+ "use strict";
1273
+ }
1274
+ });
1275
+
1276
+ // src/deep-merge.ts
1277
+ function deepMerge(...sources) {
1278
+ const result = {};
1279
+ for (const source of sources) {
1280
+ if (source != null) mergeInto(result, source, /* @__PURE__ */ new Set(), 0);
1281
+ }
1282
+ return result;
1283
+ }
1284
+ function isPlainObject(value) {
1285
+ if (value === null || typeof value !== "object") return false;
1286
+ const proto = Object.getPrototypeOf(value);
1287
+ return proto === Object.prototype || proto === null;
1288
+ }
1289
+ function mergeInto(target, source, ancestors, depth) {
1290
+ if (depth > MAX_DEPTH) throw new Error("Maximum merge depth exceeded");
1291
+ if (ancestors.has(source)) throw new Error("Circular reference detected during deep merge");
1292
+ ancestors.add(source);
1293
+ for (const key of Object.keys(source)) {
1294
+ const sourceValue = source[key];
1295
+ const targetValue = Object.hasOwn(target, key) ? target[key] : void 0;
1296
+ const value = isPlainObject(sourceValue) ? mergeInto(isPlainObject(targetValue) ? targetValue : {}, sourceValue, ancestors, depth + 1) : sourceValue;
1297
+ Object.defineProperty(target, key, {
1298
+ configurable: true,
1299
+ enumerable: true,
1300
+ value,
1301
+ writable: true
1302
+ });
1303
+ }
1304
+ ancestors.delete(source);
1305
+ return target;
1306
+ }
1307
+ var MAX_DEPTH;
1308
+ var init_deep_merge = __esm({
1309
+ "src/deep-merge.ts"() {
1310
+ "use strict";
1311
+ MAX_DEPTH = 100;
1312
+ }
1313
+ });
1314
+
1178
1315
  // src/strategy-utils.ts
1179
1316
  function applyParameterOverrides(modelParams, options, sapModelParams, settingsModelParams, mappings) {
1180
1317
  for (const mapping of mappings) {
@@ -1225,9 +1362,23 @@ function buildGenerateResult(config) {
1225
1362
  const content = [];
1226
1363
  const tokenUsage = response.getTokenUsage();
1227
1364
  const finishReasonRaw = response.getFinishReason();
1228
- const finishReason = mapFinishReason(finishReasonRaw);
1365
+ const providerSpecificFields = parseProviderSpecificFields(
1366
+ response.getProviderSpecificFields?.()
1367
+ );
1368
+ const finishReason = mapFinishReason(
1369
+ finishReasonRaw,
1370
+ getProviderFinishReason(providerSpecificFields)
1371
+ );
1229
1372
  const textContent = response.getContent();
1230
1373
  const toolCalls = response.getToolCalls();
1374
+ for (const block of response.getReasoningBlocks?.() ?? []) {
1375
+ const validatedBlock = orchestrationReasoningBlockSchema.parse(block);
1376
+ content.push({
1377
+ providerMetadata: buildOrchestrationReasoningMetadata(validatedBlock, providerName),
1378
+ text: validatedBlock.content ?? "",
1379
+ type: "reasoning"
1380
+ });
1381
+ }
1231
1382
  if (textContent) content.push({ text: textContent, type: "text" });
1232
1383
  for (const toolCall of toolCalls ?? []) {
1233
1384
  content.push({
@@ -1262,9 +1413,10 @@ function buildGenerateResult(config) {
1262
1413
  providerMetadata: {
1263
1414
  [providerName]: {
1264
1415
  ...buildAnthropicCacheMetadata(tokenUsage),
1265
- finishReason: finishReasonRaw ?? "unknown",
1416
+ finishReason: finishReason.raw ?? "unknown",
1266
1417
  finishReasonMapped: finishReason,
1267
1418
  ...intermediateFailures?.length ? { intermediateFailures: sanitizeAsJSONArray(intermediateFailures) } : {},
1419
+ ...providerSpecificFields && { providerSpecificFields },
1268
1420
  ...requestId ? { requestId } : {},
1269
1421
  version
1270
1422
  }
@@ -1535,8 +1687,8 @@ function isZodSchema(obj) {
1535
1687
  const record = obj;
1536
1688
  return "_def" in record && "parse" in record && hasCallableParse(record);
1537
1689
  }
1538
- function mapFinishReason(reason) {
1539
- const raw = reason ?? void 0;
1690
+ function mapFinishReason(reason, originalReason) {
1691
+ const raw = originalReason ?? reason ?? void 0;
1540
1692
  if (!reason) {
1541
1693
  return { raw, unified: "other" };
1542
1694
  }
@@ -1631,6 +1783,18 @@ function normalizeEmbedding(embedding) {
1631
1783
  );
1632
1784
  return Array.from(float32Array);
1633
1785
  }
1786
+ function buildOrchestrationReasoningMetadata(block, providerName) {
1787
+ return { [providerName]: { reasoningContent: block } };
1788
+ }
1789
+ function getProviderFinishReason(fields) {
1790
+ const reason = fields?.finish_reason;
1791
+ return typeof reason === "string" && reason.length > 0 ? reason : void 0;
1792
+ }
1793
+ function parseProviderSpecificFields(value) {
1794
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
1795
+ const fields = sanitizeAsJSONObject(value);
1796
+ return fields !== null && typeof fields === "object" && !Array.isArray(fields) ? fields : void 0;
1797
+ }
1634
1798
  function sanitizeAsJSONArray(value) {
1635
1799
  try {
1636
1800
  return JSON.parse(JSON.stringify(value, jsonReplacer));
@@ -1662,16 +1826,17 @@ var VERSION;
1662
1826
  var init_version = __esm({
1663
1827
  "src/version.ts"() {
1664
1828
  "use strict";
1665
- VERSION = true ? "5.0.2" : "0.0.0-test";
1829
+ VERSION = true ? "5.1.0" : "0.0.0-test";
1666
1830
  }
1667
1831
  });
1668
1832
 
1669
1833
  // src/base-embedding-model-strategy.ts
1670
- var import_provider3, BaseEmbeddingModelStrategy;
1834
+ var import_provider4, BaseEmbeddingModelStrategy;
1671
1835
  var init_base_embedding_model_strategy = __esm({
1672
1836
  "src/base-embedding-model-strategy.ts"() {
1673
1837
  "use strict";
1674
- import_provider3 = require("@ai-sdk/provider");
1838
+ import_provider4 = require("@ai-sdk/provider");
1839
+ init_abort_utils();
1675
1840
  init_deep_merge();
1676
1841
  init_sap_ai_error();
1677
1842
  init_sap_ai_provider_options();
@@ -1691,25 +1856,30 @@ var init_base_embedding_model_strategy = __esm({
1691
1856
  const { abortSignal, values } = options;
1692
1857
  try {
1693
1858
  if (values.length > maxEmbeddingsPerCall) {
1694
- throw new import_provider3.TooManyEmbeddingValuesForCallError({
1859
+ throw new import_provider4.TooManyEmbeddingValuesForCallError({
1695
1860
  maxEmbeddingsPerCall,
1696
1861
  modelId: config.modelId,
1697
1862
  provider: config.provider,
1698
1863
  values
1699
1864
  });
1700
1865
  }
1866
+ throwIfAborted(abortSignal);
1701
1867
  const embeddingOptions = config.parsedProviderOptions;
1702
1868
  const providerName = getProviderName(config.provider);
1703
1869
  const embeddingType = embeddingOptions?.type ?? settings.type ?? "text";
1704
1870
  const warnings = [];
1705
1871
  this.resolveWarnings(settings, warnings);
1706
1872
  const client = this.createClient(config, settings, embeddingOptions);
1707
- const response = await this.executeCall(
1708
- client,
1709
- values,
1710
- embeddingType,
1711
- mergeRequestConfig(config.requestConfig, abortSignal, options.headers)
1873
+ const response = await waitWithAbort(
1874
+ this.executeCall(
1875
+ client,
1876
+ values,
1877
+ embeddingType,
1878
+ mergeRequestConfig(config.requestConfig, abortSignal, options.headers)
1879
+ ),
1880
+ abortSignal
1712
1881
  );
1882
+ throwIfAborted(abortSignal);
1713
1883
  const embeddings = this.extractEmbeddings(response);
1714
1884
  const totalTokens = this.extractTokenCount(response);
1715
1885
  const { headers: responseHeaders, requestId } = this.extractResponseMetadata(response);
@@ -1724,7 +1894,7 @@ var init_base_embedding_model_strategy = __esm({
1724
1894
  warnings
1725
1895
  });
1726
1896
  } catch (error) {
1727
- if (error instanceof import_provider3.TooManyEmbeddingValuesForCallError) {
1897
+ if (error instanceof import_provider4.TooManyEmbeddingValuesForCallError) {
1728
1898
  throw error;
1729
1899
  }
1730
1900
  throw convertToAISDKError(error, {
@@ -1825,22 +1995,22 @@ var init_foundation_models_embedding_model_strategy = __esm({
1825
1995
 
1826
1996
  // src/sap-ai-validation.ts
1827
1997
  function validateEscapeTemplatePlaceholders(api, escapeTemplatePlaceholders) {
1828
- if (api === "foundation-models" && escapeTemplatePlaceholders === true) {
1998
+ if (api !== "orchestration" && escapeTemplatePlaceholders === true) {
1829
1999
  throw new UnsupportedFeatureError(
1830
2000
  ESCAPE_TEMPLATE_PLACEHOLDERS_DESCRIPTION,
1831
- "foundation-models",
2001
+ api,
1832
2002
  "orchestration"
1833
2003
  );
1834
2004
  }
1835
2005
  }
1836
- function validateFoundationModelsOnlyOptions(settings) {
2006
+ function validateFoundationModelsOnlyOptions(api, settings) {
1837
2007
  if (!settings) return;
1838
2008
  const fmSettings = settings;
1839
2009
  for (const feature of FOUNDATION_MODELS_ONLY_FEATURE_KEYS) {
1840
2010
  if (fmSettings[feature] !== void 0) {
1841
2011
  throw new UnsupportedFeatureError(
1842
2012
  FOUNDATION_MODELS_ONLY_FEATURES[feature],
1843
- "orchestration",
2013
+ api,
1844
2014
  "foundation-models"
1845
2015
  );
1846
2016
  }
@@ -1858,23 +2028,19 @@ function validateOrchestrationOnlyEmbeddingOptions(settings) {
1858
2028
  }
1859
2029
  }
1860
2030
  }
1861
- function validateOrchestrationOnlyOptions(settings) {
2031
+ function validateOrchestrationOnlyOptions(api, settings) {
1862
2032
  if (!settings) return;
1863
2033
  const orchSettings = settings;
1864
2034
  for (const feature of ORCHESTRATION_ONLY_FEATURE_KEYS) {
1865
2035
  if (orchSettings[feature] !== void 0) {
1866
- throw new UnsupportedFeatureError(
1867
- ORCHESTRATION_ONLY_FEATURES[feature],
1868
- "foundation-models",
1869
- "orchestration"
1870
- );
2036
+ throw new UnsupportedFeatureError(ORCHESTRATION_ONLY_FEATURES[feature], api, "orchestration");
1871
2037
  }
1872
2038
  }
1873
2039
  }
1874
2040
  function validateApiSwitch(fromApi, toApi, modelSettings, embeddingSettings) {
1875
2041
  if (fromApi === toApi) return;
1876
2042
  if (!modelSettings && !embeddingSettings) return;
1877
- if (fromApi === "orchestration" && toApi === "foundation-models") {
2043
+ if (toApi !== "orchestration") {
1878
2044
  const orchSettings = modelSettings;
1879
2045
  for (const feature of ORCHESTRATION_ONLY_FEATURE_KEYS) {
1880
2046
  if (orchSettings?.[feature] !== void 0) {
@@ -1887,7 +2053,7 @@ function validateApiSwitch(fromApi, toApi, modelSettings, embeddingSettings) {
1887
2053
  }
1888
2054
  }
1889
2055
  }
1890
- if (fromApi === "foundation-models" && toApi === "orchestration") {
2056
+ if (toApi !== "foundation-models") {
1891
2057
  const fmSettings = modelSettings;
1892
2058
  for (const feature of FOUNDATION_MODELS_ONLY_FEATURE_KEYS) {
1893
2059
  if (fmSettings?.[feature] !== void 0) {
@@ -1895,6 +2061,9 @@ function validateApiSwitch(fromApi, toApi, modelSettings, embeddingSettings) {
1895
2061
  }
1896
2062
  }
1897
2063
  }
2064
+ if (toApi !== "responses" && modelSettings && "responses" in modelSettings && modelSettings.responses !== void 0) {
2065
+ throw new ApiSwitchError(fromApi, toApi, "responses");
2066
+ }
1898
2067
  }
1899
2068
  function mergeSettingsWithApi(defaultSettings, callSettings, fallbackApi) {
1900
2069
  return {
@@ -1945,27 +2114,44 @@ function validateSettings(options) {
1945
2114
  );
1946
2115
  }
1947
2116
  }
1948
- if (api === "foundation-models") {
1949
- validateOrchestrationOnlyOptions(modelSettings);
1950
- validateOrchestrationOnlyInvocationOptions(invocationSettings);
2117
+ if (api === "responses" && embeddingSettings !== void 0) {
2118
+ throw new UnsupportedFeatureError("Embeddings", "responses", "foundation-models");
2119
+ }
2120
+ if (api !== "orchestration") {
2121
+ validateOrchestrationOnlyOptions(api, modelSettings);
2122
+ validateOrchestrationOnlyInvocationOptions(api, invocationSettings);
1951
2123
  validateOrchestrationOnlyEmbeddingOptions(embeddingSettings);
2124
+ }
2125
+ if (api !== "foundation-models") {
2126
+ validateFoundationModelsOnlyOptions(api, modelSettings);
2127
+ }
2128
+ const modelResponses = modelSettings && "responses" in modelSettings ? modelSettings.responses : void 0;
2129
+ const invocationResponses = invocationSettings?.responses;
2130
+ if (api !== "responses") {
2131
+ if (modelResponses !== void 0 || invocationResponses !== void 0) {
2132
+ throw new UnsupportedFeatureError("Responses options (responses)", api, "responses");
2133
+ }
1952
2134
  } else {
1953
- validateFoundationModelsOnlyOptions(modelSettings);
2135
+ if (modelResponses !== void 0) responsesModelOptionsSchema.parse(modelResponses);
2136
+ if (invocationResponses !== void 0) responsesModelOptionsSchema.parse(invocationResponses);
2137
+ }
2138
+ const modelDropUnsupportedParams = modelSettings?.dropUnsupportedParams;
2139
+ if (modelDropUnsupportedParams !== void 0) {
2140
+ dropUnsupportedParamsSchema.parse(modelDropUnsupportedParams);
2141
+ }
2142
+ if (invocationSettings?.dropUnsupportedParams !== void 0) {
2143
+ dropUnsupportedParamsSchema.parse(invocationSettings.dropUnsupportedParams);
1954
2144
  }
1955
2145
  const modelEscape = modelSettings?.escapeTemplatePlaceholders;
1956
2146
  const invocationEscape = invocationSettings?.escapeTemplatePlaceholders;
1957
2147
  const effectiveEscape = invocationEscape ?? modelEscape;
1958
2148
  validateEscapeTemplatePlaceholders(api, effectiveEscape);
1959
2149
  }
1960
- function validateOrchestrationOnlyInvocationOptions(invocationSettings) {
2150
+ function validateOrchestrationOnlyInvocationOptions(api, invocationSettings) {
1961
2151
  if (!invocationSettings) return;
1962
2152
  for (const feature of ORCHESTRATION_ONLY_INVOCATION_FEATURE_KEYS) {
1963
2153
  if (invocationSettings[feature] !== void 0) {
1964
- throw new UnsupportedFeatureError(
1965
- ORCHESTRATION_ONLY_FEATURES[feature],
1966
- "foundation-models",
1967
- "orchestration"
1968
- );
2154
+ throw new UnsupportedFeatureError(ORCHESTRATION_ONLY_FEATURES[feature], api, "orchestration");
1969
2155
  }
1970
2156
  }
1971
2157
  }
@@ -1975,7 +2161,9 @@ var init_sap_ai_validation = __esm({
1975
2161
  "use strict";
1976
2162
  init_deep_merge();
1977
2163
  init_sap_ai_error();
2164
+ init_sap_ai_provider_options();
1978
2165
  ORCHESTRATION_ONLY_FEATURE_KEYS = [
2166
+ "dropUnsupportedParams",
1979
2167
  "fallbackModuleConfigs",
1980
2168
  "filtering",
1981
2169
  "grounding",
@@ -1988,6 +2176,7 @@ var init_sap_ai_validation = __esm({
1988
2176
  "translation"
1989
2177
  ];
1990
2178
  ORCHESTRATION_ONLY_FEATURES = {
2179
+ dropUnsupportedParams: "Unsupported parameter handling (dropUnsupportedParams)",
1991
2180
  fallbackModuleConfigs: "Fallback module configurations (fallbackModuleConfigs)",
1992
2181
  filtering: "Content filtering",
1993
2182
  grounding: "Document grounding",
@@ -2004,6 +2193,7 @@ var init_sap_ai_validation = __esm({
2004
2193
  dataSources: "Azure On Your Data (dataSources)"
2005
2194
  };
2006
2195
  ORCHESTRATION_ONLY_INVOCATION_FEATURE_KEYS = [
2196
+ "dropUnsupportedParams",
2007
2197
  "orchestrationConfigRef",
2008
2198
  "placeholderValues",
2009
2199
  "promptTemplateRef"
@@ -2012,75 +2202,1146 @@ var init_sap_ai_validation = __esm({
2012
2202
  ORCHESTRATION_ONLY_EMBEDDING_FEATURES = {
2013
2203
  masking: ORCHESTRATION_ONLY_FEATURES.masking
2014
2204
  };
2015
- ESCAPE_TEMPLATE_PLACEHOLDERS_DESCRIPTION = "escapeTemplatePlaceholders (Jinja2 template escaping)";
2016
- VALID_API_TYPES = ["orchestration", "foundation-models"];
2205
+ ESCAPE_TEMPLATE_PLACEHOLDERS_DESCRIPTION = "escapeTemplatePlaceholders (Jinja2 template escaping)";
2206
+ VALID_API_TYPES = [
2207
+ "orchestration",
2208
+ "foundation-models",
2209
+ "responses"
2210
+ ];
2211
+ }
2212
+ });
2213
+
2214
+ // src/orchestration-embedding-model-strategy.ts
2215
+ var orchestration_embedding_model_strategy_exports = {};
2216
+ __export(orchestration_embedding_model_strategy_exports, {
2217
+ OrchestrationEmbeddingModelStrategy: () => OrchestrationEmbeddingModelStrategy
2218
+ });
2219
+ var OrchestrationEmbeddingModelStrategy;
2220
+ var init_orchestration_embedding_model_strategy = __esm({
2221
+ "src/orchestration-embedding-model-strategy.ts"() {
2222
+ "use strict";
2223
+ init_base_embedding_model_strategy();
2224
+ init_sap_ai_validation();
2225
+ init_strategy_utils();
2226
+ OrchestrationEmbeddingModelStrategy = class extends BaseEmbeddingModelStrategy {
2227
+ ClientClass;
2228
+ constructor(ClientClass) {
2229
+ super();
2230
+ this.ClientClass = ClientClass;
2231
+ }
2232
+ createClient(config, settings, embeddingOptions) {
2233
+ const mergedParams = this.mergeModelParams(settings, embeddingOptions);
2234
+ const embeddingConfig = {
2235
+ model: {
2236
+ name: config.modelId,
2237
+ ...hasKeys(mergedParams) ? { params: mergedParams } : {},
2238
+ ...settings.modelVersion ? { version: settings.modelVersion } : {}
2239
+ }
2240
+ };
2241
+ const moduleConfig = {
2242
+ embeddings: embeddingConfig,
2243
+ ...settings.masking && hasKeys(settings.masking) ? { masking: settings.masking } : {}
2244
+ };
2245
+ return new this.ClientClass(moduleConfig, config.deploymentConfig, config.destination);
2246
+ }
2247
+ async executeCall(client, values, embeddingType, requestConfig) {
2248
+ return client.embed({ input: values, type: embeddingType }, requestConfig);
2249
+ }
2250
+ extractEmbeddings(response) {
2251
+ const embeddingData = response.getEmbeddings();
2252
+ const sortedEmbeddings = [...embeddingData].sort((a, b) => a.index - b.index);
2253
+ return sortedEmbeddings.map((data) => normalizeEmbedding(data.embedding));
2254
+ }
2255
+ extractResponseMetadata(response) {
2256
+ return extractResponseMetadata(response, "response");
2257
+ }
2258
+ extractTokenCount(response) {
2259
+ const tokenUsage = response.getTokenUsage();
2260
+ return tokenUsage.total_tokens;
2261
+ }
2262
+ getUrl() {
2263
+ return "sap-ai:orchestration/embeddings";
2264
+ }
2265
+ resolveWarnings(settings, warnings) {
2266
+ validateMaskingProvidersDeprecation(settings, warnings);
2267
+ }
2268
+ };
2269
+ }
2270
+ });
2271
+
2272
+ // src/responses-adapters-v3-to-v4.ts
2273
+ function convertResponsesCallToV4(options) {
2274
+ return {
2275
+ ...options,
2276
+ prompt: options.prompt.map((message) => {
2277
+ switch (message.role) {
2278
+ case "assistant":
2279
+ return { ...message, content: message.content.map(convertPromptPart) };
2280
+ case "system":
2281
+ return message;
2282
+ case "tool":
2283
+ return {
2284
+ ...message,
2285
+ content: message.content.map(
2286
+ (part) => part.type === "tool-result" ? convertToolResult(part) : part
2287
+ )
2288
+ };
2289
+ case "user":
2290
+ return {
2291
+ ...message,
2292
+ content: message.content.map(
2293
+ (part) => part.type === "file" ? convertFile(part) : part
2294
+ )
2295
+ };
2296
+ }
2297
+ })
2298
+ };
2299
+ }
2300
+ function convertFile(part) {
2301
+ const data = part.data;
2302
+ const href = getURLHref(data);
2303
+ if (href !== void 0) {
2304
+ const url = data instanceof URL && data.toString === URL.prototype.toString ? data : new URL(href);
2305
+ return { ...part, data: { type: "url", url } };
2306
+ }
2307
+ return { ...part, data: { data, type: "data" } };
2308
+ }
2309
+ function convertPromptPart(part) {
2310
+ if (part.type === "file") {
2311
+ throw new import_provider5.UnsupportedFunctionalityError({
2312
+ functionality: "Responses assistant file history is not supported."
2313
+ });
2314
+ }
2315
+ if (part.type === "tool-result") return convertToolResult(part);
2316
+ return part;
2317
+ }
2318
+ function convertToolItem(item) {
2319
+ switch (item.type) {
2320
+ case "custom":
2321
+ case "text":
2322
+ return item;
2323
+ case "file-data":
2324
+ case "image-data": {
2325
+ const delegateIsImage = (0, import_provider_utils2.getTopLevelMediaType)(item.mediaType) === "image";
2326
+ if (delegateIsImage !== (item.type === "image-data")) {
2327
+ throw new import_provider5.UnsupportedFunctionalityError({
2328
+ functionality: "Responses tool-result media whose legacy category disagrees with its media type."
2329
+ });
2330
+ }
2331
+ return { ...item, data: { data: item.data, type: "data" }, type: "file" };
2332
+ }
2333
+ case "file-id":
2334
+ case "image-file-id":
2335
+ return {
2336
+ data: {
2337
+ reference: typeof item.fileId === "string" ? { openai: item.fileId } : item.fileId,
2338
+ type: "reference"
2339
+ },
2340
+ mediaType: item.type === "image-file-id" ? "image" : "application/octet-stream",
2341
+ providerOptions: item.providerOptions,
2342
+ type: "file"
2343
+ };
2344
+ case "file-url":
2345
+ case "image-url":
2346
+ return {
2347
+ data: { type: "url", url: new URL(item.url) },
2348
+ mediaType: item.type === "image-url" ? "image" : "application/octet-stream",
2349
+ providerOptions: item.providerOptions,
2350
+ type: "file"
2351
+ };
2352
+ }
2353
+ }
2354
+ function convertToolResult(part) {
2355
+ return part.output.type === "content" ? { ...part, output: { ...part.output, value: part.output.value.map(convertToolItem) } } : { ...part, output: part.output };
2356
+ }
2357
+ var import_provider5, import_provider_utils2;
2358
+ var init_responses_adapters_v3_to_v4 = __esm({
2359
+ "src/responses-adapters-v3-to-v4.ts"() {
2360
+ "use strict";
2361
+ import_provider5 = require("@ai-sdk/provider");
2362
+ import_provider_utils2 = require("@ai-sdk/provider-utils");
2363
+ init_convert_to_sap_messages();
2364
+ }
2365
+ });
2366
+
2367
+ // src/adapter-metadata.ts
2368
+ var ORIGINAL_V4_FINISH_REASON;
2369
+ var init_adapter_metadata = __esm({
2370
+ "src/adapter-metadata.ts"() {
2371
+ "use strict";
2372
+ ORIGINAL_V4_FINISH_REASON = /* @__PURE__ */ Symbol.for(
2373
+ "@jerome-benoit/sap-ai-provider/adapter-metadata.originalV4FinishReason"
2374
+ );
2375
+ }
2376
+ });
2377
+
2378
+ // src/responses-adapters-v4-to-v3.ts
2379
+ function convertResponsesResultToV3(result) {
2380
+ return {
2381
+ ...result,
2382
+ content: result.content.map(convertContent),
2383
+ finishReason: convertFinishReason(result.finishReason),
2384
+ warnings: result.warnings.map(convertWarning)
2385
+ };
2386
+ }
2387
+ function convertResponsesStreamPartToV3(part) {
2388
+ switch (part.type) {
2389
+ case "custom":
2390
+ case "reasoning-file":
2391
+ throw new import_provider6.UnsupportedFunctionalityError({
2392
+ functionality: `Responses '${part.type}' output has no V3 equivalent.`
2393
+ });
2394
+ case "file":
2395
+ return convertGeneratedFile(part);
2396
+ case "finish":
2397
+ return { ...part, finishReason: convertFinishReason(part.finishReason) };
2398
+ case "stream-start":
2399
+ return { ...part, warnings: part.warnings.map(convertWarning) };
2400
+ default:
2401
+ return part;
2402
+ }
2403
+ }
2404
+ function convertContent(part) {
2405
+ if (part.type === "custom" || part.type === "reasoning-file") {
2406
+ throw new import_provider6.UnsupportedFunctionalityError({
2407
+ functionality: `Responses '${part.type}' output has no V3 equivalent.`
2408
+ });
2409
+ }
2410
+ return part.type === "file" ? convertGeneratedFile(part) : part;
2411
+ }
2412
+ function convertFinishReason(reason) {
2413
+ if (reason.unified !== "interrupted") return reason;
2414
+ const converted = { ...reason, unified: "other" };
2415
+ return Object.defineProperty(converted, ORIGINAL_V4_FINISH_REASON, { value: reason });
2416
+ }
2417
+ function convertGeneratedFile(part) {
2418
+ if (part.data.type !== "data") {
2419
+ throw new import_provider6.UnsupportedFunctionalityError({
2420
+ functionality: "Responses generated file URLs have no V3 equivalent and are not fetched."
2421
+ });
2422
+ }
2423
+ return { ...part, data: part.data.data };
2424
+ }
2425
+ function convertWarning(warning) {
2426
+ return warning.type === "deprecated" ? { message: `${warning.setting}: ${warning.message}`, type: "other" } : warning;
2427
+ }
2428
+ var import_provider6;
2429
+ var init_responses_adapters_v4_to_v3 = __esm({
2430
+ "src/responses-adapters-v4-to-v3.ts"() {
2431
+ "use strict";
2432
+ import_provider6 = require("@ai-sdk/provider");
2433
+ init_adapter_metadata();
2434
+ }
2435
+ });
2436
+
2437
+ // src/sap-http-stream.ts
2438
+ function destroyHttpResponse(response, retainedRequest) {
2439
+ const body = response.data;
2440
+ const request = response.request;
2441
+ try {
2442
+ if (isDestroyableRequest(body)) body.destroy();
2443
+ } finally {
2444
+ if (request !== retainedRequest && isDestroyableRequest(request)) request.destroy();
2445
+ }
2446
+ }
2447
+ function disposeSapStream(response) {
2448
+ if (disposedStreams.has(response)) return;
2449
+ disposedStreams.add(response);
2450
+ try {
2451
+ response.stream.controller.abort();
2452
+ } finally {
2453
+ if (leasedStreams.has(response)) releaseSapStream(response);
2454
+ else destroyHttpResponse(response.rawResponse);
2455
+ }
2456
+ }
2457
+ async function executeSapStream(execute, signal, requestConfig) {
2458
+ const responses = [];
2459
+ const cleanups = /* @__PURE__ */ new Set();
2460
+ let closed = false;
2461
+ let transferred = false;
2462
+ let failedRequest;
2463
+ let failedError;
2464
+ const release = () => {
2465
+ closed = true;
2466
+ signal?.removeEventListener("abort", release);
2467
+ for (const response of responses) {
2468
+ if (response.fromTransport && isConsumedHttpBody(response.data)) continue;
2469
+ const consumedRequest = responses.some(
2470
+ (other) => other.fromTransport && other.request === response.request && isConsumedHttpBody(other.data)
2471
+ );
2472
+ try {
2473
+ const dispose = response.disposeTimeout;
2474
+ const retainedRequest = consumedRequest ? response.request : void 0;
2475
+ if (dispose && cleanups.has(dispose)) dispose(retainedRequest);
2476
+ else destroyHttpResponse(response, retainedRequest);
2477
+ } catch {
2478
+ }
2479
+ }
2480
+ responses.length = 0;
2481
+ cleanups.clear();
2482
+ };
2483
+ const ownResponse = (response, request, fromTransport, failed) => {
2484
+ const data = response.data;
2485
+ const nativeRequest = response.request;
2486
+ const owned = responses.find((other) => other.data === data && other.request === nativeRequest);
2487
+ if (owned) {
2488
+ if (failed && !owned.disposeTimeout) {
2489
+ owned.disposeTimeout = preserveResponseBodyTimeout(response, request, cleanups);
2490
+ }
2491
+ } else {
2492
+ responses.push({
2493
+ data,
2494
+ disposeTimeout: failed ? preserveResponseBodyTimeout(response, request, cleanups) : void 0,
2495
+ fromTransport,
2496
+ request: nativeRequest
2497
+ });
2498
+ }
2499
+ if (closed || signal?.aborted) release();
2500
+ };
2501
+ const observeResponse = ({ fn }) => async (request) => {
2502
+ try {
2503
+ const response = await fn(request);
2504
+ ownResponse(response, request, true, false);
2505
+ return response;
2506
+ } catch (error) {
2507
+ const failed = findFailedHttpRequest(error);
2508
+ if (failed) ownResponse(failed.response, request, true, true);
2509
+ throw error;
2510
+ }
2511
+ };
2512
+ const captureFinalFailure = ({ fn }) => async (request) => {
2513
+ try {
2514
+ const response = await fn(request);
2515
+ ownResponse(response, request, false, false);
2516
+ return response;
2517
+ } catch (error) {
2518
+ const failed = findFailedHttpRequest(error);
2519
+ if (!failed) throw error;
2520
+ failedRequest = failed;
2521
+ failedError = error;
2522
+ ownResponse(failed.response, request, false, true);
2523
+ return failed.response;
2524
+ }
2525
+ };
2526
+ try {
2527
+ const response = await waitWithAbort(
2528
+ execute({
2529
+ ...requestConfig,
2530
+ middleware: [captureFinalFailure, ...requestConfig?.middleware ?? [], observeResponse]
2531
+ }),
2532
+ signal,
2533
+ disposeSapStream
2534
+ );
2535
+ if (signal?.aborted) {
2536
+ try {
2537
+ disposeSapStream(response);
2538
+ } finally {
2539
+ throwIfAborted(signal);
2540
+ }
2541
+ }
2542
+ if (failedRequest) {
2543
+ try {
2544
+ await readHttpErrorBody(
2545
+ failedRequest.response,
2546
+ createErrorByteStream(failedRequest.response),
2547
+ signal
2548
+ );
2549
+ } catch {
2550
+ throwIfAborted(signal);
2551
+ }
2552
+ throw failedError;
2553
+ }
2554
+ if (responses.length > 0) {
2555
+ streamLeases.set(response, release);
2556
+ leasedStreams.add(response);
2557
+ signal?.addEventListener("abort", release, { once: true });
2558
+ if (signal?.aborted) {
2559
+ releaseSapStream(response);
2560
+ throwIfAborted(signal);
2561
+ }
2562
+ transferred = true;
2563
+ }
2564
+ return response;
2565
+ } finally {
2566
+ if (!transferred) release();
2567
+ }
2568
+ }
2569
+ function findFailedHttpRequest(error) {
2570
+ const seen = /* @__PURE__ */ new Set();
2571
+ let current = error;
2572
+ for (let depth = 0; depth < 32; depth++) {
2573
+ if (typeof current !== "object" || current === null || seen.has(current)) return void 0;
2574
+ if (import_provider7.AISDKError.isInstance(current)) return void 0;
2575
+ seen.add(current);
2576
+ if (isFailedHttpRequest(current)) return current;
2577
+ current = "cause" in current ? current.cause : current instanceof Error && (0, import_util2.isErrorWithCause)(current) ? current.rootCause : void 0;
2578
+ }
2579
+ return void 0;
2580
+ }
2581
+ function isDestroyableRequest(request) {
2582
+ return typeof request === "object" && request !== null && "destroy" in request && typeof request.destroy === "function";
2583
+ }
2584
+ function preserveResponseBodyTimeout(response, requestConfig, cleanups) {
2585
+ const body = response.data;
2586
+ const request = response.request;
2587
+ if (!isHttpResponseEvents(body) || !isHttpResponseEvents(request)) return;
2588
+ const responseConfig = "config" in response ? response.config : void 0;
2589
+ const timeoutConfig = typeof responseConfig === "object" && responseConfig !== null && !Array.isArray(responseConfig) ? responseConfig : requestConfig;
2590
+ let ownsRequest = true;
2591
+ const release = () => {
2592
+ request.removeListener("timeout", onTimeout);
2593
+ body.removeListener("end", release);
2594
+ body.removeListener("error", onFailure);
2595
+ body.removeListener("close", onFailure);
2596
+ cleanups.delete(dispose);
2597
+ };
2598
+ const onFailure = () => {
2599
+ try {
2600
+ if (ownsRequest) request.destroy();
2601
+ } finally {
2602
+ release();
2603
+ }
2604
+ };
2605
+ const dispose = (retainedRequest) => {
2606
+ ownsRequest = request !== retainedRequest;
2607
+ request.removeListener("timeout", onTimeout);
2608
+ try {
2609
+ body.destroy();
2610
+ } finally {
2611
+ if (ownsRequest) request.destroy();
2612
+ }
2613
+ };
2614
+ const onTimeout = () => {
2615
+ const nativeResponse = "res" in request ? request.res : void 0;
2616
+ if (typeof nativeResponse === "object" && nativeResponse !== null && "complete" in nativeResponse && nativeResponse.complete === true) {
2617
+ release();
2618
+ return;
2619
+ }
2620
+ const timeout = timeoutConfig.timeout;
2621
+ const timeoutErrorMessage = timeoutConfig.timeoutErrorMessage;
2622
+ const transitional = timeoutConfig.transitional;
2623
+ const clarifyTimeoutError = typeof transitional === "object" && transitional !== null && "clarifyTimeoutError" in transitional && transitional.clarifyTimeoutError === true;
2624
+ const message = typeof timeoutErrorMessage === "string" && timeoutErrorMessage ? timeoutErrorMessage : (typeof timeout === "number" || typeof timeout === "string") && timeout ? `timeout of ${String(timeout)}ms exceeded` : "timeout exceeded";
2625
+ body.destroy(
2626
+ Object.assign(new Error(message), {
2627
+ code: clarifyTimeoutError ? "ETIMEDOUT" : "ECONNABORTED"
2628
+ })
2629
+ );
2630
+ request.destroy();
2631
+ };
2632
+ request.once("timeout", onTimeout);
2633
+ body.once("end", release);
2634
+ body.once("error", onFailure);
2635
+ body.once("close", onFailure);
2636
+ cleanups.add(dispose);
2637
+ return dispose;
2638
+ }
2639
+ async function readHttpErrorBody(response, stream, signal) {
2640
+ const decoder = new TextDecoder();
2641
+ const reader = stream.getReader();
2642
+ let retainedBytes = 0;
2643
+ let text = "";
2644
+ let truncated = false;
2645
+ let readFailure;
2646
+ try {
2647
+ for (; ; ) {
2648
+ const chunk = await waitWithAbort(reader.read(), signal);
2649
+ if (chunk.done) {
2650
+ text += decoder.decode();
2651
+ break;
2652
+ }
2653
+ const remaining = MAX_ERROR_BODY_BYTES - retainedBytes;
2654
+ text += decoder.decode(chunk.value.subarray(0, remaining), { stream: true });
2655
+ retainedBytes += Math.min(chunk.value.byteLength, remaining);
2656
+ if (chunk.value.byteLength > remaining) {
2657
+ truncated = true;
2658
+ await reader.cancel("HTTP error diagnostic limit exceeded");
2659
+ break;
2660
+ }
2661
+ }
2662
+ } catch (error) {
2663
+ readFailure = error;
2664
+ if (!truncated) text += decoder.decode();
2665
+ void reader.cancel(error).catch(() => {
2666
+ });
2667
+ } finally {
2668
+ if (signal?.aborted) {
2669
+ destroyHttpResponse(response);
2670
+ void reader.cancel(signal.reason).catch(() => {
2671
+ });
2672
+ }
2673
+ reader.releaseLock();
2674
+ }
2675
+ response.data = truncated ? text + ERROR_BODY_TRUNCATION : text;
2676
+ if (!truncated && readFailure === void 0) {
2677
+ try {
2678
+ response.data = JSON.parse(text);
2679
+ } catch {
2680
+ response.data = text;
2681
+ }
2682
+ }
2683
+ throwIfAborted(signal);
2684
+ return readFailure;
2685
+ }
2686
+ function withSapStreamCleanup(response, stream) {
2687
+ if (!streamLeases.has(response)) return stream;
2688
+ return iterate();
2689
+ async function* iterate() {
2690
+ try {
2691
+ yield* stream;
2692
+ } finally {
2693
+ releaseSapStream(response);
2694
+ }
2695
+ }
2696
+ }
2697
+ function createErrorByteStream(response) {
2698
+ const body = response.data;
2699
+ if (typeof body !== "object" || body === null || !(Symbol.asyncIterator in body) || typeof body[Symbol.asyncIterator] !== "function") {
2700
+ throw new TypeError("SAP did not return a readable HTTP error body.");
2701
+ }
2702
+ const iterator = body[Symbol.asyncIterator]();
2703
+ const encoder = new TextEncoder();
2704
+ return new ReadableStream(
2705
+ {
2706
+ cancel() {
2707
+ destroyHttpResponse(response);
2708
+ },
2709
+ async pull(controller) {
2710
+ try {
2711
+ const chunk = await iterator.next();
2712
+ if (chunk.done) controller.close();
2713
+ else if (typeof chunk.value === "string") controller.enqueue(encoder.encode(chunk.value));
2714
+ else if (chunk.value instanceof Uint8Array) controller.enqueue(chunk.value);
2715
+ else throw new TypeError("SAP returned a non-byte HTTP error chunk.");
2716
+ } catch (error) {
2717
+ try {
2718
+ destroyHttpResponse(response);
2719
+ } catch {
2720
+ } finally {
2721
+ controller.error(error);
2722
+ }
2723
+ }
2724
+ }
2725
+ },
2726
+ { highWaterMark: 0 }
2727
+ );
2728
+ }
2729
+ function isConsumedHttpBody(body) {
2730
+ return typeof body === "object" && body !== null && "readableEnded" in body && body.readableEnded === true;
2731
+ }
2732
+ function isFailedHttpRequest(error) {
2733
+ return error instanceof Error && "isAxiosError" in error && error.isAxiosError === true && "response" in error && typeof error.response === "object" && error.response !== null;
2734
+ }
2735
+ function isHttpResponseEvents(value) {
2736
+ return isDestroyableRequest(value) && "once" in value && typeof value.once === "function" && "removeListener" in value && typeof value.removeListener === "function";
2737
+ }
2738
+ function releaseSapStream(response) {
2739
+ const release = streamLeases.get(response);
2740
+ streamLeases.delete(response);
2741
+ release?.();
2742
+ }
2743
+ var import_provider7, import_util2, ERROR_BODY_TRUNCATION, MAX_ERROR_BODY_BYTES, ERROR_BODY_READ_FAILURE, disposedStreams, leasedStreams, streamLeases;
2744
+ var init_sap_http_stream = __esm({
2745
+ "src/sap-http-stream.ts"() {
2746
+ "use strict";
2747
+ import_provider7 = require("@ai-sdk/provider");
2748
+ import_util2 = require("@sap-cloud-sdk/util");
2749
+ init_abort_utils();
2750
+ ERROR_BODY_TRUNCATION = "...[truncated]";
2751
+ MAX_ERROR_BODY_BYTES = 2e3 - ERROR_BODY_TRUNCATION.length;
2752
+ ERROR_BODY_READ_FAILURE = /* @__PURE__ */ Symbol("sap-ai.httpErrorBodyReadFailure");
2753
+ disposedStreams = /* @__PURE__ */ new WeakSet();
2754
+ leasedStreams = /* @__PURE__ */ new WeakSet();
2755
+ streamLeases = /* @__PURE__ */ new WeakMap();
2756
+ }
2757
+ });
2758
+
2759
+ // src/responses-http-transport.ts
2760
+ async function createResponsesTransport(config, settings, options) {
2761
+ throwIfAborted(options.abortSignal);
2762
+ const deployment = buildModelDeployment(config, settings.modelVersion);
2763
+ const [deploymentId, destination] = await waitWithAbort(
2764
+ Promise.all([
2765
+ (0, import_internal.getFoundationModelDeploymentId)(deployment, "azure-openai", config.destination),
2766
+ (0, import_core.getAiCoreDestination)(config.destination)
2767
+ ]),
2768
+ options.abortSignal
2769
+ );
2770
+ throwIfAborted(options.abortSignal);
2771
+ const deploymentPath = `/inference/deployments/${encodeURIComponent(deploymentId)}`;
2772
+ const baseURL = (0, import_internal2.getTargetUrl)(destination.url, deploymentPath);
2773
+ const endpoint = new URL(`${baseURL}/responses`);
2774
+ const requestConfig = mergeRequestConfig(
2775
+ config.requestConfig,
2776
+ options.abortSignal,
2777
+ options.headers
2778
+ );
2779
+ const activeRequests = /* @__PURE__ */ new Set();
2780
+ let disposed = false;
2781
+ let disposalReason;
2782
+ const dispose = (reason) => {
2783
+ if (disposed) return;
2784
+ disposed = true;
2785
+ disposalReason = reason;
2786
+ for (const release of activeRequests) {
2787
+ try {
2788
+ release(reason);
2789
+ } catch {
2790
+ }
2791
+ }
2792
+ activeRequests.clear();
2793
+ };
2794
+ const fetch = async (input, init) => {
2795
+ if (disposed) throw createAbortError(disposalReason);
2796
+ const url = new URL(typeof input === "string" || input instanceof URL ? input : input.url);
2797
+ if (url.origin !== endpoint.origin || url.pathname !== endpoint.pathname) {
2798
+ throw new TypeError("SAP Responses requests must target the configured deployment.");
2799
+ }
2800
+ if (init?.method !== "POST" || typeof init.body !== "string") {
2801
+ throw new TypeError("SAP Responses requires a POST request with a JSON body.");
2802
+ }
2803
+ const body = JSON.parse(init.body);
2804
+ const operation = typeof body === "object" && body !== null && "stream" in body && body.stream === true ? "doStream" : "doGenerate";
2805
+ const controller = new AbortController();
2806
+ const signal = options.abortSignal ?? init.signal;
2807
+ const bodyTimeoutCleanups = /* @__PURE__ */ new Set();
2808
+ let abortFailedRequest;
2809
+ let activeResponse;
2810
+ const onAbort = () => {
2811
+ controller.abort(signal?.reason);
2812
+ };
2813
+ const cleanup = () => {
2814
+ activeRequests.delete(disposeRequest);
2815
+ signal?.removeEventListener("abort", onAbort);
2816
+ if (abortFailedRequest) controller.signal.removeEventListener("abort", abortFailedRequest);
2817
+ for (const dispose2 of bodyTimeoutCleanups) dispose2();
2818
+ activeResponse = void 0;
2819
+ };
2820
+ const disposeRequest = (reason) => {
2821
+ try {
2822
+ controller.abort(reason);
2823
+ } finally {
2824
+ try {
2825
+ if (activeResponse) destroyHttpResponse(activeResponse);
2826
+ } finally {
2827
+ cleanup();
2828
+ }
2829
+ }
2830
+ };
2831
+ throwIfAborted(signal ?? void 0);
2832
+ signal?.addEventListener("abort", onAbort, { once: true });
2833
+ activeRequests.add(disposeRequest);
2834
+ const headers = new Headers(init.headers);
2835
+ headers.delete("authorization");
2836
+ const configuredHeaders = Object.fromEntries(
2837
+ Object.entries(requestConfig?.headers ?? {}).map(([key, value]) => [
2838
+ key.toLowerCase(),
2839
+ value
2840
+ ])
2841
+ );
2842
+ let failedRequest;
2843
+ let failedError;
2844
+ const watchResponse = (response, request) => {
2845
+ activeResponse = response;
2846
+ if (controller.signal.aborted) destroyHttpResponse(response);
2847
+ else preserveResponseBodyTimeout(response, request, bodyTimeoutCleanups);
2848
+ return response;
2849
+ };
2850
+ const preserveBodyTimeout = ({ fn }) => async (request) => {
2851
+ try {
2852
+ return watchResponse(await fn(request), request);
2853
+ } catch (error) {
2854
+ const failed = findFailedHttpRequest(error);
2855
+ if (failed) watchResponse(failed.response, request);
2856
+ throw error;
2857
+ }
2858
+ };
2859
+ const preserveErrorResponse = ({ fn }) => async (request) => {
2860
+ try {
2861
+ return await fn(request);
2862
+ } catch (error) {
2863
+ const failed = findFailedHttpRequest(error);
2864
+ if (!failed) throw error;
2865
+ failedRequest = failed;
2866
+ failedError = error;
2867
+ const request2 = failed.response.request;
2868
+ if (isDestroyableRequest(request2)) {
2869
+ abortFailedRequest = () => {
2870
+ request2.destroy();
2871
+ };
2872
+ if (controller.signal.aborted) abortFailedRequest();
2873
+ else controller.signal.addEventListener("abort", abortFailedRequest, { once: true });
2874
+ }
2875
+ return failed.response;
2876
+ }
2877
+ };
2878
+ try {
2879
+ const pendingResponse = (0, import_core.executeRequest)(
2880
+ {
2881
+ apiVersion: "2024-10-21",
2882
+ resourceGroup: (0, import_internal.getResourceGroup)(deployment),
2883
+ url: `${deploymentPath}/responses`
2884
+ },
2885
+ body,
2886
+ {
2887
+ ...requestConfig,
2888
+ headers: { ...Object.fromEntries(headers), ...configuredHeaders },
2889
+ middleware: [
2890
+ preserveErrorResponse,
2891
+ ...requestConfig?.middleware ?? [],
2892
+ preserveBodyTimeout
2893
+ ],
2894
+ responseType: "stream",
2895
+ signal: controller.signal
2896
+ },
2897
+ config.destination
2898
+ );
2899
+ const response = await waitWithAbort(pendingResponse, controller.signal, destroyHttpResponse);
2900
+ activeResponse = response;
2901
+ if (controller.signal.aborted) {
2902
+ destroyHttpResponse(response);
2903
+ throw createAbortError(controller.signal.reason);
2904
+ }
2905
+ const responseBody = response.data;
2906
+ const responseStream = createByteStream(
2907
+ responseBody,
2908
+ controller,
2909
+ cleanup,
2910
+ config,
2911
+ options,
2912
+ operation
2913
+ );
2914
+ if (failedRequest) {
2915
+ const readFailure = await readHttpErrorBody(
2916
+ failedRequest.response,
2917
+ responseStream,
2918
+ signal ?? void 0
2919
+ );
2920
+ const failure = convertToAISDKError(failedError, {
2921
+ modelId: config.modelId,
2922
+ modelType: "languageModel",
2923
+ operation,
2924
+ requestBody: createAISDKRequestBodySummary(options),
2925
+ url: "sap-ai:responses"
2926
+ });
2927
+ if (readFailure !== void 0 && import_provider8.APICallError.isInstance(failure)) {
2928
+ Object.defineProperty(failure, ERROR_BODY_READ_FAILURE, { value: readFailure });
2929
+ }
2930
+ throw failure;
2931
+ }
2932
+ return new Response(responseStream, {
2933
+ headers: normalizeHeaders(response.headers),
2934
+ status: response.status
2935
+ });
2936
+ } catch (error) {
2937
+ dispose(error);
2938
+ throw error;
2939
+ }
2940
+ };
2941
+ return { baseURL, dispose, fetch };
2942
+ }
2943
+ function createByteStream(body, requestController, cleanup, config, options, operation) {
2944
+ if (typeof body !== "object" || body === null || !(Symbol.asyncIterator in body) || typeof body[Symbol.asyncIterator] !== "function") {
2945
+ requestController.abort();
2946
+ cleanup();
2947
+ throw new TypeError("SAP Responses did not return a readable response body.");
2948
+ }
2949
+ const source = body;
2950
+ const iterator = source[Symbol.asyncIterator]();
2951
+ const encoder = new TextEncoder();
2952
+ const onAbort = () => source.destroy?.();
2953
+ const cleanupStream = () => {
2954
+ requestController.signal.removeEventListener("abort", onAbort);
2955
+ cleanup();
2956
+ };
2957
+ requestController.signal.addEventListener("abort", onAbort, { once: true });
2958
+ if (requestController.signal.aborted) onAbort();
2959
+ return new ReadableStream(
2960
+ {
2961
+ async cancel(reason) {
2962
+ requestController.abort(reason);
2963
+ cleanupStream();
2964
+ if (source.destroy) {
2965
+ source.destroy();
2966
+ } else {
2967
+ await iterator.return?.();
2968
+ }
2969
+ },
2970
+ async pull(controller) {
2971
+ try {
2972
+ throwIfAborted(requestController.signal);
2973
+ const chunk = await iterator.next();
2974
+ throwIfAborted(requestController.signal);
2975
+ if (chunk.done) {
2976
+ cleanupStream();
2977
+ controller.close();
2978
+ } else if (typeof chunk.value === "string") {
2979
+ controller.enqueue(encoder.encode(chunk.value));
2980
+ } else if (chunk.value instanceof Uint8Array) {
2981
+ controller.enqueue(chunk.value);
2982
+ } else {
2983
+ throw new TypeError("SAP Responses returned a non-byte response chunk.");
2984
+ }
2985
+ } catch (error) {
2986
+ const failure = requestController.signal.aborted ? createAbortError(requestController.signal.reason) : error;
2987
+ requestController.abort(error);
2988
+ cleanupStream();
2989
+ source.destroy?.();
2990
+ controller.error(
2991
+ convertToAISDKError(failure, {
2992
+ modelId: config.modelId,
2993
+ modelType: "languageModel",
2994
+ operation,
2995
+ requestBody: createAISDKRequestBodySummary(options),
2996
+ url: "sap-ai:responses"
2997
+ })
2998
+ );
2999
+ }
3000
+ }
3001
+ },
3002
+ { highWaterMark: 0 }
3003
+ );
3004
+ }
3005
+ var import_provider8, import_internal, import_core, import_internal2;
3006
+ var init_responses_http_transport = __esm({
3007
+ "src/responses-http-transport.ts"() {
3008
+ "use strict";
3009
+ import_provider8 = require("@ai-sdk/provider");
3010
+ import_internal = require("@sap-ai-sdk/ai-api/internal.js");
3011
+ import_core = require("@sap-ai-sdk/core");
3012
+ import_internal2 = require("@sap-ai-sdk/core/internal.js");
3013
+ init_abort_utils();
3014
+ init_sap_ai_error();
3015
+ init_sap_http_stream();
3016
+ init_strategy_utils();
2017
3017
  }
2018
3018
  });
2019
3019
 
2020
- // src/orchestration-embedding-model-strategy.ts
2021
- var orchestration_embedding_model_strategy_exports = {};
2022
- __export(orchestration_embedding_model_strategy_exports, {
2023
- OrchestrationEmbeddingModelStrategy: () => OrchestrationEmbeddingModelStrategy
3020
+ // src/responses-language-model-strategy.ts
3021
+ var responses_language_model_strategy_exports = {};
3022
+ __export(responses_language_model_strategy_exports, {
3023
+ ResponsesLanguageModelStrategy: () => ResponsesLanguageModelStrategy
2024
3024
  });
2025
- var OrchestrationEmbeddingModelStrategy;
2026
- var init_orchestration_embedding_model_strategy = __esm({
2027
- "src/orchestration-embedding-model-strategy.ts"() {
2028
- "use strict";
2029
- init_base_embedding_model_strategy();
2030
- init_sap_ai_validation();
2031
- init_strategy_utils();
2032
- OrchestrationEmbeddingModelStrategy = class extends BaseEmbeddingModelStrategy {
2033
- ClientClass;
2034
- constructor(ClientClass) {
2035
- super();
2036
- this.ClientClass = ClientClass;
2037
- }
2038
- createClient(config, settings, embeddingOptions) {
2039
- const mergedParams = this.mergeModelParams(settings, embeddingOptions);
2040
- const embeddingConfig = {
2041
- model: {
2042
- name: config.modelId,
2043
- ...hasKeys(mergedParams) ? { params: mergedParams } : {},
2044
- ...settings.modelVersion ? { version: settings.modelVersion } : {}
2045
- }
3025
+ function convertError(error, config, options, operation) {
3026
+ if (import_provider9.APICallError.isInstance(error) && error.message === "Failed to process successful response" && error.statusCode !== void 0 && error.statusCode >= 200 && error.statusCode < 300 && import_provider9.APICallError.isInstance(error.cause)) {
3027
+ return error.cause;
3028
+ }
3029
+ if (operation === "doStream" && !import_provider9.APICallError.isInstance(error)) {
3030
+ const parsed = OPENAI_STREAM_ERROR_SCHEMA.safeParse(error);
3031
+ if (parsed.success) {
3032
+ return new import_provider9.APICallError({
3033
+ cause: error,
3034
+ data: parsed.data.data,
3035
+ isRetryable: parsed.data.isRetryable,
3036
+ message: parsed.data.message,
3037
+ requestBodyValues: createAISDKRequestBodySummary(options),
3038
+ statusCode: parsed.data.statusCode,
3039
+ url: "sap-ai:responses"
3040
+ });
3041
+ }
3042
+ }
3043
+ return convertToAISDKError(error, {
3044
+ modelId: config.modelId,
3045
+ modelType: "languageModel",
3046
+ operation,
3047
+ requestBody: createAISDKRequestBodySummary(options),
3048
+ url: "sap-ai:responses"
3049
+ });
3050
+ }
3051
+ function fromOpenAI(metadata, providerName) {
3052
+ if (providerName === "openai" || !metadata?.openai) return metadata;
3053
+ const { openai, ...rest } = metadata;
3054
+ return { ...rest, [providerName]: { ...rest[providerName], ...openai } };
3055
+ }
3056
+ function fromOpenAICitations(citations, providerName) {
3057
+ if (providerName === "openai" || !citations) return citations;
3058
+ let mapped;
3059
+ let index = 0;
3060
+ for (const citation of citations) {
3061
+ const providerMetadata = fromOpenAI(citation.source.providerMetadata, providerName);
3062
+ if (providerMetadata !== citation.source.providerMetadata) {
3063
+ mapped ??= citations.slice();
3064
+ mapped[index] = {
3065
+ ...citation,
3066
+ source: { ...citation.source, providerMetadata }
3067
+ };
3068
+ }
3069
+ index++;
3070
+ }
3071
+ return mapped ?? citations;
3072
+ }
3073
+ function fromOpenAIContent(part, providerName) {
3074
+ const providerMetadata = fromOpenAI(part.providerMetadata, providerName);
3075
+ const citations = fromOpenAICitations(part.citations, providerName);
3076
+ if (providerMetadata === part.providerMetadata && citations === part.citations) return part;
3077
+ if (providerMetadata === part.providerMetadata) return { ...part, citations };
3078
+ return citations === part.citations ? { ...part, providerMetadata } : { ...part, citations, providerMetadata };
3079
+ }
3080
+ function modelResponseFormat(settings) {
3081
+ const format = settings.responseFormat;
3082
+ if (!format || format.type === "text") return format;
3083
+ if (format.type === "json_object") return { type: "json" };
3084
+ const schema = format.json_schema;
3085
+ return {
3086
+ description: schema.description,
3087
+ name: schema.name,
3088
+ schema: schema.schema === void 0 ? void 0 : import_zod3.z.record(import_zod3.z.string(), import_zod3.z.json()).parse(schema.schema),
3089
+ type: "json"
3090
+ };
3091
+ }
3092
+ async function prepareModel(config, settings, options) {
3093
+ if (options.abortSignal?.aborted) {
3094
+ throw createAbortError(options.abortSignal.reason);
3095
+ }
3096
+ const providerName = getProviderName(config.provider);
3097
+ const sapOptions = config.parsedProviderOptions;
3098
+ const parameters = { ...settings.modelParams, ...sapOptions?.modelParams };
3099
+ const warnings = Object.keys(parameters).filter((key) => !MODEL_PARAMETERS.has(key)).map((key) => ({
3100
+ details: "Use the responses option for Responses-specific parameters.",
3101
+ feature: `modelParams.${key}`,
3102
+ type: "unsupported"
3103
+ }));
3104
+ if (sapOptions?.includeReasoning ?? settings.includeReasoning) {
3105
+ warnings.push({
3106
+ details: "Responses preserves native reasoning history instead of converting it to text.",
3107
+ feature: "includeReasoning",
3108
+ type: "unsupported"
3109
+ });
3110
+ }
3111
+ const responseOptions = {
3112
+ ...parameters.parallel_tool_calls !== void 0 ? { parallelToolCalls: parameters.parallel_tool_calls } : {},
3113
+ ...settings.responseFormat?.type === "json_schema" ? { strictJsonSchema: settings.responseFormat.json_schema.strict } : {},
3114
+ store: false,
3115
+ ...settings.responses,
3116
+ ...sapOptions?.responses
3117
+ };
3118
+ const reasoning = "reasoning" in options ? options.reasoning : void 0;
3119
+ if (typeof reasoning === "string" && reasoning !== "provider-default") {
3120
+ responseOptions.reasoningEffort = reasoning;
3121
+ }
3122
+ const input = {
3123
+ ...options,
3124
+ frequencyPenalty: options.frequencyPenalty ?? parameters.frequencyPenalty,
3125
+ maxOutputTokens: options.maxOutputTokens ?? parameters.maxTokens,
3126
+ presencePenalty: options.presencePenalty ?? parameters.presencePenalty,
3127
+ prompt: toOpenAIPrompt(options.prompt, providerName),
3128
+ providerOptions: {
3129
+ ...options.providerOptions,
3130
+ openai: responseOptions
3131
+ },
3132
+ responseFormat: options.responseFormat ?? modelResponseFormat(settings),
3133
+ temperature: options.temperature ?? parameters.temperature,
3134
+ tools: options.tools?.map(
3135
+ (tool) => tool.type === "function" ? {
3136
+ ...tool,
3137
+ providerOptions: toOpenAI(tool.providerOptions, providerName),
3138
+ strict: tool.strict ?? false
3139
+ } : tool
3140
+ ),
3141
+ topP: options.topP ?? parameters.topP
3142
+ };
3143
+ const convertedInput = convertResponsesCallToV4(input);
3144
+ const transport = await createResponsesTransport(config, settings, options);
3145
+ const model = (0, import_openai.createOpenAI)({
3146
+ // Authentication is supplied by SAP's transport, not an OpenAI API key.
3147
+ apiKey: "sap-ai-core",
3148
+ baseURL: transport.baseURL,
3149
+ fetch: transport.fetch
3150
+ }).responses(config.modelId);
3151
+ return { dispose: transport.dispose, input: convertedInput, model, providerName, warnings };
3152
+ }
3153
+ function responseMetadata(metadata, providerName) {
3154
+ const mapped = fromOpenAI(metadata, providerName);
3155
+ return {
3156
+ ...mapped,
3157
+ [providerName]: { ...mapped?.[providerName], api: "responses", version: VERSION }
3158
+ };
3159
+ }
3160
+ function toOpenAI(options, providerName) {
3161
+ if (providerName === "openai" || !options?.[providerName]) return options;
3162
+ return { ...options, openai: { ...options.openai, ...options[providerName] } };
3163
+ }
3164
+ function toOpenAIOutput(output, providerName) {
3165
+ const mappedOutput = {
3166
+ ...output,
3167
+ providerOptions: toOpenAI(output.providerOptions, providerName)
3168
+ };
3169
+ if (mappedOutput.type !== "content") return mappedOutput;
3170
+ return {
3171
+ ...mappedOutput,
3172
+ value: mappedOutput.value.map((part) => ({
3173
+ ...part,
3174
+ ...(part.type === "file-id" || part.type === "image-file-id") && typeof part.fileId !== "string" && part.fileId[providerName] ? { fileId: { ...part.fileId, openai: part.fileId[providerName] } } : {},
3175
+ ..."providerOptions" in part ? { providerOptions: toOpenAI(part.providerOptions, providerName) } : {}
3176
+ }))
3177
+ };
3178
+ }
3179
+ function toOpenAIPart(part, providerName) {
3180
+ return {
3181
+ ...part,
3182
+ ...part.type === "tool-result" ? { output: toOpenAIOutput(part.output, providerName) } : {},
3183
+ providerOptions: toOpenAI(part.providerOptions, providerName)
3184
+ };
3185
+ }
3186
+ function toOpenAIPrompt(prompt, providerName) {
3187
+ return prompt.map((message) => {
3188
+ const providerOptions = toOpenAI(message.providerOptions, providerName);
3189
+ switch (message.role) {
3190
+ case "assistant":
3191
+ return {
3192
+ ...message,
3193
+ content: message.content.map((part) => toOpenAIPart(part, providerName)),
3194
+ providerOptions
2046
3195
  };
2047
- const moduleConfig = {
2048
- embeddings: embeddingConfig,
2049
- ...settings.masking && hasKeys(settings.masking) ? { masking: settings.masking } : {}
3196
+ case "system":
3197
+ return { ...message, providerOptions };
3198
+ case "tool":
3199
+ return {
3200
+ ...message,
3201
+ content: message.content.map((part) => toOpenAIPart(part, providerName)),
3202
+ providerOptions
2050
3203
  };
2051
- return new this.ClientClass(moduleConfig, config.deploymentConfig, config.destination);
2052
- }
2053
- async executeCall(client, values, embeddingType, requestConfig) {
2054
- return client.embed({ input: values, type: embeddingType }, requestConfig);
2055
- }
2056
- extractEmbeddings(response) {
2057
- const embeddingData = response.getEmbeddings();
2058
- const sortedEmbeddings = [...embeddingData].sort((a, b) => a.index - b.index);
2059
- return sortedEmbeddings.map((data) => normalizeEmbedding(data.embedding));
2060
- }
2061
- extractResponseMetadata(response) {
2062
- return extractResponseMetadata(response, "response");
2063
- }
2064
- extractTokenCount(response) {
2065
- const tokenUsage = response.getTokenUsage();
2066
- return tokenUsage.total_tokens;
2067
- }
2068
- getUrl() {
2069
- return "sap-ai:orchestration/embeddings";
3204
+ case "user":
3205
+ return {
3206
+ ...message,
3207
+ content: message.content.map((part) => toOpenAIPart(part, providerName)),
3208
+ providerOptions
3209
+ };
3210
+ }
3211
+ });
3212
+ }
3213
+ var import_openai, import_provider9, import_zod3, MODEL_PARAMETERS, OPENAI_STREAM_ERROR_SCHEMA, ResponsesLanguageModelStrategy;
3214
+ var init_responses_language_model_strategy = __esm({
3215
+ "src/responses-language-model-strategy.ts"() {
3216
+ "use strict";
3217
+ import_openai = require("@ai-sdk/openai");
3218
+ import_provider9 = require("@ai-sdk/provider");
3219
+ import_zod3 = require("zod");
3220
+ init_abort_utils();
3221
+ init_responses_adapters_v3_to_v4();
3222
+ init_responses_adapters_v4_to_v3();
3223
+ init_responses_http_transport();
3224
+ init_sap_ai_error();
3225
+ init_sap_ai_provider_options();
3226
+ init_strategy_utils();
3227
+ init_version();
3228
+ MODEL_PARAMETERS = /* @__PURE__ */ new Set([
3229
+ "frequencyPenalty",
3230
+ "maxTokens",
3231
+ "parallel_tool_calls",
3232
+ "presencePenalty",
3233
+ "temperature",
3234
+ "topP"
3235
+ ]);
3236
+ OPENAI_STREAM_ERROR_SCHEMA = import_zod3.z.object({
3237
+ data: import_zod3.z.object({ type: import_zod3.z.enum(["error", "response.failed"]) }).loose(),
3238
+ isRetryable: import_zod3.z.boolean(),
3239
+ message: import_zod3.z.string(),
3240
+ statusCode: import_zod3.z.number().int().min(400).max(599)
3241
+ });
3242
+ ResponsesLanguageModelStrategy = class {
3243
+ async doGenerate(config, settings, options) {
3244
+ let dispose;
3245
+ try {
3246
+ const prepared = await prepareModel(config, settings, options);
3247
+ dispose = prepared.dispose;
3248
+ const { input, model, providerName, warnings } = prepared;
3249
+ const result = convertResponsesResultToV3(await model.doGenerate(input));
3250
+ return {
3251
+ ...result,
3252
+ content: result.content.map((part) => fromOpenAIContent(part, providerName)),
3253
+ providerMetadata: responseMetadata(result.providerMetadata, providerName),
3254
+ warnings: [...warnings, ...result.warnings]
3255
+ };
3256
+ } catch (error) {
3257
+ const failure = convertError(error, config, options, "doGenerate");
3258
+ dispose?.(failure);
3259
+ throw failure;
3260
+ }
2070
3261
  }
2071
- resolveWarnings(settings, warnings) {
2072
- validateMaskingProvidersDeprecation(settings, warnings);
3262
+ async doStream(config, settings, options) {
3263
+ let dispose;
3264
+ try {
3265
+ const prepared = await prepareModel(config, settings, options);
3266
+ dispose = prepared.dispose;
3267
+ const { input, model, providerName, warnings } = prepared;
3268
+ const result = await model.doStream(input);
3269
+ const reader = result.stream.getReader();
3270
+ let cancelled = false;
3271
+ const isCancelled = () => cancelled;
3272
+ return {
3273
+ ...result,
3274
+ stream: new ReadableStream(
3275
+ {
3276
+ async cancel(reason) {
3277
+ cancelled = true;
3278
+ dispose?.(reason);
3279
+ try {
3280
+ await reader.cancel(reason);
3281
+ } finally {
3282
+ reader.releaseLock();
3283
+ }
3284
+ },
3285
+ async pull(controller) {
3286
+ try {
3287
+ if (options.abortSignal?.aborted)
3288
+ throw createAbortError(options.abortSignal.reason);
3289
+ const next = await reader.read();
3290
+ if (isCancelled()) return;
3291
+ if (options.abortSignal?.aborted)
3292
+ throw createAbortError(options.abortSignal.reason);
3293
+ if (next.done) {
3294
+ reader.releaseLock();
3295
+ controller.close();
3296
+ return;
3297
+ }
3298
+ const part = convertResponsesStreamPartToV3(next.value);
3299
+ if (part.type === "stream-start") {
3300
+ controller.enqueue({ ...part, warnings: [...warnings, ...part.warnings] });
3301
+ } else if (part.type === "finish") {
3302
+ controller.enqueue({
3303
+ ...part,
3304
+ providerMetadata: responseMetadata(part.providerMetadata, providerName)
3305
+ });
3306
+ } else if (part.type === "error") {
3307
+ controller.enqueue({
3308
+ ...part,
3309
+ error: convertError(part.error, config, options, "doStream")
3310
+ });
3311
+ } else if ("providerMetadata" in part || part.type === "text-end") {
3312
+ controller.enqueue(fromOpenAIContent(part, providerName));
3313
+ } else {
3314
+ controller.enqueue(part);
3315
+ }
3316
+ } catch (error) {
3317
+ if (isCancelled()) return;
3318
+ const failure = convertError(error, config, options, "doStream");
3319
+ dispose?.(failure);
3320
+ await reader.cancel(error).catch(() => void 0);
3321
+ if (isCancelled()) return;
3322
+ reader.releaseLock();
3323
+ controller.enqueue({
3324
+ error: failure,
3325
+ type: "error"
3326
+ });
3327
+ controller.close();
3328
+ }
3329
+ }
3330
+ },
3331
+ { highWaterMark: 0 }
3332
+ )
3333
+ };
3334
+ } catch (error) {
3335
+ const failure = convertError(error, config, options, "doStream");
3336
+ dispose?.(failure);
3337
+ throw failure;
3338
+ }
2073
3339
  }
2074
3340
  };
2075
3341
  }
2076
3342
  });
2077
3343
 
2078
3344
  // src/stream-transformer.ts
2079
- function createAbortError(reason) {
2080
- const error = new Error("The operation was aborted.", { cause: reason });
2081
- error.name = "AbortError";
2082
- return error;
2083
- }
2084
3345
  function createInitialStreamState() {
2085
3346
  return {
2086
3347
  activeText: false,
@@ -2109,13 +3370,15 @@ function createStreamTransformer(config) {
2109
3370
  cancel,
2110
3371
  convertToAISDKError: convertToAISDKError2,
2111
3372
  extractChunkMetadata,
3373
+ extractProviderSpecificFields,
3374
+ extractReasoningBlocks,
2112
3375
  idGenerator,
2113
3376
  includeRawChunks,
2114
3377
  modelId,
2115
3378
  options,
2116
3379
  providerName,
2117
3380
  requestId,
2118
- responseMetadata,
3381
+ responseMetadata: responseMetadata2,
2119
3382
  sdkStream,
2120
3383
  streamResponseGetCitations,
2121
3384
  streamResponseGetFinishReason,
@@ -2127,10 +3390,51 @@ function createStreamTransformer(config) {
2127
3390
  let textBlockId = null;
2128
3391
  const streamState = createInitialStreamState();
2129
3392
  const toolCallsInProgress = /* @__PURE__ */ new Map();
2130
- const resolvedResponseMetadata = { ...responseMetadata };
3393
+ const resolvedResponseMetadata = { ...responseMetadata2 };
2131
3394
  let resolvedRequestId = requestId;
2132
3395
  let tokenUsage;
2133
3396
  let citations;
3397
+ let providerSpecificFields;
3398
+ let providerFinishReason;
3399
+ let reasoningBlocks;
3400
+ function collectReasoningBlocks(incoming, controller) {
3401
+ if (incoming === void 0) return true;
3402
+ if (!Array.isArray(incoming)) {
3403
+ handleStreamError(
3404
+ new TypeError("Invalid Orchestration reasoning_content: expected an array."),
3405
+ controller,
3406
+ convertToAISDKError2,
3407
+ options,
3408
+ modelId,
3409
+ url
3410
+ );
3411
+ return false;
3412
+ }
3413
+ const blocks = incoming;
3414
+ if (blocks.length === 0) return true;
3415
+ reasoningBlocks ??= [];
3416
+ for (const [index, value] of blocks.entries()) {
3417
+ const parsed = orchestrationReasoningBlockSchema.safeParse(value);
3418
+ if (!parsed.success) {
3419
+ handleStreamError(parsed.error, controller, convertToAISDKError2, options, modelId, url);
3420
+ return false;
3421
+ }
3422
+ const block = parsed.data;
3423
+ let state = reasoningBlocks[index];
3424
+ if (state) {
3425
+ state.block.content = (state.block.content ?? "") + (block.content ?? "");
3426
+ if (block.signature) state.block.signature = block.signature;
3427
+ } else {
3428
+ state = { block, id: idGenerator.generateReasoningBlockId() };
3429
+ reasoningBlocks.push(state);
3430
+ controller.enqueue({ id: state.id, type: "reasoning-start" });
3431
+ }
3432
+ if (block.content) {
3433
+ controller.enqueue({ delta: block.content, id: state.id, type: "reasoning-delta" });
3434
+ }
3435
+ }
3436
+ return true;
3437
+ }
2134
3438
  function collectCitations(incoming) {
2135
3439
  if (!incoming?.length) return;
2136
3440
  citations ??= /* @__PURE__ */ new Map();
@@ -2207,6 +3511,13 @@ function createStreamTransformer(config) {
2207
3511
  );
2208
3512
  return;
2209
3513
  }
3514
+ for (const state of reasoningBlocks ?? []) {
3515
+ controller.enqueue({
3516
+ id: state.id,
3517
+ providerMetadata: buildOrchestrationReasoningMetadata(state.block, providerName),
3518
+ type: "reasoning-end"
3519
+ });
3520
+ }
2210
3521
  const didEmitAnyToolCalls = finalizeToolCalls(
2211
3522
  controller,
2212
3523
  toolCallsInProgress,
@@ -2218,13 +3529,16 @@ function createStreamTransformer(config) {
2218
3529
  }
2219
3530
  const finalFinishReason = streamResponseGetFinishReason();
2220
3531
  if (finalFinishReason) {
2221
- streamState.finishReason = mapFinishReason(finalFinishReason);
3532
+ streamState.finishReason = mapFinishReason(finalFinishReason, providerFinishReason);
2222
3533
  } else if (didEmitAnyToolCalls) {
2223
3534
  streamState.finishReason = {
2224
- raw: void 0,
3535
+ raw: providerFinishReason,
2225
3536
  unified: "tool-calls"
2226
3537
  };
2227
3538
  }
3539
+ if (providerFinishReason !== void 0) {
3540
+ streamState.finishReason = { ...streamState.finishReason, raw: providerFinishReason };
3541
+ }
2228
3542
  streamState.usage = mapTokenUsage(tokenUsage);
2229
3543
  collectCitations(streamResponseGetCitations?.());
2230
3544
  if (citations) {
@@ -2246,6 +3560,7 @@ function createStreamTransformer(config) {
2246
3560
  ...buildAnthropicCacheMetadata(tokenUsage),
2247
3561
  finishReason: streamState.finishReason.raw ?? "unknown",
2248
3562
  finishReasonMapped: streamState.finishReason,
3563
+ ...providerSpecificFields && { providerSpecificFields },
2249
3564
  ...streamIntermediateFailures?.length ? {
2250
3565
  intermediateFailures: sanitizeAsJSONArray(streamIntermediateFailures)
2251
3566
  } : {},
@@ -2285,6 +3600,14 @@ function createStreamTransformer(config) {
2285
3600
  Object.assign(resolvedResponseMetadata, incomingMetadata);
2286
3601
  collectUsage(chunk.getTokenUsage?.());
2287
3602
  collectCitations(chunk.getCitations?.());
3603
+ const incomingProviderFields = parseProviderSpecificFields(
3604
+ extractProviderSpecificFields?.(chunk)
3605
+ );
3606
+ if (incomingProviderFields) {
3607
+ providerSpecificFields = { ...providerSpecificFields, ...incomingProviderFields };
3608
+ providerFinishReason = getProviderFinishReason(incomingProviderFields) ?? providerFinishReason;
3609
+ }
3610
+ if (!collectReasoningBlocks(extractReasoningBlocks?.(chunk), controller)) return;
2288
3611
  if (streamState.isFirstChunk || metadataChanged) {
2289
3612
  streamState.isFirstChunk = false;
2290
3613
  controller.enqueue({
@@ -2314,7 +3637,7 @@ function createStreamTransformer(config) {
2314
3637
  }
2315
3638
  const chunkFinishReason = chunk.getFinishReason();
2316
3639
  if (chunkFinishReason) {
2317
- streamState.finishReason = mapFinishReason(chunkFinishReason);
3640
+ streamState.finishReason = mapFinishReason(chunkFinishReason, providerFinishReason);
2318
3641
  if (streamState.finishReason.unified === "tool-calls") {
2319
3642
  finalizeToolCalls(controller, toolCallsInProgress, idGenerator, emitToolInputStart);
2320
3643
  if (streamState.activeText && textBlockId) {
@@ -2437,8 +3760,16 @@ var StreamIdGenerator;
2437
3760
  var init_stream_transformer = __esm({
2438
3761
  "src/stream-transformer.ts"() {
2439
3762
  "use strict";
3763
+ init_abort_utils();
3764
+ init_sap_ai_provider_options();
2440
3765
  init_strategy_utils();
2441
3766
  StreamIdGenerator = class {
3767
+ /**
3768
+ * @returns A UUID string for identifying a native reasoning block.
3769
+ */
3770
+ generateReasoningBlockId() {
3771
+ return crypto.randomUUID();
3772
+ }
2442
3773
  /**
2443
3774
  * @returns A UUID string for identifying the response.
2444
3775
  */
@@ -2466,6 +3797,7 @@ var BaseLanguageModelStrategy;
2466
3797
  var init_base_language_model_strategy = __esm({
2467
3798
  "src/base-language-model-strategy.ts"() {
2468
3799
  "use strict";
3800
+ init_abort_utils();
2469
3801
  init_convert_to_sap_messages();
2470
3802
  init_sap_ai_error();
2471
3803
  init_sap_ai_provider_options();
@@ -2497,15 +3829,19 @@ var init_base_language_model_strategy = __esm({
2497
3829
  ];
2498
3830
  async doGenerate(config, settings, options) {
2499
3831
  try {
2500
- if (options.abortSignal?.aborted) throw createAbortError(options.abortSignal.reason);
3832
+ throwIfAborted(options.abortSignal);
2501
3833
  const commonParts = this.buildCommonParts(config, settings, options);
2502
3834
  const { request, warnings } = this.buildRequest(config, settings, options, commonParts);
2503
3835
  const client = this.createClient(config, settings, commonParts);
2504
- const response = await this.executeApiCall(
2505
- client,
2506
- request,
2507
- mergeRequestConfig(config.requestConfig, options.abortSignal, options.headers)
3836
+ const response = await waitWithAbort(
3837
+ this.executeApiCall(
3838
+ client,
3839
+ request,
3840
+ mergeRequestConfig(config.requestConfig, options.abortSignal, options.headers)
3841
+ ),
3842
+ options.abortSignal
2508
3843
  );
3844
+ throwIfAborted(options.abortSignal);
2509
3845
  return buildGenerateResult({
2510
3846
  providerName: commonParts.providerName,
2511
3847
  requestBody: request,
@@ -2527,7 +3863,7 @@ var init_base_language_model_strategy = __esm({
2527
3863
  }
2528
3864
  async doStream(config, settings, options) {
2529
3865
  try {
2530
- if (options.abortSignal?.aborted) throw createAbortError(options.abortSignal.reason);
3866
+ throwIfAborted(options.abortSignal);
2531
3867
  const commonParts = this.buildCommonParts(config, settings, options);
2532
3868
  const { request, warnings } = this.buildRequest(config, settings, options, commonParts);
2533
3869
  const client = this.createClient(config, settings, commonParts);
@@ -2536,14 +3872,24 @@ var init_base_language_model_strategy = __esm({
2536
3872
  request,
2537
3873
  options.abortSignal ?? void 0,
2538
3874
  settings,
2539
- mergeRequestConfig(config.requestConfig, void 0, options.headers)
3875
+ mergeRequestConfig(config.requestConfig, void 0, options.headers),
3876
+ commonParts
2540
3877
  );
3878
+ if (options.abortSignal?.aborted) {
3879
+ try {
3880
+ streamResponse.cancel();
3881
+ } finally {
3882
+ throwIfAborted(options.abortSignal);
3883
+ }
3884
+ }
2541
3885
  const idGenerator = new StreamIdGenerator();
2542
3886
  const streamWarnings = this.collectStreamWarnings(settings, commonParts.sapOptions);
2543
3887
  const transformedStream = createStreamTransformer({
2544
3888
  cancel: streamResponse.cancel,
2545
3889
  convertToAISDKError,
2546
3890
  extractChunkMetadata: (chunk) => this.extractMetadata(chunk),
3891
+ extractProviderSpecificFields: streamResponse.extractProviderSpecificFields,
3892
+ extractReasoningBlocks: streamResponse.extractReasoningBlocks,
2547
3893
  idGenerator,
2548
3894
  includeRawChunks: options.includeRawChunks ?? false,
2549
3895
  modelId: config.modelId,
@@ -2603,6 +3949,7 @@ var init_base_language_model_strategy = __esm({
2603
3949
  const messages = convertToSAPMessages(options.prompt, {
2604
3950
  escapeTemplatePlaceholders: this.getEscapeTemplatePlaceholders(sapOptions, settings),
2605
3951
  includeReasoning: this.getIncludeReasoning(sapOptions, settings),
3952
+ nativeReasoningProviderName: this.getNativeReasoningProviderName(providerName),
2606
3953
  parsePartProviderOptions: this.getPartProviderOptionsParser(),
2607
3954
  warnings
2608
3955
  });
@@ -2642,12 +3989,12 @@ var init_base_language_model_strategy = __esm({
2642
3989
  * @internal
2643
3990
  */
2644
3991
  extractMetadata(response) {
2645
- const responseMetadata = extractCompletionMetadata(
3992
+ const responseMetadata2 = extractCompletionMetadata(
2646
3993
  response,
2647
3994
  this.getCompletionDataPath()
2648
3995
  );
2649
3996
  const { headers, requestId } = extractResponseMetadata(response, "rawResponse");
2650
- return { requestId, responseHeaders: headers, responseMetadata };
3997
+ return { requestId, responseHeaders: headers, responseMetadata: responseMetadata2 };
2651
3998
  }
2652
3999
  /**
2653
4000
  * Returns whether to escape template placeholders for this API.
@@ -2667,7 +4014,16 @@ var init_base_language_model_strategy = __esm({
2667
4014
  * @internal
2668
4015
  */
2669
4016
  getIncludeReasoning(sapOptions, settings) {
2670
- return sapOptions?.includeReasoning ?? settings.includeReasoning ?? false;
4017
+ return sapOptions?.includeReasoning ?? ("includeReasoning" in settings ? settings.includeReasoning : false) ?? false;
4018
+ }
4019
+ /**
4020
+ * Enables native reasoning history only for strategies supporting the Orchestration wire format.
4021
+ * @param _providerName - Configured provider namespace.
4022
+ * @returns The native reasoning namespace, or undefined for legacy text-only history.
4023
+ * @internal
4024
+ */
4025
+ getNativeReasoningProviderName(_providerName) {
4026
+ return void 0;
2671
4027
  }
2672
4028
  /**
2673
4029
  * Returns a parser for per-message-part `providerOptions['sap-ai']`.
@@ -2710,6 +4066,7 @@ var init_foundation_models_language_model_strategy = __esm({
2710
4066
  "src/foundation-models-language-model-strategy.ts"() {
2711
4067
  "use strict";
2712
4068
  init_base_language_model_strategy();
4069
+ init_sap_http_stream();
2713
4070
  init_strategy_utils();
2714
4071
  FOUNDATION_MODELS_PARAM_MAPPINGS = [
2715
4072
  ...BaseLanguageModelStrategy.COMMON_PARAM_MAPPINGS,
@@ -2755,7 +4112,7 @@ var init_foundation_models_language_model_strategy = __esm({
2755
4112
  }
2756
4113
  async executeApiCall(client, request, requestConfig) {
2757
4114
  const response = await client.run(request, requestConfig);
2758
- const { requestId, responseMetadata } = this.extractMetadata(response);
4115
+ const { requestId, responseMetadata: responseMetadata2 } = this.extractMetadata(response);
2759
4116
  return {
2760
4117
  getContent: () => response.getContent(),
2761
4118
  getFinishReason: () => response.getFinishReason(),
@@ -2764,21 +4121,28 @@ var init_foundation_models_language_model_strategy = __esm({
2764
4121
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- SAP SDK types headers as any
2765
4122
  rawResponse: { headers: response.rawResponse.headers },
2766
4123
  requestId,
2767
- responseMetadata
4124
+ responseMetadata: responseMetadata2
2768
4125
  };
2769
4126
  }
2770
- async executeStreamCall(client, request, abortSignal, _settings, requestConfig) {
2771
- const streamResponse = await client.stream(request, abortSignal, requestConfig);
2772
- const { requestId, responseHeaders, responseMetadata } = this.extractMetadata(streamResponse);
4127
+ async executeStreamCall(client, request, abortSignal, _settings, requestConfig, _commonParts) {
4128
+ const streamResponse = await executeSapStream(
4129
+ (streamRequestConfig) => client.stream(request, abortSignal, streamRequestConfig),
4130
+ abortSignal,
4131
+ requestConfig
4132
+ );
4133
+ const { requestId, responseHeaders, responseMetadata: responseMetadata2 } = this.extractMetadata(streamResponse);
2773
4134
  return {
2774
4135
  cancel: () => {
2775
- streamResponse.stream.controller.abort();
4136
+ disposeSapStream(streamResponse);
2776
4137
  },
2777
4138
  getFinishReason: () => streamResponse.getFinishReason(),
2778
4139
  requestId,
2779
4140
  responseHeaders,
2780
- responseMetadata,
2781
- stream: streamResponse.stream
4141
+ responseMetadata: responseMetadata2,
4142
+ stream: withSapStreamCleanup(
4143
+ streamResponse,
4144
+ streamResponse.stream
4145
+ )
2782
4146
  };
2783
4147
  }
2784
4148
  getCompletionDataPath() {
@@ -2839,10 +4203,12 @@ var init_orchestration_language_model_strategy = __esm({
2839
4203
  init_deep_merge();
2840
4204
  init_sap_ai_provider_options();
2841
4205
  init_sap_ai_validation();
4206
+ init_sap_http_stream();
2842
4207
  init_strategy_utils();
2843
4208
  ORCHESTRATION_MODULE_KEYS = ["masking", "filtering", "grounding", "translation"];
2844
4209
  CONFIG_REF_IGNORED_MODULES = [
2845
4210
  ...ORCHESTRATION_MODULE_KEYS,
4211
+ "dropUnsupportedParams",
2846
4212
  "fallbackModuleConfigs",
2847
4213
  "promptTemplateRef",
2848
4214
  "responseFormat",
@@ -2850,7 +4216,11 @@ var init_orchestration_language_model_strategy = __esm({
2850
4216
  "modelParams",
2851
4217
  "modelVersion"
2852
4218
  ];
2853
- CONFIG_REF_IGNORED_PROVIDER_OPTIONS = ["promptTemplateRef", "modelParams"];
4219
+ CONFIG_REF_IGNORED_PROVIDER_OPTIONS = [
4220
+ "dropUnsupportedParams",
4221
+ "promptTemplateRef",
4222
+ "modelParams"
4223
+ ];
2854
4224
  ORCHESTRATION_PARAM_MAPPINGS = [
2855
4225
  ...BaseLanguageModelStrategy.COMMON_PARAM_MAPPINGS,
2856
4226
  { camelCaseKey: "topK", optionKey: "topK", outputKey: "top_k" }
@@ -2880,6 +4250,12 @@ var init_orchestration_language_model_strategy = __esm({
2880
4250
  const warnings = [];
2881
4251
  const configRefCandidate = sapOptions?.orchestrationConfigRef ?? settings.orchestrationConfigRef;
2882
4252
  if (configRefCandidate && isOrchestrationConfigRef(configRefCandidate)) {
4253
+ if (settings.streamOptions && hasKeys(settings.streamOptions)) {
4254
+ warnings.push({
4255
+ message: "orchestrationConfigRef is set; local streamOptions are ignored. Configure streaming in the referenced configuration or its overrideConfig.",
4256
+ type: "other"
4257
+ });
4258
+ }
2883
4259
  return warnings;
2884
4260
  }
2885
4261
  if (settings.translation && hasKeys(settings.translation)) {
@@ -2893,11 +4269,12 @@ var init_orchestration_language_model_strategy = __esm({
2893
4269
  return warnings;
2894
4270
  }
2895
4271
  createClient(config, settings, commonParts) {
2896
- const { configRef, promptTemplateRef, responseFormat, tools } = commonParts.resolvedState;
4272
+ const { configRef, dropUnsupportedParams, promptTemplateRef, responseFormat, tools } = commonParts.resolvedState;
2897
4273
  if (configRef) {
2898
4274
  return new this.ClientClass(configRef, config.deploymentConfig, config.destination);
2899
4275
  }
2900
4276
  const clientConfig = this.buildOrchestrationModuleConfig(config, settings, {
4277
+ dropUnsupportedParams,
2901
4278
  modelParams: commonParts.modelParams,
2902
4279
  promptTemplateRef,
2903
4280
  responseFormat,
@@ -2915,40 +4292,47 @@ var init_orchestration_language_model_strategy = __esm({
2915
4292
  }
2916
4293
  async executeApiCall(client, request, requestConfig) {
2917
4294
  const response = await client.chatCompletion(request, requestConfig);
2918
- const { requestId, responseMetadata } = this.extractMetadata(response);
4295
+ const { requestId, responseMetadata: responseMetadata2 } = this.extractMetadata(response);
2919
4296
  return {
2920
4297
  getCitations: () => response.getCitations(),
2921
4298
  getContent: () => response.getContent(),
2922
4299
  getFinishReason: () => response.getFinishReason(),
2923
4300
  getIntermediateFailures: () => response.getIntermediateFailures(),
4301
+ getProviderSpecificFields: () => response.findChoiceByIndex(0)?.provider_specific_fields,
4302
+ getReasoningBlocks: () => response.getAssistantMessage()?.reasoning_content,
2924
4303
  getTokenUsage: () => response.getTokenUsage(),
2925
4304
  getToolCalls: () => response.getToolCalls(),
2926
4305
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- SAP SDK types headers as any
2927
4306
  rawResponse: { headers: response.rawResponse.headers },
2928
4307
  requestId,
2929
- responseMetadata
4308
+ responseMetadata: responseMetadata2
2930
4309
  };
2931
4310
  }
2932
- async executeStreamCall(client, request, abortSignal, settings, requestConfig) {
2933
- const sdkStreamOptions = this.buildSdkStreamOptions(settings.streamOptions);
2934
- const streamResponse = await client.stream(
2935
- request,
4311
+ async executeStreamCall(client, request, abortSignal, settings, requestConfig, commonParts) {
4312
+ const { configRef } = commonParts.resolvedState;
4313
+ const sdkStreamOptions = configRef ? void 0 : this.buildSdkStreamOptions(settings.streamOptions);
4314
+ const streamResponse = await executeSapStream(
4315
+ (streamRequestConfig) => client.stream(request, abortSignal, sdkStreamOptions, streamRequestConfig),
2936
4316
  abortSignal,
2937
- sdkStreamOptions,
2938
4317
  requestConfig
2939
4318
  );
2940
- const { requestId, responseHeaders, responseMetadata } = this.extractMetadata(streamResponse);
4319
+ const { requestId, responseHeaders, responseMetadata: responseMetadata2 } = this.extractMetadata(streamResponse);
2941
4320
  return {
2942
4321
  cancel: () => {
2943
- streamResponse.stream.controller.abort();
4322
+ disposeSapStream(streamResponse);
2944
4323
  },
4324
+ extractProviderSpecificFields: (chunk) => chunk.findChoiceByIndex(0)?.provider_specific_fields,
4325
+ extractReasoningBlocks: (chunk) => chunk.findChoiceByIndex(0)?.delta.reasoning_content,
2945
4326
  getCitations: () => streamResponse.getCitations(),
2946
4327
  getFinishReason: () => streamResponse.getFinishReason(),
2947
4328
  getIntermediateFailures: () => streamResponse.getIntermediateFailures(),
2948
4329
  requestId,
2949
4330
  responseHeaders,
2950
- responseMetadata,
2951
- stream: streamResponse.stream
4331
+ responseMetadata: responseMetadata2,
4332
+ stream: withSapStreamCleanup(
4333
+ streamResponse,
4334
+ streamResponse.stream
4335
+ )
2952
4336
  };
2953
4337
  }
2954
4338
  getCompletionDataPath() {
@@ -2957,6 +4341,9 @@ var init_orchestration_language_model_strategy = __esm({
2957
4341
  getEscapeTemplatePlaceholders(sapOptions, settings) {
2958
4342
  return sapOptions?.escapeTemplatePlaceholders ?? settings.escapeTemplatePlaceholders ?? true;
2959
4343
  }
4344
+ getNativeReasoningProviderName(providerName) {
4345
+ return providerName;
4346
+ }
2960
4347
  getParamMappings() {
2961
4348
  return ORCHESTRATION_PARAM_MAPPINGS;
2962
4349
  }
@@ -2990,7 +4377,8 @@ var init_orchestration_language_model_strategy = __esm({
2990
4377
  if (converted.warning) warnings.push(converted.warning);
2991
4378
  }
2992
4379
  const tools = this.resolveTools(settings, options, warnings);
2993
- return { configRef, promptTemplateRef, responseFormat, tools };
4380
+ const dropUnsupportedParams = sapOptions?.dropUnsupportedParams ?? settings.dropUnsupportedParams;
4381
+ return { configRef, dropUnsupportedParams, promptTemplateRef, responseFormat, tools };
2994
4382
  }
2995
4383
  /**
2996
4384
  * Builds request for orchestrationConfigRef mode.
@@ -3035,6 +4423,7 @@ var init_orchestration_language_model_strategy = __esm({
3035
4423
  * @param config - Strategy configuration.
3036
4424
  * @param settings - Model settings.
3037
4425
  * @param params - Build parameters.
4426
+ * @param params.dropUnsupportedParams - Optional unsupported-parameter policy for the primary model.
3038
4427
  * @param params.modelParams - LLM model parameters.
3039
4428
  * @param params.promptTemplateRef - Optional prompt template reference.
3040
4429
  * @param params.responseFormat - Optional response format specification.
@@ -3044,7 +4433,14 @@ var init_orchestration_language_model_strategy = __esm({
3044
4433
  * @internal
3045
4434
  */
3046
4435
  buildOrchestrationModuleConfig(config, settings, params) {
3047
- const { modelParams, promptTemplateRef, responseFormat, toolChoice, tools } = params;
4436
+ const {
4437
+ dropUnsupportedParams,
4438
+ modelParams,
4439
+ promptTemplateRef,
4440
+ responseFormat,
4441
+ toolChoice,
4442
+ tools
4443
+ } = params;
3048
4444
  const promptConfig = promptTemplateRef ? this.buildTemplateRefPromptConfig(promptTemplateRef, tools, responseFormat) : this.buildInlineTemplateConfig(tools, responseFormat);
3049
4445
  const effectiveModelParams = toolChoice ? { ...modelParams, tool_choice: toolChoice } : modelParams;
3050
4446
  const moduleConfig = {
@@ -3052,7 +4448,8 @@ var init_orchestration_language_model_strategy = __esm({
3052
4448
  model: {
3053
4449
  name: config.modelId,
3054
4450
  params: effectiveModelParams,
3055
- ...settings.modelVersion ? { version: settings.modelVersion } : {}
4451
+ ...settings.modelVersion ? { version: settings.modelVersion } : {},
4452
+ ...dropUnsupportedParams !== void 0 ? { drop_unsupported_params: dropUnsupportedParams } : {}
3056
4453
  },
3057
4454
  prompt: promptConfig
3058
4455
  }
@@ -3141,7 +4538,7 @@ var init_orchestration_language_model_strategy = __esm({
3141
4538
  }
3142
4539
  }
3143
4540
  for (const key of CONFIG_REF_IGNORED_PROVIDER_OPTIONS) {
3144
- if (sapOptions?.[key] && !settings[key]) {
4541
+ if (sapOptions?.[key] !== void 0 && settings[key] === void 0) {
3145
4542
  ignoredSettings.push(`providerOptions.${key}`);
3146
4543
  }
3147
4544
  }
@@ -3282,6 +4679,52 @@ __export(index_v2_exports, {
3282
4679
  module.exports = __toCommonJS(index_v2_exports);
3283
4680
  init_convert_to_sap_messages();
3284
4681
 
4682
+ // src/sap-ai-adapters-v3-to-v2.ts
4683
+ var import_provider2 = require("@ai-sdk/provider");
4684
+
4685
+ // src/map-readable-stream.ts
4686
+ function mapReadableStream(source, convert) {
4687
+ const reader = source.getReader();
4688
+ let cancelled = false;
4689
+ return new ReadableStream(
4690
+ {
4691
+ async cancel(reason) {
4692
+ cancelled = true;
4693
+ try {
4694
+ await reader.cancel(reason);
4695
+ } finally {
4696
+ reader.releaseLock();
4697
+ }
4698
+ },
4699
+ async pull(controller) {
4700
+ try {
4701
+ for (; ; ) {
4702
+ const next = await reader.read();
4703
+ if (cancelled) return;
4704
+ if (next.done) {
4705
+ reader.releaseLock();
4706
+ controller.close();
4707
+ return;
4708
+ }
4709
+ const converted = convert(next.value);
4710
+ if (converted !== null) {
4711
+ controller.enqueue(converted);
4712
+ return;
4713
+ }
4714
+ }
4715
+ } catch (error) {
4716
+ if (cancelled) return;
4717
+ await reader.cancel(error).catch(() => void 0);
4718
+ if (cancelled) return;
4719
+ reader.releaseLock();
4720
+ controller.error(error);
4721
+ }
4722
+ }
4723
+ },
4724
+ { highWaterMark: 0 }
4725
+ );
4726
+ }
4727
+
3285
4728
  // src/sap-ai-adapters-v3-to-v2.ts
3286
4729
  function convertStreamPartToV2(internalPart) {
3287
4730
  const compatiblePart = internalPart;
@@ -3299,7 +4742,7 @@ function convertStreamPartToV2(internalPart) {
3299
4742
  case "stream-start":
3300
4743
  return { ...compatiblePart, warnings: convertWarningsToV2(compatiblePart.warnings) };
3301
4744
  case "tool-approval-request":
3302
- return null;
4745
+ throw createV2ToolApprovalError();
3303
4746
  case "tool-call": {
3304
4747
  const { dynamic: _dynamic, ...part } = compatiblePart;
3305
4748
  return part;
@@ -3337,19 +4780,17 @@ function convertWarningToV2(internalWarning) {
3337
4780
  };
3338
4781
  }
3339
4782
  function createV2StreamFromInternal(internalStream) {
3340
- return internalStream.pipeThrough(
3341
- new TransformStream({
3342
- transform(chunk, controller) {
3343
- const converted = convertStreamPartToV2(chunk);
3344
- if (converted !== null) controller.enqueue(converted);
3345
- }
3346
- })
3347
- );
4783
+ return mapReadableStream(internalStream, convertStreamPartToV2);
4784
+ }
4785
+ function createV2ToolApprovalError() {
4786
+ return new import_provider2.UnsupportedFunctionalityError({
4787
+ functionality: "Tool approvals are unavailable through the V2 provider. Use /v3 with AI SDK 6 or /v4 with AI SDK 7."
4788
+ });
3348
4789
  }
3349
4790
 
3350
4791
  // src/sap-ai-embedding-model.ts
3351
- var import_provider_utils2 = require("@ai-sdk/provider-utils");
3352
- var import_zod3 = require("zod");
4792
+ var import_provider_utils3 = require("@ai-sdk/provider-utils");
4793
+ var import_zod4 = require("zod");
3353
4794
  init_sap_ai_provider_options();
3354
4795
 
3355
4796
  // src/sap-ai-strategy.ts
@@ -3380,6 +4821,10 @@ function getOrCreateLanguageModelStrategy(api) {
3380
4821
  return strategyPromise;
3381
4822
  }
3382
4823
  async function createEmbeddingModelStrategy(api) {
4824
+ if (api === "responses") {
4825
+ const { UnsupportedFeatureError: UnsupportedFeatureError2 } = await Promise.resolve().then(() => (init_sap_ai_error(), sap_ai_error_exports));
4826
+ throw new UnsupportedFeatureError2("Embeddings", "responses", "foundation-models");
4827
+ }
3383
4828
  if (api === "foundation-models") {
3384
4829
  const { AzureOpenAiEmbeddingClient } = await import("@sap-ai-sdk/foundation-models");
3385
4830
  const { FoundationModelsEmbeddingModelStrategy: FoundationModelsEmbeddingModelStrategy2 } = await Promise.resolve().then(() => (init_foundation_models_embedding_model_strategy(), foundation_models_embedding_model_strategy_exports));
@@ -3390,6 +4835,10 @@ async function createEmbeddingModelStrategy(api) {
3390
4835
  return new OrchestrationEmbeddingModelStrategy2(OrchestrationEmbeddingClient2);
3391
4836
  }
3392
4837
  async function createLanguageModelStrategy(api) {
4838
+ if (api === "responses") {
4839
+ const { ResponsesLanguageModelStrategy: ResponsesLanguageModelStrategy2 } = await Promise.resolve().then(() => (init_responses_language_model_strategy(), responses_language_model_strategy_exports));
4840
+ return new ResponsesLanguageModelStrategy2();
4841
+ }
3393
4842
  if (api === "foundation-models") {
3394
4843
  const { AzureOpenAiChatClient } = await import("@sap-ai-sdk/foundation-models");
3395
4844
  const { FoundationModelsLanguageModelStrategy: FoundationModelsLanguageModelStrategy2 } = await Promise.resolve().then(() => (init_foundation_models_language_model_strategy(), foundation_models_language_model_strategy_exports));
@@ -3403,7 +4852,7 @@ async function createLanguageModelStrategy(api) {
3403
4852
  // src/sap-ai-embedding-model.ts
3404
4853
  init_sap_ai_validation();
3405
4854
  var DEFAULT_MAX_EMBEDDINGS_PER_CALL = 2048;
3406
- var maxEmbeddingsPerCallSchema = import_zod3.z.number().int().positive().or(import_zod3.z.literal(Infinity));
4855
+ var maxEmbeddingsPerCallSchema = import_zod4.z.number().int().positive().or(import_zod4.z.literal(Infinity));
3407
4856
  var SAPAIEmbeddingModel = class {
3408
4857
  maxEmbeddingsPerCall;
3409
4858
  modelId;
@@ -3432,7 +4881,7 @@ var SAPAIEmbeddingModel = class {
3432
4881
  }
3433
4882
  async doEmbed(options) {
3434
4883
  const providerName = getProviderName(this.config.provider);
3435
- const sapOptions = await (0, import_provider_utils2.parseProviderOptions)({
4884
+ const sapOptions = await (0, import_provider_utils3.parseProviderOptions)({
3436
4885
  provider: providerName,
3437
4886
  providerOptions: options.providerOptions,
3438
4887
  schema: sapAIEmbeddingProviderOptions
@@ -3453,7 +4902,12 @@ var SAPAIEmbeddingModel = class {
3453
4902
  provider: this.config.provider,
3454
4903
  requestConfig: this.config.requestConfig
3455
4904
  };
3456
- return strategy.doEmbed(strategyConfig, this.settings, options, this.maxEmbeddingsPerCall);
4905
+ return strategy.doEmbed(
4906
+ strategyConfig,
4907
+ this.settings,
4908
+ options,
4909
+ this.maxEmbeddingsPerCall
4910
+ );
3457
4911
  }
3458
4912
  };
3459
4913
 
@@ -3508,8 +4962,57 @@ var SAPAIEmbeddingModelV2 = class {
3508
4962
  // src/index-v2.ts
3509
4963
  init_sap_ai_error();
3510
4964
 
4965
+ // src/sap-ai-adapters-v2-to-v3.ts
4966
+ var import_provider_utils4 = require("@ai-sdk/provider-utils");
4967
+ function normalizeV2PromptToV3(prompt) {
4968
+ return prompt.map((message) => {
4969
+ switch (message.role) {
4970
+ case "assistant":
4971
+ return {
4972
+ ...message,
4973
+ content: message.content.map(
4974
+ (part) => part.type === "tool-result" ? normalizeToolResultPart(part) : part
4975
+ )
4976
+ };
4977
+ case "tool":
4978
+ return {
4979
+ ...message,
4980
+ content: message.content.map(
4981
+ (part) => part.type === "tool-result" ? normalizeToolResultPart(part) : part
4982
+ )
4983
+ };
4984
+ default:
4985
+ return message;
4986
+ }
4987
+ });
4988
+ }
4989
+ function normalizeToolOutput(output) {
4990
+ if (output.type !== "content") return output;
4991
+ return {
4992
+ ...output,
4993
+ value: output.value.map((item) => {
4994
+ if (item.type !== "media") return item;
4995
+ const mediaType = (0, import_provider_utils4.resolveFullMediaType)({
4996
+ part: {
4997
+ data: { data: item.data, type: "data" },
4998
+ mediaType: item.mediaType.toLowerCase(),
4999
+ type: "file"
5000
+ }
5001
+ });
5002
+ return {
5003
+ ...item,
5004
+ mediaType,
5005
+ type: mediaType.startsWith("image/") ? "image-data" : "file-data"
5006
+ };
5007
+ })
5008
+ };
5009
+ }
5010
+ function normalizeToolResultPart(part) {
5011
+ return { ...part, output: normalizeToolOutput(part.output) };
5012
+ }
5013
+
3511
5014
  // src/sap-ai-language-model.ts
3512
- var import_provider_utils3 = require("@ai-sdk/provider-utils");
5015
+ var import_provider_utils5 = require("@ai-sdk/provider-utils");
3513
5016
  init_sap_ai_provider_options();
3514
5017
  init_sap_ai_validation();
3515
5018
  var SAPAILanguageModel = class {
@@ -3543,11 +5046,13 @@ var SAPAILanguageModel = class {
3543
5046
  }
3544
5047
  async doGenerate(options) {
3545
5048
  const { strategy, strategyConfig } = await this.prepareInvocation(options);
3546
- return strategy.doGenerate(strategyConfig, this.settings, options);
5049
+ const result = strategy.doGenerate(strategyConfig, this.settings, options);
5050
+ return result;
3547
5051
  }
3548
5052
  async doStream(options) {
3549
5053
  const { strategy, strategyConfig } = await this.prepareInvocation(options);
3550
- return strategy.doStream(strategyConfig, this.settings, options);
5054
+ const result = strategy.doStream(strategyConfig, this.settings, options);
5055
+ return result;
3551
5056
  }
3552
5057
  supportsUrl(url) {
3553
5058
  if (url.protocol === "https:") return true;
@@ -3564,7 +5069,7 @@ var SAPAILanguageModel = class {
3564
5069
  */
3565
5070
  async prepareInvocation(options) {
3566
5071
  const providerName = getProviderName(this.config.provider);
3567
- const sapOptions = await (0, import_provider_utils3.parseProviderOptions)({
5072
+ const sapOptions = await (0, import_provider_utils5.parseProviderOptions)({
3568
5073
  provider: providerName,
3569
5074
  providerOptions: options.providerOptions,
3570
5075
  schema: sapAILanguageModelProviderOptions
@@ -3574,10 +5079,12 @@ var SAPAILanguageModel = class {
3574
5079
  api: effectiveApi,
3575
5080
  invocationSettings: sapOptions ? {
3576
5081
  api: sapOptions.api,
5082
+ dropUnsupportedParams: sapOptions.dropUnsupportedParams,
3577
5083
  escapeTemplatePlaceholders: sapOptions.escapeTemplatePlaceholders,
3578
5084
  orchestrationConfigRef: sapOptions.orchestrationConfigRef,
3579
5085
  placeholderValues: sapOptions.placeholderValues,
3580
- promptTemplateRef: sapOptions.promptTemplateRef
5086
+ promptTemplateRef: sapOptions.promptTemplateRef,
5087
+ responses: sapOptions.responses
3581
5088
  } : void 0,
3582
5089
  modelApi: this.settings.api,
3583
5090
  modelSettings: this.settings
@@ -3618,7 +5125,10 @@ var SAPAILanguageModelV2 = class {
3618
5125
  this.internalModel = new SAPAILanguageModel(modelId, settings, config);
3619
5126
  }
3620
5127
  async doGenerate(options) {
3621
- const result = await this.internalModel.doGenerate(options);
5128
+ const result = await this.internalModel.doGenerate(normalizeCallOptions(options));
5129
+ if (result.content.some((part) => part.type === "tool-approval-request")) {
5130
+ throw createV2ToolApprovalError();
5131
+ }
3622
5132
  return {
3623
5133
  content: result.content,
3624
5134
  finishReason: result.finishReason.unified,
@@ -3630,7 +5140,7 @@ var SAPAILanguageModelV2 = class {
3630
5140
  };
3631
5141
  }
3632
5142
  async doStream(options) {
3633
- const result = await this.internalModel.doStream(options);
5143
+ const result = await this.internalModel.doStream(normalizeCallOptions(options));
3634
5144
  return {
3635
5145
  request: result.request,
3636
5146
  response: result.response ? {
@@ -3640,13 +5150,22 @@ var SAPAILanguageModelV2 = class {
3640
5150
  };
3641
5151
  }
3642
5152
  };
5153
+ function normalizeCallOptions(options) {
5154
+ const normalized = {
5155
+ ...options,
5156
+ prompt: normalizeV2PromptToV3(options.prompt),
5157
+ // Legacy provider-defined tools keep their unsupported warning/skip behavior.
5158
+ tools: options.tools
5159
+ };
5160
+ return normalized;
5161
+ }
3643
5162
 
3644
5163
  // src/index-v2.ts
3645
5164
  init_sap_ai_provider_options();
3646
5165
 
3647
5166
  // src/sap-ai-provider-v2.ts
3648
- var import_provider4 = require("@ai-sdk/provider");
3649
- var import_util2 = require("@sap-cloud-sdk/util");
5167
+ var import_provider10 = require("@ai-sdk/provider");
5168
+ var import_util3 = require("@sap-cloud-sdk/util");
3650
5169
  init_sap_ai_provider_options();
3651
5170
  init_sap_ai_validation();
3652
5171
  function createSAPAIProvider(options = {}) {
@@ -3663,7 +5182,7 @@ function createSAPAIProvider(options = {}) {
3663
5182
  }
3664
5183
  if (typeof process === "undefined" || !process.env.SAP_CLOUD_SDK_LOG_LEVEL) {
3665
5184
  const logLevel = options.logLevel ?? "warn";
3666
- (0, import_util2.setGlobalLogLevel)(logLevel);
5185
+ (0, import_util3.setGlobalLogLevel)(logLevel);
3667
5186
  }
3668
5187
  const deploymentConfig = options.deploymentId ? { deploymentId: options.deploymentId } : { resourceGroup };
3669
5188
  const providerApi = options.api ?? "orchestration";
@@ -3705,7 +5224,7 @@ function createSAPAIProvider(options = {}) {
3705
5224
  provider.languageModel = createModel;
3706
5225
  provider.textEmbeddingModel = createEmbeddingModel;
3707
5226
  provider.imageModel = (modelId) => {
3708
- throw new import_provider4.NoSuchModelError({
5227
+ throw new import_provider10.NoSuchModelError({
3709
5228
  message: `SAP AI Core does not support image generation. Model '${modelId}' is not available.`,
3710
5229
  modelId,
3711
5230
  modelType: "imageModel"