@jerome-benoit/sap-ai-provider-v2 4.2.1 → 4.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -14141,7 +14141,7 @@ var require_cloud_sdk_logger = __commonJS({
14141
14141
  exports2.createLogger = createLogger;
14142
14142
  exports2.getLogger = getLogger;
14143
14143
  exports2.setLogLevel = setLogLevel;
14144
- exports2.setGlobalLogLevel = setGlobalLogLevel;
14144
+ exports2.setGlobalLogLevel = setGlobalLogLevel2;
14145
14145
  exports2.getGlobalLogLevel = getGlobalLogLevel;
14146
14146
  exports2.setGlobalTransports = setGlobalTransports;
14147
14147
  exports2.setLogFormat = setLogFormat;
@@ -14228,7 +14228,7 @@ var require_cloud_sdk_logger = __commonJS({
14228
14228
  messageContextOrLogger.level = level;
14229
14229
  }
14230
14230
  }
14231
- function setGlobalLogLevel(level) {
14231
+ function setGlobalLogLevel2(level) {
14232
14232
  container.options.level = level;
14233
14233
  container.loggers.forEach((logger) => {
14234
14234
  logger.level = level;
@@ -26264,7 +26264,7 @@ var require_axios = __commonJS({
26264
26264
  var isNumber = typeOfTest("number");
26265
26265
  var isObject = (thing) => thing !== null && typeof thing === "object";
26266
26266
  var isBoolean = (thing) => thing === true || thing === false;
26267
- var isPlainObject = (val) => {
26267
+ var isPlainObject2 = (val) => {
26268
26268
  if (kindOf(val) !== "object") {
26269
26269
  return false;
26270
26270
  }
@@ -26346,9 +26346,9 @@ var require_axios = __commonJS({
26346
26346
  const result = {};
26347
26347
  const assignValue = (val, key) => {
26348
26348
  const targetKey = caseless && findKey(result, key) || key;
26349
- if (isPlainObject(result[targetKey]) && isPlainObject(val)) {
26349
+ if (isPlainObject2(result[targetKey]) && isPlainObject2(val)) {
26350
26350
  result[targetKey] = merge(result[targetKey], val);
26351
- } else if (isPlainObject(val)) {
26351
+ } else if (isPlainObject2(val)) {
26352
26352
  result[targetKey] = merge({}, val);
26353
26353
  } else if (isArray(val)) {
26354
26354
  result[targetKey] = val.slice();
@@ -26565,7 +26565,7 @@ var require_axios = __commonJS({
26565
26565
  isNumber,
26566
26566
  isBoolean,
26567
26567
  isObject,
26568
- isPlainObject,
26568
+ isPlainObject: isPlainObject2,
26569
26569
  isEmptyObject,
26570
26570
  isReadableStream,
26571
26571
  isRequest,
@@ -29743,6 +29743,7 @@ __export(index_exports, {
29743
29743
  OrchestrationStreamChunkResponse: () => import_orchestration4.OrchestrationStreamChunkResponse,
29744
29744
  OrchestrationStreamResponse: () => import_orchestration4.OrchestrationStreamResponse,
29745
29745
  SAPAIEmbeddingModel: () => SAPAIEmbeddingModelV2,
29746
+ SAPAILanguageModel: () => SAPAILanguageModelV2,
29746
29747
  SAP_AI_PROVIDER_NAME: () => SAP_AI_PROVIDER_NAME,
29747
29748
  buildAzureContentSafetyFilter: () => import_orchestration3.buildAzureContentSafetyFilter,
29748
29749
  buildDocumentGroundingConfig: () => import_orchestration3.buildDocumentGroundingConfig,
@@ -29751,7 +29752,6 @@ __export(index_exports, {
29751
29752
  buildTranslationConfig: () => import_orchestration3.buildTranslationConfig,
29752
29753
  createSAPAIProvider: () => createSAPAIProvider,
29753
29754
  getProviderName: () => getProviderName,
29754
- isConfigReference: () => import_orchestration3.isConfigReference,
29755
29755
  sapAIEmbeddingProviderOptions: () => sapAIEmbeddingProviderOptions,
29756
29756
  sapAILanguageModelProviderOptions: () => sapAILanguageModelProviderOptions,
29757
29757
  sapai: () => sapai
@@ -29834,6 +29834,67 @@ var import_provider2 = require("@ai-sdk/provider");
29834
29834
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
29835
29835
  var import_orchestration = require("@sap-ai-sdk/orchestration");
29836
29836
 
29837
+ // src/deep-merge.ts
29838
+ var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
29839
+ var MAX_DEPTH = 100;
29840
+ function deepMerge(...sources) {
29841
+ return mergeInternal(sources);
29842
+ }
29843
+ function cloneDeep(obj, seen, depth) {
29844
+ if (depth > MAX_DEPTH) {
29845
+ throw new Error("Maximum merge depth exceeded");
29846
+ }
29847
+ if (seen.has(obj)) {
29848
+ throw new Error("Circular reference detected during deep merge");
29849
+ }
29850
+ seen.add(obj);
29851
+ const result = {};
29852
+ for (const key of Object.keys(obj)) {
29853
+ if (!isSafeKey(key)) continue;
29854
+ const value = obj[key];
29855
+ result[key] = isPlainObject(value) ? cloneDeep(value, seen, depth + 1) : value;
29856
+ }
29857
+ return result;
29858
+ }
29859
+ function isPlainObject(value) {
29860
+ if (value === null || typeof value !== "object") return false;
29861
+ const proto = Object.getPrototypeOf(value);
29862
+ return proto === Object.prototype || proto === null;
29863
+ }
29864
+ function isSafeKey(key) {
29865
+ return !DANGEROUS_KEYS.has(key);
29866
+ }
29867
+ function mergeInternal(sources) {
29868
+ let result = {};
29869
+ for (const source of sources) {
29870
+ if (source == null) continue;
29871
+ result = mergeTwo(result, source, /* @__PURE__ */ new WeakSet(), 0);
29872
+ }
29873
+ return result;
29874
+ }
29875
+ function mergeTwo(target, source, seen, depth) {
29876
+ if (depth > MAX_DEPTH) {
29877
+ throw new Error("Maximum merge depth exceeded");
29878
+ }
29879
+ if (seen.has(source)) {
29880
+ throw new Error("Circular reference detected during deep merge");
29881
+ }
29882
+ seen.add(source);
29883
+ for (const key of Object.keys(source)) {
29884
+ if (!isSafeKey(key)) continue;
29885
+ const sourceValue = source[key];
29886
+ const targetValue = target[key];
29887
+ if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
29888
+ target[key] = mergeTwo({ ...targetValue }, sourceValue, seen, depth + 1);
29889
+ } else if (isPlainObject(sourceValue)) {
29890
+ target[key] = cloneDeep(sourceValue, seen, depth + 1);
29891
+ } else {
29892
+ target[key] = sourceValue;
29893
+ }
29894
+ }
29895
+ return target;
29896
+ }
29897
+
29837
29898
  // src/sap-ai-error.ts
29838
29899
  var import_provider = require("@ai-sdk/provider");
29839
29900
  var import_util = __toESM(require_dist(), 1);
@@ -29942,46 +30003,45 @@ function convertToAISDKError(error, context) {
29942
30003
  });
29943
30004
  }
29944
30005
  }
29945
- const responseHeaders = context?.responseHeaders ?? getAxiosResponseHeaders(error);
29946
30006
  if (rootError instanceof Error) {
29947
30007
  const errorMsg = rootError.message.toLowerCase();
29948
- const originalMsg = rootError.message;
30008
+ const originalErrorMsg = rootError.message;
29949
30009
  if (errorMsg.includes("authentication") || errorMsg.includes("unauthorized") || errorMsg.includes("aicore_service_key") || errorMsg.includes("invalid credentials") || errorMsg.includes("service credentials") || errorMsg.includes("service binding")) {
29950
30010
  return new import_provider.LoadAPIKeyError({
29951
- message: `SAP AI Core authentication failed: ${originalMsg}
30011
+ message: `SAP AI Core authentication failed: ${originalErrorMsg}
29952
30012
 
29953
30013
  Make sure your AICORE_SERVICE_KEY environment variable is set correctly.
29954
30014
  See: https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-service-key`
29955
30015
  });
29956
30016
  }
29957
30017
  if (errorMsg.includes("econnrefused") || errorMsg.includes("enotfound") || errorMsg.includes("network") || errorMsg.includes("timeout")) {
29958
- return new import_provider.APICallError({
29959
- cause: error,
29960
- isRetryable: true,
29961
- message: `Network error connecting to SAP AI Core: ${originalMsg}`,
29962
- requestBodyValues: context?.requestBody,
29963
- responseHeaders,
29964
- statusCode: HTTP_STATUS.SERVICE_UNAVAILABLE,
29965
- url: context?.url ?? ""
29966
- });
30018
+ return createAPICallError(
30019
+ error,
30020
+ {
30021
+ isRetryable: true,
30022
+ message: `Network error connecting to SAP AI Core: ${originalErrorMsg}`,
30023
+ statusCode: HTTP_STATUS.SERVICE_UNAVAILABLE
30024
+ },
30025
+ context
30026
+ );
29967
30027
  }
29968
30028
  if (errorMsg.includes("could not resolve destination")) {
29969
- return new import_provider.APICallError({
29970
- cause: error,
29971
- isRetryable: false,
29972
- message: `SAP AI Core destination error: ${originalMsg}
30029
+ return createAPICallError(
30030
+ error,
30031
+ {
30032
+ isRetryable: false,
30033
+ message: `SAP AI Core destination error: ${originalErrorMsg}
29973
30034
 
29974
30035
  Check your destination configuration or provide a valid destinationName.`,
29975
- requestBodyValues: context?.requestBody,
29976
- responseHeaders,
29977
- statusCode: HTTP_STATUS.BAD_REQUEST,
29978
- url: context?.url ?? ""
29979
- });
30036
+ statusCode: HTTP_STATUS.BAD_REQUEST
30037
+ },
30038
+ context
30039
+ );
29980
30040
  }
29981
30041
  if (errorMsg.includes("failed to resolve deployment") || errorMsg.includes("no deployment matched")) {
29982
- const modelId = extractModelIdentifier(originalMsg);
30042
+ const modelId = extractModelIdentifier(originalErrorMsg);
29983
30043
  return new import_provider.NoSuchModelError({
29984
- message: `SAP AI Core deployment error: ${originalMsg}
30044
+ message: `SAP AI Core deployment error: ${originalErrorMsg}
29985
30045
 
29986
30046
  Make sure you have a running orchestration deployment in your AI Core instance.
29987
30047
  See: https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-deployment-for-orchestration`,
@@ -29990,129 +30050,165 @@ See: https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-depl
29990
30050
  });
29991
30051
  }
29992
30052
  if (errorMsg.includes("filtered by the output filter")) {
29993
- return new import_provider.APICallError({
29994
- cause: error,
29995
- isRetryable: false,
29996
- message: `Content was filtered: ${originalMsg}
30053
+ return createAPICallError(
30054
+ error,
30055
+ {
30056
+ isRetryable: false,
30057
+ message: `Content was filtered: ${originalErrorMsg}
29997
30058
 
29998
30059
  The model's response was blocked by content safety filters. Try a different prompt.`,
29999
- requestBodyValues: context?.requestBody,
30000
- responseHeaders,
30001
- statusCode: HTTP_STATUS.BAD_REQUEST,
30002
- url: context?.url ?? ""
30003
- });
30060
+ statusCode: HTTP_STATUS.BAD_REQUEST
30061
+ },
30062
+ context
30063
+ );
30004
30064
  }
30005
- const statusMatch = /status code (\d+)/i.exec(originalMsg);
30065
+ const statusMatch = /status code (\d+)/i.exec(originalErrorMsg);
30006
30066
  if (statusMatch) {
30007
- const extractedStatus = parseInt(statusMatch[1], 10);
30008
- return new import_provider.APICallError({
30009
- cause: error,
30010
- isRetryable: isRetryable(extractedStatus),
30011
- message: `SAP AI Core request failed: ${originalMsg}`,
30012
- requestBodyValues: context?.requestBody,
30013
- responseHeaders,
30014
- statusCode: extractedStatus,
30015
- url: context?.url ?? ""
30016
- });
30067
+ const extractedStatus = Number.parseInt(statusMatch[1], 10);
30068
+ return createAPICallError(
30069
+ error,
30070
+ {
30071
+ isRetryable: isRetryable(extractedStatus),
30072
+ message: `SAP AI Core request failed: ${originalErrorMsg}`,
30073
+ statusCode: extractedStatus
30074
+ },
30075
+ context
30076
+ );
30017
30077
  }
30018
30078
  if (errorMsg.includes("consumed stream")) {
30019
- return new import_provider.APICallError({
30020
- cause: error,
30021
- isRetryable: false,
30022
- message: `SAP AI Core stream consumption error: ${originalMsg}`,
30023
- requestBodyValues: context?.requestBody,
30024
- responseHeaders,
30025
- statusCode: HTTP_STATUS.INTERNAL_ERROR,
30026
- url: context?.url ?? ""
30027
- });
30079
+ return createAPICallError(
30080
+ error,
30081
+ {
30082
+ isRetryable: false,
30083
+ message: `SAP AI Core stream consumption error: ${originalErrorMsg}`,
30084
+ statusCode: HTTP_STATUS.INTERNAL_ERROR
30085
+ },
30086
+ context
30087
+ );
30028
30088
  }
30029
30089
  if (errorMsg.includes("iterating over") || errorMsg.includes("parse message into json") || errorMsg.includes("received from") || errorMsg.includes("no body") || errorMsg.includes("invalid sse payload")) {
30030
- return new import_provider.APICallError({
30031
- cause: error,
30032
- isRetryable: true,
30033
- message: `SAP AI Core streaming error: ${originalMsg}`,
30034
- requestBodyValues: context?.requestBody,
30035
- responseHeaders,
30036
- statusCode: HTTP_STATUS.INTERNAL_ERROR,
30037
- url: context?.url ?? ""
30038
- });
30090
+ return createAPICallError(
30091
+ error,
30092
+ {
30093
+ isRetryable: true,
30094
+ message: `SAP AI Core streaming error: ${originalErrorMsg}`,
30095
+ statusCode: HTTP_STATUS.INTERNAL_ERROR
30096
+ },
30097
+ context
30098
+ );
30039
30099
  }
30040
30100
  if (errorMsg.includes("prompt template or messages must be defined") || errorMsg.includes("filtering parameters cannot be empty") || errorMsg.includes("templating yaml string must be non-empty") || errorMsg.includes("could not access response data") || errorMsg.includes("could not parse json") || errorMsg.includes("error parsing yaml") || errorMsg.includes("yaml does not conform") || errorMsg.includes("validation errors")) {
30041
- return new import_provider.APICallError({
30042
- cause: error,
30043
- isRetryable: false,
30044
- message: `SAP AI Core configuration error: ${originalMsg}`,
30045
- requestBodyValues: context?.requestBody,
30046
- responseHeaders,
30047
- statusCode: HTTP_STATUS.BAD_REQUEST,
30048
- url: context?.url ?? ""
30049
- });
30101
+ return createAPICallError(
30102
+ error,
30103
+ {
30104
+ isRetryable: false,
30105
+ message: `SAP AI Core configuration error: ${originalErrorMsg}`,
30106
+ statusCode: HTTP_STATUS.BAD_REQUEST
30107
+ },
30108
+ context
30109
+ );
30050
30110
  }
30051
30111
  if (errorMsg.includes("buffer is not available as globals")) {
30052
- return new import_provider.APICallError({
30053
- cause: error,
30054
- isRetryable: false,
30055
- message: `SAP AI Core environment error: ${originalMsg}`,
30056
- requestBodyValues: context?.requestBody,
30057
- responseHeaders,
30058
- statusCode: HTTP_STATUS.INTERNAL_ERROR,
30059
- url: context?.url ?? ""
30060
- });
30112
+ return createAPICallError(
30113
+ error,
30114
+ {
30115
+ isRetryable: false,
30116
+ message: `SAP AI Core environment error: ${originalErrorMsg}`,
30117
+ statusCode: HTTP_STATUS.INTERNAL_ERROR
30118
+ },
30119
+ context
30120
+ );
30061
30121
  }
30062
30122
  if (errorMsg.includes("response stream is undefined")) {
30063
- return new import_provider.APICallError({
30064
- cause: error,
30065
- isRetryable: false,
30066
- message: `SAP AI Core response stream error: ${originalMsg}`,
30067
- requestBodyValues: context?.requestBody,
30068
- responseHeaders,
30069
- statusCode: HTTP_STATUS.INTERNAL_ERROR,
30070
- url: context?.url ?? ""
30071
- });
30123
+ return createAPICallError(
30124
+ error,
30125
+ {
30126
+ isRetryable: false,
30127
+ message: `SAP AI Core response stream error: ${originalErrorMsg}`,
30128
+ statusCode: HTTP_STATUS.INTERNAL_ERROR
30129
+ },
30130
+ context
30131
+ );
30072
30132
  }
30073
30133
  if (errorMsg.includes("response is required to process") || errorMsg.includes("stream is still open") || errorMsg.includes("data is not available yet")) {
30074
- return new import_provider.APICallError({
30075
- cause: error,
30076
- isRetryable: true,
30077
- message: `SAP AI Core response processing error: ${originalMsg}`,
30078
- requestBodyValues: context?.requestBody,
30079
- responseHeaders,
30080
- statusCode: HTTP_STATUS.INTERNAL_ERROR,
30081
- url: context?.url ?? ""
30082
- });
30134
+ return createAPICallError(
30135
+ error,
30136
+ {
30137
+ isRetryable: true,
30138
+ message: `SAP AI Core response processing error: ${originalErrorMsg}`,
30139
+ statusCode: HTTP_STATUS.INTERNAL_ERROR
30140
+ },
30141
+ context
30142
+ );
30083
30143
  }
30084
30144
  if (errorMsg.includes("failed to fetch the list of deployments")) {
30085
- return new import_provider.APICallError({
30086
- cause: error,
30087
- isRetryable: true,
30088
- message: `SAP AI Core deployment retrieval error: ${originalMsg}`,
30089
- requestBodyValues: context?.requestBody,
30090
- responseHeaders,
30091
- statusCode: HTTP_STATUS.SERVICE_UNAVAILABLE,
30092
- url: context?.url ?? ""
30093
- });
30145
+ return createAPICallError(
30146
+ error,
30147
+ {
30148
+ isRetryable: true,
30149
+ message: `SAP AI Core deployment retrieval error: ${originalErrorMsg}`,
30150
+ statusCode: HTTP_STATUS.SERVICE_UNAVAILABLE
30151
+ },
30152
+ context
30153
+ );
30094
30154
  }
30095
30155
  if (errorMsg.includes("received non-uint8array")) {
30096
- return new import_provider.APICallError({
30097
- cause: error,
30098
- isRetryable: false,
30099
- message: `SAP AI Core stream buffer error: ${originalMsg}`,
30100
- requestBodyValues: context?.requestBody,
30101
- responseHeaders,
30102
- statusCode: HTTP_STATUS.INTERNAL_ERROR,
30103
- url: context?.url ?? ""
30104
- });
30156
+ return createAPICallError(
30157
+ error,
30158
+ {
30159
+ isRetryable: false,
30160
+ message: `SAP AI Core stream buffer error: ${originalErrorMsg}`,
30161
+ statusCode: HTTP_STATUS.INTERNAL_ERROR
30162
+ },
30163
+ context
30164
+ );
30105
30165
  }
30106
30166
  }
30107
30167
  const message = rootError instanceof Error ? rootError.message : typeof rootError === "string" ? rootError : "Unknown error occurred";
30108
30168
  const fullMessage = context?.operation ? `SAP AI Core ${context.operation} failed: ${message}` : `SAP AI Core error: ${message}`;
30169
+ return createAPICallError(
30170
+ error,
30171
+ {
30172
+ isRetryable: false,
30173
+ message: fullMessage,
30174
+ statusCode: HTTP_STATUS.INTERNAL_ERROR
30175
+ },
30176
+ context
30177
+ );
30178
+ }
30179
+ function normalizeHeaders(headers) {
30180
+ if (!headers || typeof headers !== "object") return void 0;
30181
+ const record = headers;
30182
+ const entries = Object.entries(record).flatMap(([key, value]) => {
30183
+ if (typeof value === "string") return [[key, value]];
30184
+ if (Array.isArray(value)) {
30185
+ const strings = value.filter((item) => typeof item === "string").join("; ");
30186
+ return strings.length > 0 ? [[key, strings]] : [];
30187
+ }
30188
+ if (typeof value === "number" || typeof value === "boolean") {
30189
+ return [[key, String(value)]];
30190
+ }
30191
+ return [];
30192
+ });
30193
+ if (entries.length === 0) return void 0;
30194
+ return Object.fromEntries(entries);
30195
+ }
30196
+ function createAPICallError(error, options, context) {
30197
+ const responseBody = getAxiosResponseBody(error);
30198
+ const responseHeaders = context?.responseHeaders ?? getAxiosResponseHeaders(error);
30199
+ const enrichMessage = options.enrichMessage ?? true;
30200
+ const message = enrichMessage && responseBody ? `${options.message}
30201
+
30202
+ SAP AI Core Error Response:
30203
+ ${responseBody}` : options.message;
30109
30204
  return new import_provider.APICallError({
30110
30205
  cause: error,
30111
- isRetryable: false,
30112
- message: fullMessage,
30206
+ isRetryable: options.isRetryable,
30207
+ message,
30113
30208
  requestBodyValues: context?.requestBody,
30209
+ responseBody,
30114
30210
  responseHeaders,
30115
- statusCode: HTTP_STATUS.INTERNAL_ERROR,
30211
+ statusCode: options.statusCode,
30116
30212
  url: context?.url ?? ""
30117
30213
  });
30118
30214
  }
@@ -30136,13 +30232,23 @@ function extractModelIdentifier(message, location) {
30136
30232
  }
30137
30233
  return void 0;
30138
30234
  }
30139
- function getAxiosResponseHeaders(error) {
30235
+ function getAxiosError(error) {
30140
30236
  if (!(error instanceof Error)) return void 0;
30141
30237
  const rootCause = (0, import_util.isErrorWithCause)(error) ? error.rootCause : error;
30142
- if (typeof rootCause !== "object") return void 0;
30238
+ if (typeof rootCause !== "object" || rootCause === null) return void 0;
30143
30239
  const maybeAxios = rootCause;
30144
30240
  if (maybeAxios.isAxiosError !== true) return void 0;
30145
- return normalizeHeaders(maybeAxios.response?.headers);
30241
+ return maybeAxios;
30242
+ }
30243
+ function getAxiosResponseBody(error) {
30244
+ const axiosError = getAxiosError(error);
30245
+ if (!axiosError?.response?.data) return void 0;
30246
+ return serializeAxiosResponseData(axiosError.response.data);
30247
+ }
30248
+ function getAxiosResponseHeaders(error) {
30249
+ const axiosError = getAxiosError(error);
30250
+ if (!axiosError) return void 0;
30251
+ return normalizeHeaders(axiosError.response?.headers);
30146
30252
  }
30147
30253
  function getStatusCodeFromSAPError(code) {
30148
30254
  if (!code) return HTTP_STATUS.INTERNAL_ERROR;
@@ -30188,22 +30294,22 @@ function isOrchestrationErrorResponse(error) {
30188
30294
  function isRetryable(statusCode) {
30189
30295
  return statusCode === HTTP_STATUS.REQUEST_TIMEOUT || statusCode === HTTP_STATUS.CONFLICT || statusCode === HTTP_STATUS.RATE_LIMIT || statusCode >= HTTP_STATUS.INTERNAL_ERROR && statusCode < 600;
30190
30296
  }
30191
- function normalizeHeaders(headers) {
30192
- if (!headers || typeof headers !== "object") return void 0;
30193
- const record = headers;
30194
- const entries = Object.entries(record).flatMap(([key, value]) => {
30195
- if (typeof value === "string") return [[key, value]];
30196
- if (Array.isArray(value)) {
30197
- const strings = value.filter((item) => typeof item === "string").join("; ");
30198
- return strings.length > 0 ? [[key, strings]] : [];
30199
- }
30200
- if (typeof value === "number" || typeof value === "boolean") {
30201
- return [[key, String(value)]];
30297
+ function serializeAxiosResponseData(data, maxLength = 2e3) {
30298
+ if (data === void 0) return void 0;
30299
+ let serialized;
30300
+ try {
30301
+ if (typeof data === "string") {
30302
+ serialized = data;
30303
+ } else {
30304
+ serialized = JSON.stringify(data, null, 2);
30202
30305
  }
30203
- return [];
30204
- });
30205
- if (entries.length === 0) return void 0;
30206
- return Object.fromEntries(entries);
30306
+ } catch {
30307
+ serialized = `[Unable to serialize: ${typeof data}]`;
30308
+ }
30309
+ if (serialized.length > maxLength) {
30310
+ return serialized.slice(0, maxLength) + "...[truncated]";
30311
+ }
30312
+ return serialized;
30207
30313
  }
30208
30314
  function tryExtractSAPErrorFromMessage(message) {
30209
30315
  const jsonMatch = /\{[\s\S]*\}/.exec(message);
@@ -30231,62 +30337,27 @@ function getProviderName(providerIdentifier) {
30231
30337
  return dotIndex === -1 ? providerIdentifier : providerIdentifier.slice(0, dotIndex);
30232
30338
  }
30233
30339
  var modelParamsSchema = import_zod.z.object({
30234
- /**
30235
- * Frequency penalty between -2.0 and 2.0.
30236
- * Positive values penalize tokens based on their frequency in the text so far.
30237
- */
30340
+ /** Frequency penalty value (-2.0 to 2.0). */
30238
30341
  frequencyPenalty: import_zod.z.number().min(-2).max(2).optional(),
30239
- /**
30240
- * Maximum number of tokens to generate.
30241
- * Must be a positive integer.
30242
- */
30342
+ /** Maximum number of tokens to generate (must be a positive integer). */
30243
30343
  maxTokens: import_zod.z.number().int().positive().optional(),
30244
- /**
30245
- * Number of completions to generate.
30246
- * Must be a positive integer.
30247
- * Note: Not supported by Amazon and Anthropic models.
30248
- */
30344
+ /** Number of completions to generate (not supported by Amazon/Anthropic models). */
30249
30345
  n: import_zod.z.number().int().positive().optional(),
30250
- /**
30251
- * Whether to enable parallel tool calls.
30252
- * When enabled, the model can call multiple tools in parallel.
30253
- */
30346
+ /** Whether to enable parallel tool calls. */
30254
30347
  parallel_tool_calls: import_zod.z.boolean().optional(),
30255
- /**
30256
- * Presence penalty between -2.0 and 2.0.
30257
- * Positive values penalize tokens that have appeared in the text so far.
30258
- */
30348
+ /** Presence penalty value (-2.0 to 2.0). */
30259
30349
  presencePenalty: import_zod.z.number().min(-2).max(2).optional(),
30260
- /**
30261
- * Sampling temperature between 0 and 2.
30262
- * Higher values make output more random, lower values more deterministic.
30263
- */
30350
+ /** Sampling temperature value (0 to 2). */
30264
30351
  temperature: import_zod.z.number().min(0).max(2).optional(),
30265
- /**
30266
- * Nucleus sampling parameter between 0 and 1.
30267
- * Controls diversity via cumulative probability cutoff.
30268
- */
30352
+ /** Nucleus sampling probability (0 to 1). */
30269
30353
  topP: import_zod.z.number().min(0).max(1).optional()
30270
30354
  }).catchall(import_zod.z.unknown());
30271
30355
  var embeddingModelParamsSchema = import_zod.z.object({
30272
- /**
30273
- * The number of dimensions for output embeddings.
30274
- * Must be a positive integer. Support varies by model.
30275
- * - text-embedding-3-small: supports 512, 1536
30276
- * - text-embedding-3-large: supports 256, 1024, 3072
30277
- */
30356
+ /** Output embedding dimensions (model-dependent, must be a positive integer). */
30278
30357
  dimensions: import_zod.z.number().int().positive().optional(),
30279
- /**
30280
- * Encoding format for embeddings.
30281
- * - 'float': Array of floats (default)
30282
- * - 'base64': Base64-encoded binary
30283
- * - 'binary': Raw binary format
30284
- */
30358
+ /** Encoding format for embeddings: 'float' (default), 'base64', or 'binary'. */
30285
30359
  encoding_format: import_zod.z.enum(["base64", "binary", "float"]).optional(),
30286
- /**
30287
- * Whether to normalize the embedding vectors.
30288
- * When true, vectors are normalized to unit length.
30289
- */
30360
+ /** Whether to normalize embedding vectors to unit length. */
30290
30361
  normalize: import_zod.z.boolean().optional()
30291
30362
  }).catchall(import_zod.z.unknown());
30292
30363
  function validateEmbeddingModelParamsSettings(modelParams) {
@@ -30311,18 +30382,9 @@ function validateModelParamsWithWarnings(params, warnings) {
30311
30382
  var sapAILanguageModelProviderOptions = (0, import_provider_utils.lazySchema)(
30312
30383
  () => (0, import_provider_utils.zodSchema)(
30313
30384
  import_zod.z.object({
30314
- /**
30315
- * Whether to include assistant reasoning parts in the response.
30316
- * Overrides the constructor `includeReasoning` setting for this specific call.
30317
- *
30318
- * Reasoning parts contain internal model chain-of-thought reasoning.
30319
- * Enable for debugging/analysis; disable for production applications.
30320
- */
30385
+ /** Whether to include assistant reasoning parts in the response. */
30321
30386
  includeReasoning: import_zod.z.boolean().optional(),
30322
- /**
30323
- * Model generation parameters for this specific call.
30324
- * These override the corresponding constructor `modelParams` settings.
30325
- */
30387
+ /** Model generation parameters for this specific call. */
30326
30388
  modelParams: modelParamsSchema.optional()
30327
30389
  })
30328
30390
  )
@@ -30330,25 +30392,9 @@ var sapAILanguageModelProviderOptions = (0, import_provider_utils.lazySchema)(
30330
30392
  var sapAIEmbeddingProviderOptions = (0, import_provider_utils.lazySchema)(
30331
30393
  () => (0, import_provider_utils.zodSchema)(
30332
30394
  import_zod.z.object({
30333
- /**
30334
- * Additional model parameters for this call.
30335
- * Passed directly to the embedding API.
30336
- *
30337
- * Known parameters:
30338
- * - `dimensions`: Output embedding dimensions (model-dependent)
30339
- * - `encoding_format`: 'float' | 'base64' | 'binary'
30340
- * - `normalize`: Whether to normalize vectors
30341
- * @see {@link embeddingModelParamsSchema} for validation rules
30342
- */
30395
+ /** Additional model parameters for this call. */
30343
30396
  modelParams: embeddingModelParamsSchema.optional(),
30344
- /**
30345
- * Embedding task type for this specific call.
30346
- * Overrides the constructor `type` setting.
30347
- *
30348
- * - `text`: General-purpose text embeddings (default)
30349
- * - `query`: Optimized for search queries
30350
- * - `document`: Optimized for document content
30351
- */
30397
+ /** Embedding task type: 'text' (default), 'query', or 'document'. */
30352
30398
  type: import_zod.z.enum(["document", "query", "text"]).optional()
30353
30399
  })
30354
30400
  )
@@ -30357,35 +30403,25 @@ var sapAIEmbeddingProviderOptions = (0, import_provider_utils.lazySchema)(
30357
30403
  // src/sap-ai-embedding-model.ts
30358
30404
  var DEFAULT_MAX_EMBEDDINGS_PER_CALL = 2048;
30359
30405
  var SAPAIEmbeddingModel = class {
30360
- /**
30361
- * Maximum number of embeddings that can be generated in a single API call.
30362
- * @default 2048
30363
- */
30406
+ /** Maximum number of embeddings per API call. */
30364
30407
  maxEmbeddingsPerCall;
30365
- /**
30366
- * The model ID.
30367
- */
30408
+ /** The model identifier. */
30368
30409
  modelId;
30369
- /**
30370
- * The provider identifier.
30371
- */
30410
+ /** The provider identifier string. */
30372
30411
  provider;
30373
- /**
30374
- * The embedding model interface version.
30375
- */
30412
+ /** The Vercel AI SDK specification version. */
30376
30413
  specificationVersion = "v3";
30377
- /**
30378
- * Whether the model supports parallel calls.
30379
- * Set to true as SAP AI Core can handle concurrent requests.
30380
- */
30414
+ /** Whether the model supports parallel API calls. */
30381
30415
  supportsParallelCalls = true;
30382
30416
  config;
30383
30417
  settings;
30384
30418
  /**
30385
30419
  * Creates a new SAP AI Embedding Model instance.
30386
- * @param modelId - The embedding model identifier (e.g., 'text-embedding-ada-002')
30387
- * @param settings - Optional model settings
30388
- * @param config - Internal configuration from the provider
30420
+ *
30421
+ * This is the main implementation that handles all SAP AI Core embedding logic.
30422
+ * @param modelId - The model identifier (e.g., 'text-embedding-ada-002', 'text-embedding-3-small').
30423
+ * @param settings - Model configuration settings (embedding type, model parameters, etc.).
30424
+ * @param config - SAP AI Core deployment and destination configuration.
30389
30425
  */
30390
30426
  constructor(modelId, settings = {}, config) {
30391
30427
  if (settings.modelParams) {
@@ -30400,20 +30436,9 @@ var SAPAIEmbeddingModel = class {
30400
30436
  /**
30401
30437
  * Generates embeddings for the given input values.
30402
30438
  *
30403
- * This method implements the EmbeddingModelV3 interface and wraps
30404
- * the SAP AI SDK's OrchestrationEmbeddingClient.
30405
- * @param options - The embedding request options
30406
- * @returns Promise resolving to embeddings and usage information
30407
- * @since 1.0.0
30408
- * @example
30409
- * ```typescript
30410
- * const result = await model.doEmbed({
30411
- * values: ['Hello, world!', 'How are you?']
30412
- * });
30413
- *
30414
- * console.log(result.embeddings); // [[0.1, 0.2, ...], [0.3, 0.4, ...]]
30415
- * console.log(result.usage?.tokens); // 10
30416
- * ```
30439
+ * Validates input count, merges settings, calls SAP AI SDK, and normalizes embeddings.
30440
+ * @param options - The Vercel AI SDK V3 embedding call options.
30441
+ * @returns The embedding result with vectors, usage data, and warnings.
30417
30442
  */
30418
30443
  async doEmbed(options) {
30419
30444
  const { abortSignal, providerOptions, values } = options;
@@ -30435,11 +30460,7 @@ var SAPAIEmbeddingModel = class {
30435
30460
  try {
30436
30461
  const client = this.createClient(sapOptions?.modelParams);
30437
30462
  const response = await client.embed(
30438
- {
30439
- input: values,
30440
- type: embeddingType
30441
- },
30442
- // Pass abortSignal to the SAP SDK via requestConfig
30463
+ { input: values, type: embeddingType },
30443
30464
  abortSignal ? { signal: abortSignal } : void 0
30444
30465
  );
30445
30466
  const embeddingData = response.getEmbeddings();
@@ -30468,15 +30489,13 @@ var SAPAIEmbeddingModel = class {
30468
30489
  }
30469
30490
  }
30470
30491
  /**
30471
- * Creates an OrchestrationEmbeddingClient with the current configuration.
30472
- * @param perCallModelParams - Optional model params from per-call provider options
30473
- * @returns Configured embedding client
30492
+ * Creates an SAP AI SDK OrchestrationEmbeddingClient with merged configuration.
30493
+ * @param perCallModelParams - Per-call model parameters to merge with instance settings.
30494
+ * @returns A configured SAP AI SDK embedding client instance.
30495
+ * @internal
30474
30496
  */
30475
30497
  createClient(perCallModelParams) {
30476
- const mergedParams = {
30477
- ...this.settings.modelParams,
30478
- ...perCallModelParams
30479
- };
30498
+ const mergedParams = deepMerge(this.settings.modelParams ?? {}, perCallModelParams ?? {});
30480
30499
  const hasParams = Object.keys(mergedParams).length > 0;
30481
30500
  const embeddingConfig = {
30482
30501
  model: {
@@ -30491,10 +30510,10 @@ var SAPAIEmbeddingModel = class {
30491
30510
  );
30492
30511
  }
30493
30512
  /**
30494
- * Converts SAP embedding response to AI SDK format.
30495
- * Handles both number array and base64-encoded string formats.
30496
- * @param embedding - The embedding from SAP API (number[] or base64 string)
30497
- * @returns Normalized embedding as number array
30513
+ * Converts SAP AI SDK embedding (number[] or base64) to Vercel AI SDK format.
30514
+ * @param embedding - The embedding as number array or base64 string.
30515
+ * @returns The normalized embedding as a number array.
30516
+ * @internal
30498
30517
  */
30499
30518
  normalizeEmbedding(embedding) {
30500
30519
  if (Array.isArray(embedding)) {
@@ -30512,19 +30531,26 @@ var SAPAIEmbeddingModel = class {
30512
30531
 
30513
30532
  // src/sap-ai-embedding-model-v2.ts
30514
30533
  var SAPAIEmbeddingModelV2 = class {
30534
+ /** Maximum number of embeddings per API call. */
30515
30535
  maxEmbeddingsPerCall;
30536
+ /** The model identifier. */
30516
30537
  modelId;
30538
+ /** The provider identifier string. */
30517
30539
  provider;
30540
+ /** The Vercel AI SDK specification version. */
30518
30541
  specificationVersion = "v2";
30542
+ /** Whether the model supports parallel API calls. */
30519
30543
  supportsParallelCalls;
30520
- /** Internal V3 model instance that handles all SAP AI Core logic */
30544
+ /** Internal V3 model instance that handles all SAP AI Core logic. */
30521
30545
  v3Model;
30522
30546
  /**
30523
30547
  * Creates a new SAP AI Embedding Model V2 instance.
30548
+ *
30549
+ * This constructor creates a V3 implementation internally and delegates all operations to it.
30550
+ * @param modelId - The model identifier (e.g., 'text-embedding-ada-002', 'text-embedding-3-small').
30551
+ * @param settings - Model configuration settings (embedding type, model parameters, etc.).
30552
+ * @param config - SAP AI Core deployment and destination configuration.
30524
30553
  * @internal
30525
- * @param modelId - The embedding model identifier (e.g., 'text-embedding-ada-002')
30526
- * @param settings - Model-specific configuration settings
30527
- * @param config - Internal configuration (deployment config, destination, etc.)
30528
30554
  */
30529
30555
  constructor(modelId, settings, config) {
30530
30556
  this.v3Model = new SAPAIEmbeddingModel(modelId, settings, config);
@@ -30536,19 +30562,14 @@ var SAPAIEmbeddingModelV2 = class {
30536
30562
  /**
30537
30563
  * Generates embeddings for the given text values.
30538
30564
  *
30539
- * Implements `EmbeddingModelV2.doEmbed`, delegating to the internal V3 implementation
30540
- * and transforming the response to V2 format.
30541
- *
30542
- * The main differences between V2 and V3:
30543
- * - V3 includes a `warnings` array that needs to be converted
30544
- * - Provider metadata and headers use different type definitions
30545
- * @param options - Embedding options including values and headers
30546
- * @param options.values - Array of text values to embed
30547
- * @param options.abortSignal - Optional abort signal for cancelling the operation
30548
- * @param options.providerOptions - Optional provider-specific options
30549
- * @param options.headers - Optional HTTP headers
30550
- * @returns Promise resolving to embeddings and metadata in V2 format
30551
- * @since 1.0.0
30565
+ * Delegates to V3 implementation and transforms the result to V2 format.
30566
+ * Warnings are logged to console instead of being returned (V2 API limitation).
30567
+ * @param options - The embedding generation options.
30568
+ * @param options.abortSignal - Optional abort signal to cancel the request.
30569
+ * @param options.headers - Optional HTTP headers to include in the request.
30570
+ * @param options.providerOptions - Optional provider-specific options.
30571
+ * @param options.values - The text values to generate embeddings for.
30572
+ * @returns The embedding result with vectors, usage, and provider metadata.
30552
30573
  */
30553
30574
  async doEmbed(options) {
30554
30575
  const v3Options = {
@@ -30589,9 +30610,6 @@ function castProviderMetadataV3ToV2(v3Metadata) {
30589
30610
  return v3Metadata;
30590
30611
  }
30591
30612
 
30592
- // src/sap-ai-provider-v2.ts
30593
- var import_provider4 = require("@ai-sdk/provider");
30594
-
30595
30613
  // src/sap-ai-language-model.ts
30596
30614
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
30597
30615
  var import_orchestration2 = require("@sap-ai-sdk/orchestration");
@@ -30762,72 +30780,73 @@ function convertToSAPMessages(prompt, options = {}) {
30762
30780
  }
30763
30781
 
30764
30782
  // src/sap-ai-language-model.ts
30783
+ var PARAM_MAPPINGS = [
30784
+ { camelCaseKey: "maxTokens", optionKey: "maxOutputTokens", outputKey: "max_tokens" },
30785
+ { camelCaseKey: "temperature", optionKey: "temperature", outputKey: "temperature" },
30786
+ { camelCaseKey: "topP", optionKey: "topP", outputKey: "top_p" },
30787
+ { camelCaseKey: "topK", optionKey: "topK", outputKey: "top_k" },
30788
+ {
30789
+ camelCaseKey: "frequencyPenalty",
30790
+ optionKey: "frequencyPenalty",
30791
+ outputKey: "frequency_penalty"
30792
+ },
30793
+ { camelCaseKey: "presencePenalty", optionKey: "presencePenalty", outputKey: "presence_penalty" },
30794
+ { camelCaseKey: "seed", optionKey: "seed", outputKey: "seed" },
30795
+ { camelCaseKey: "parallel_tool_calls", outputKey: "parallel_tool_calls" }
30796
+ ];
30765
30797
  var StreamIdGenerator = class {
30766
- /**
30767
- * Generates a unique ID for a response stream.
30768
- * @returns RFC 4122-compliant UUID
30769
- */
30770
30798
  generateResponseId() {
30771
30799
  return crypto.randomUUID();
30772
30800
  }
30773
- /**
30774
- * Generates a unique ID for a text block.
30775
- * @returns RFC 4122-compliant UUID
30776
- */
30777
30801
  generateTextBlockId() {
30778
30802
  return crypto.randomUUID();
30779
30803
  }
30780
30804
  };
30781
30805
  var SAPAILanguageModel = class {
30806
+ /** The model identifier. */
30782
30807
  modelId;
30808
+ /** The Vercel AI SDK specification version. */
30783
30809
  specificationVersion = "v3";
30784
- /**
30785
- * Model capabilities.
30786
- *
30787
- * These defaults assume “modern” model behavior to avoid maintaining a
30788
- * per-model capability matrix. If a deployment doesn't support a feature,
30789
- * SAP AI Core will fail the request at runtime.
30790
- */
30810
+ /** Whether the model supports image URLs in prompts. */
30791
30811
  supportsImageUrls = true;
30792
- /**
30793
- * Multiple completions via the `n` parameter.
30794
- * Note: Amazon and Anthropic models do not support this feature.
30795
- * The provider silently omits the parameter for unsupported models.
30796
- */
30812
+ /** Whether the model supports generating multiple completions. */
30797
30813
  supportsMultipleCompletions = true;
30798
- /** Parallel tool calls. */
30814
+ /** Whether the model supports parallel tool calls. */
30799
30815
  supportsParallelToolCalls = true;
30800
- /** Streaming responses. */
30816
+ /** Whether the model supports streaming responses. */
30801
30817
  supportsStreaming = true;
30802
- /** Structured JSON outputs (json_schema response format). */
30818
+ /** Whether the model supports structured JSON outputs. */
30803
30819
  supportsStructuredOutputs = true;
30804
- /** Tool/function calling. */
30820
+ /** Whether the model supports tool/function calling. */
30805
30821
  supportsToolCalls = true;
30806
30822
  /**
30807
- * Returns the provider identifier.
30808
- * @returns The provider name
30823
+ * Gets the provider identifier string.
30824
+ * @returns The provider identifier.
30809
30825
  */
30810
30826
  get provider() {
30811
30827
  return this.config.provider;
30812
30828
  }
30813
30829
  /**
30814
- * Returns supported URL patterns for different content types.
30815
- * @returns Record of content types to regex patterns
30830
+ * Gets the supported URL patterns for image input.
30831
+ * @returns A mapping of MIME type patterns to URL regex patterns.
30816
30832
  */
30817
30833
  get supportedUrls() {
30818
30834
  return {
30819
30835
  "image/*": [/^https:\/\/.+$/i, /^data:image\/.*$/]
30820
30836
  };
30821
30837
  }
30838
+ /** @internal */
30822
30839
  config;
30840
+ /** @internal */
30823
30841
  settings;
30824
30842
  /**
30825
- * Creates a new SAP AI Chat Language Model instance.
30843
+ * Creates a new SAP AI Language Model instance.
30844
+ *
30845
+ * This is the main implementation that handles all SAP AI Core orchestration logic.
30846
+ * @param modelId - The model identifier (e.g., 'gpt-4o', 'claude-3-5-sonnet', 'gemini-2.0-flash').
30847
+ * @param settings - Model configuration settings (temperature, max tokens, filtering, etc.).
30848
+ * @param config - SAP AI Core deployment and destination configuration.
30826
30849
  * @internal
30827
- * @param modelId - The model identifier
30828
- * @param settings - Model-specific configuration settings
30829
- * @param config - Internal configuration (deployment config, destination, etc.)
30830
- * @throws {z.ZodError} If modelParams contains invalid values
30831
30850
  */
30832
30851
  constructor(modelId, settings, config) {
30833
30852
  if (settings.modelParams) {
@@ -30840,109 +30859,22 @@ var SAPAILanguageModel = class {
30840
30859
  /**
30841
30860
  * Generates a single completion (non-streaming).
30842
30861
  *
30843
- * This method implements the `LanguageModelV3.doGenerate` interface,
30844
- * sending a request to SAP AI Core and returning the complete response.
30845
- *
30846
- * **Features:**
30847
- * - Tool calling support
30848
- * - Multi-modal input (text + images)
30849
- * - Data masking (if configured)
30850
- * - Content filtering (if configured)
30851
- * - Abort signal support (via Promise.race)
30852
- *
30853
- * **Note on Abort Signal:**
30854
- * The abort signal implementation uses Promise.race to reject the promise when
30855
- * aborted. However, this does not cancel the underlying HTTP request to SAP AI Core -
30856
- * the request continues executing on the server. This is a current limitation of the
30857
- * SAP AI SDK's API. See https://github.com/SAP/ai-sdk-js/issues/1429
30858
- * @param options - Generation options including prompt, tools, and settings
30859
- * @returns Promise resolving to the generation result with content, usage, and metadata
30860
- * @since 1.0.0
30861
- * @example
30862
- * ```typescript
30863
- * const result = await model.doGenerate({
30864
- * prompt: [
30865
- * { role: 'user', content: [{ type: 'text', text: 'Hello!' }] }
30866
- * ]
30867
- * });
30868
- *
30869
- * console.log(result.content); // Generated content
30870
- * console.log(result.usage); // Token usage
30871
- * ```
30862
+ * Builds orchestration configuration, converts messages, validates parameters,
30863
+ * calls SAP AI SDK, and processes the response.
30864
+ * Supports request cancellation via AbortSignal at the HTTP transport layer.
30865
+ * @param options - The Vercel AI SDK V3 generation call options.
30866
+ * @returns The generation result with content, usage, warnings, and provider metadata.
30872
30867
  */
30873
30868
  async doGenerate(options) {
30874
30869
  try {
30875
30870
  const { messages, orchestrationConfig, warnings } = await this.buildOrchestrationConfig(options);
30876
30871
  const client = this.createClient(orchestrationConfig);
30877
- const promptTemplating = orchestrationConfig.promptTemplating;
30878
- const requestBody = {
30879
- messages,
30880
- model: {
30881
- ...orchestrationConfig.promptTemplating.model
30882
- },
30883
- ...promptTemplating.prompt.tools ? { tools: promptTemplating.prompt.tools } : {},
30884
- ...promptTemplating.prompt.response_format ? { response_format: promptTemplating.prompt.response_format } : {},
30885
- ...(() => {
30886
- const masking = orchestrationConfig.masking;
30887
- return masking && Object.keys(masking).length > 0 ? { masking } : {};
30888
- })(),
30889
- ...(() => {
30890
- const filtering = orchestrationConfig.filtering;
30891
- return filtering && Object.keys(filtering).length > 0 ? { filtering } : {};
30892
- })(),
30893
- ...(() => {
30894
- const grounding = orchestrationConfig.grounding;
30895
- return grounding && Object.keys(grounding).length > 0 ? { grounding } : {};
30896
- })(),
30897
- ...(() => {
30898
- const translation = orchestrationConfig.translation;
30899
- return translation && Object.keys(translation).length > 0 ? { translation } : {};
30900
- })()
30901
- };
30902
- const response = await (async () => {
30903
- const completionPromise = client.chatCompletion(requestBody);
30904
- if (options.abortSignal) {
30905
- return Promise.race([
30906
- completionPromise,
30907
- new Promise((_, reject) => {
30908
- if (options.abortSignal?.aborted) {
30909
- reject(
30910
- new Error(
30911
- `Request aborted: ${String(options.abortSignal.reason ?? "unknown reason")}`
30912
- )
30913
- );
30914
- return;
30915
- }
30916
- options.abortSignal?.addEventListener(
30917
- "abort",
30918
- () => {
30919
- reject(
30920
- new Error(
30921
- `Request aborted: ${String(options.abortSignal?.reason ?? "unknown reason")}`
30922
- )
30923
- );
30924
- },
30925
- { once: true }
30926
- );
30927
- })
30928
- ]);
30929
- }
30930
- return completionPromise;
30931
- })();
30932
- const responseHeadersRaw = response.rawResponse.headers;
30933
- const responseHeaders = responseHeadersRaw ? Object.fromEntries(
30934
- Object.entries(responseHeadersRaw).flatMap(([key, value]) => {
30935
- if (typeof value === "string") return [[key, value]];
30936
- if (Array.isArray(value)) {
30937
- const strings = value.filter((item) => typeof item === "string").join("; ");
30938
- return strings.length > 0 ? [[key, strings]] : [];
30939
- }
30940
- if (typeof value === "number" || typeof value === "boolean") {
30941
- return [[key, String(value)]];
30942
- }
30943
- return [];
30944
- })
30945
- ) : void 0;
30872
+ const requestBody = this.buildRequestBody(messages, orchestrationConfig);
30873
+ const response = await client.chatCompletion(
30874
+ requestBody,
30875
+ options.abortSignal ? { signal: options.abortSignal } : void 0
30876
+ );
30877
+ const responseHeaders = normalizeHeaders(response.rawResponse.headers);
30946
30878
  const content = [];
30947
30879
  const textContent = response.getContent();
30948
30880
  if (textContent) {
@@ -31017,66 +30949,17 @@ var SAPAILanguageModel = class {
31017
30949
  /**
31018
30950
  * Generates a streaming completion.
31019
30951
  *
31020
- * Implements `LanguageModelV3.doStream`, sending a streaming request to SAP AI Core
31021
- * and returning a stream of response parts.
31022
- *
31023
- * **Stream Events:**
31024
- * - `stream-start` - Initialization with warnings
31025
- * - `response-metadata` - Model, timestamp, response ID
31026
- * - `text-start` - Text block begins (with unique ID)
31027
- * - `text-delta` - Incremental text chunks
31028
- * - `text-end` - Text block completes
31029
- * - `tool-input-start/delta/end` - Tool input lifecycle
31030
- * - `tool-call` - Complete tool call
31031
- * - `finish` - Stream completes with usage and finish reason
31032
- * - `error` - Error occurred
31033
- *
31034
- * **Response ID:**
31035
- * Client-generated UUID in `response-metadata.id` and `providerMetadata['sap-ai'].responseId`.
31036
- * TODO: Use backend's `x-request-id` when `OrchestrationStreamResponse` exposes `rawResponse`.
31037
- *
31038
- * **Abort Signal:**
31039
- * Same limitation as `doGenerate` - see its documentation for details.
31040
- * @see {@link https://sdk.vercel.ai/docs/ai-sdk-core/streaming Vercel AI SDK Streaming}
31041
- * @param options - Streaming options including prompt, tools, and settings
31042
- * @returns Promise resolving to stream and request metadata
31043
- * @example
31044
- * ```typescript
31045
- * const { stream } = await model.doStream({
31046
- * prompt: [
31047
- * { role: 'user', content: [{ type: 'text', text: 'Write a story' }] }
31048
- * ]
31049
- * });
31050
- *
31051
- * for await (const part of stream) {
31052
- * if (part.type === 'text-delta') {
31053
- * process.stdout.write(part.delta);
31054
- * }
31055
- * }
31056
- * ```
31057
- * @since 1.0.0
30952
+ * Builds orchestration configuration, creates streaming client, and transforms
30953
+ * the stream with proper event handling (text blocks, tool calls, finish reason).
30954
+ * Supports request cancellation via AbortSignal at the HTTP transport layer.
30955
+ * @param options - The Vercel AI SDK V3 generation call options.
30956
+ * @returns A stream result with async iterable stream parts.
31058
30957
  */
31059
30958
  async doStream(options) {
31060
30959
  try {
31061
30960
  const { messages, orchestrationConfig, warnings } = await this.buildOrchestrationConfig(options);
31062
30961
  const client = this.createClient(orchestrationConfig);
31063
- const promptTemplating = orchestrationConfig.promptTemplating;
31064
- const requestBody = {
31065
- messages,
31066
- model: {
31067
- ...orchestrationConfig.promptTemplating.model
31068
- },
31069
- ...promptTemplating.prompt.tools ? { tools: promptTemplating.prompt.tools } : {},
31070
- ...promptTemplating.prompt.response_format ? { response_format: promptTemplating.prompt.response_format } : {},
31071
- ...(() => {
31072
- const masking = orchestrationConfig.masking;
31073
- return masking && Object.keys(masking).length > 0 ? { masking } : {};
31074
- })(),
31075
- ...(() => {
31076
- const filtering = orchestrationConfig.filtering;
31077
- return filtering && Object.keys(filtering).length > 0 ? { filtering } : {};
31078
- })()
31079
- };
30962
+ const requestBody = this.buildRequestBody(messages, orchestrationConfig);
31080
30963
  const streamResponse = await client.stream(requestBody, options.abortSignal, {
31081
30964
  promptTemplating: { include_usage: true }
31082
30965
  });
@@ -31334,9 +31217,9 @@ var SAPAILanguageModel = class {
31334
31217
  }
31335
31218
  }
31336
31219
  /**
31337
- * Checks if a URL is supported for file/image uploads.
31338
- * @param url - The URL to check
31339
- * @returns True if the URL protocol is HTTPS or data with valid image format
31220
+ * Checks if a URL is supported for image input (HTTPS or data:image/*).
31221
+ * @param url - The URL to check.
31222
+ * @returns True if the URL is supported for image input.
31340
31223
  */
31341
31224
  supportsUrl(url) {
31342
31225
  if (url.protocol === "https:") return true;
@@ -31346,9 +31229,9 @@ var SAPAILanguageModel = class {
31346
31229
  return false;
31347
31230
  }
31348
31231
  /**
31349
- * Builds orchestration module config for SAP AI SDK.
31350
- * @param options - Call options from the AI SDK
31351
- * @returns Promise resolving to object containing orchestration config, messages, and warnings
31232
+ * Builds the SAP AI SDK orchestration configuration from Vercel AI SDK call options.
31233
+ * @param options - The Vercel AI SDK language model call options.
31234
+ * @returns The SAP AI SDK orchestration configuration, messages, and warnings.
31352
31235
  * @internal
31353
31236
  */
31354
31237
  async buildOrchestrationConfig(options) {
@@ -31427,37 +31310,26 @@ var SAPAILanguageModel = class {
31427
31310
  }).filter((t) => t !== null);
31428
31311
  }
31429
31312
  const supportsN = !this.modelId.startsWith("amazon--") && !this.modelId.startsWith("anthropic--");
31430
- const modelParams = {};
31431
- const maxTokens = options.maxOutputTokens ?? sapOptions?.modelParams?.maxTokens ?? this.settings.modelParams?.maxTokens;
31432
- if (maxTokens !== void 0) modelParams.max_tokens = maxTokens;
31433
- const temperature = options.temperature ?? sapOptions?.modelParams?.temperature ?? this.settings.modelParams?.temperature;
31434
- if (temperature !== void 0) modelParams.temperature = temperature;
31435
- const topP = options.topP ?? sapOptions?.modelParams?.topP ?? this.settings.modelParams?.topP;
31436
- if (topP !== void 0) modelParams.top_p = topP;
31437
- if (options.topK !== void 0) modelParams.top_k = options.topK;
31438
- const frequencyPenalty = options.frequencyPenalty ?? sapOptions?.modelParams?.frequencyPenalty ?? this.settings.modelParams?.frequencyPenalty;
31439
- if (frequencyPenalty !== void 0) {
31440
- modelParams.frequency_penalty = frequencyPenalty;
31441
- }
31442
- const presencePenalty = options.presencePenalty ?? sapOptions?.modelParams?.presencePenalty ?? this.settings.modelParams?.presencePenalty;
31443
- if (presencePenalty !== void 0) {
31444
- modelParams.presence_penalty = presencePenalty;
31313
+ const modelParams = deepMerge(
31314
+ this.settings.modelParams ?? {},
31315
+ sapOptions?.modelParams ?? {}
31316
+ );
31317
+ applyParameterOverrides(
31318
+ modelParams,
31319
+ options,
31320
+ sapOptions?.modelParams,
31321
+ this.settings.modelParams
31322
+ );
31323
+ if (options.stopSequences && options.stopSequences.length > 0) {
31324
+ modelParams.stop = options.stopSequences;
31445
31325
  }
31446
31326
  if (supportsN) {
31447
31327
  const nValue = sapOptions?.modelParams?.n ?? this.settings.modelParams?.n;
31448
31328
  if (nValue !== void 0) {
31449
31329
  modelParams.n = nValue;
31450
31330
  }
31451
- }
31452
- const parallelToolCalls = sapOptions?.modelParams?.parallel_tool_calls ?? this.settings.modelParams?.parallel_tool_calls;
31453
- if (parallelToolCalls !== void 0) {
31454
- modelParams.parallel_tool_calls = parallelToolCalls;
31455
- }
31456
- if (options.stopSequences && options.stopSequences.length > 0) {
31457
- modelParams.stop = options.stopSequences;
31458
- }
31459
- if (options.seed !== void 0) {
31460
- modelParams.seed = options.seed;
31331
+ } else {
31332
+ delete modelParams.n;
31461
31333
  }
31462
31334
  validateModelParamsWithWarnings(
31463
31335
  {
@@ -31509,35 +31381,57 @@ var SAPAILanguageModel = class {
31509
31381
  ...responseFormat ? { response_format: responseFormat } : {}
31510
31382
  }
31511
31383
  },
31512
- ...(() => {
31513
- const masking = this.settings.masking;
31514
- return masking && Object.keys(masking).length > 0 ? { masking } : {};
31515
- })(),
31516
- ...(() => {
31517
- const filtering = this.settings.filtering;
31518
- return filtering && Object.keys(filtering).length > 0 ? { filtering } : {};
31519
- })(),
31520
- ...(() => {
31521
- const grounding = this.settings.grounding;
31522
- return grounding && Object.keys(grounding).length > 0 ? { grounding } : {};
31523
- })(),
31524
- ...(() => {
31525
- const translation = this.settings.translation;
31526
- return translation && Object.keys(translation).length > 0 ? { translation } : {};
31527
- })()
31384
+ ...this.settings.masking && Object.keys(this.settings.masking).length > 0 ? { masking: this.settings.masking } : {},
31385
+ ...this.settings.filtering && Object.keys(this.settings.filtering).length > 0 ? { filtering: this.settings.filtering } : {},
31386
+ ...this.settings.grounding && Object.keys(this.settings.grounding).length > 0 ? { grounding: this.settings.grounding } : {},
31387
+ ...this.settings.translation && Object.keys(this.settings.translation).length > 0 ? { translation: this.settings.translation } : {}
31528
31388
  };
31529
31389
  return { messages, orchestrationConfig, warnings };
31530
31390
  }
31531
31391
  /**
31532
- * Creates an OrchestrationClient instance.
31533
- * @param config - Orchestration module configuration
31534
- * @returns OrchestrationClient instance
31392
+ * Builds the request body for SAP AI SDK chat completion or streaming.
31393
+ * @param messages - The chat messages to send.
31394
+ * @param orchestrationConfig - The orchestration configuration.
31395
+ * @returns The request body object.
31396
+ * @internal
31397
+ */
31398
+ buildRequestBody(messages, orchestrationConfig) {
31399
+ const promptTemplating = orchestrationConfig.promptTemplating;
31400
+ return {
31401
+ messages,
31402
+ model: {
31403
+ ...orchestrationConfig.promptTemplating.model
31404
+ },
31405
+ ...promptTemplating.prompt.tools ? { tools: promptTemplating.prompt.tools } : {},
31406
+ ...promptTemplating.prompt.response_format ? { response_format: promptTemplating.prompt.response_format } : {},
31407
+ ...orchestrationConfig.masking && Object.keys(orchestrationConfig.masking).length > 0 ? { masking: orchestrationConfig.masking } : {},
31408
+ ...orchestrationConfig.filtering && Object.keys(orchestrationConfig.filtering).length > 0 ? { filtering: orchestrationConfig.filtering } : {},
31409
+ ...orchestrationConfig.grounding && Object.keys(orchestrationConfig.grounding).length > 0 ? { grounding: orchestrationConfig.grounding } : {},
31410
+ ...orchestrationConfig.translation && Object.keys(orchestrationConfig.translation).length > 0 ? { translation: orchestrationConfig.translation } : {}
31411
+ };
31412
+ }
31413
+ /**
31414
+ * Creates an SAP AI SDK OrchestrationClient with the given configuration.
31415
+ * @param config - The SAP AI SDK orchestration module configuration.
31416
+ * @returns A configured SAP AI SDK orchestration client.
31535
31417
  * @internal
31536
31418
  */
31537
31419
  createClient(config) {
31538
31420
  return new import_orchestration2.OrchestrationClient(config, this.config.deploymentConfig, this.config.destination);
31539
31421
  }
31540
31422
  };
31423
+ function applyParameterOverrides(modelParams, options, sapModelParams, settingsModelParams) {
31424
+ const params = modelParams;
31425
+ for (const mapping of PARAM_MAPPINGS) {
31426
+ const value = (mapping.optionKey ? options[mapping.optionKey] : void 0) ?? (mapping.camelCaseKey ? sapModelParams?.[mapping.camelCaseKey] : void 0) ?? (mapping.camelCaseKey ? settingsModelParams?.[mapping.camelCaseKey] : void 0);
31427
+ if (value !== void 0) {
31428
+ params[mapping.outputKey] = value;
31429
+ }
31430
+ if (mapping.camelCaseKey && mapping.camelCaseKey !== mapping.outputKey) {
31431
+ Reflect.deleteProperty(params, mapping.camelCaseKey);
31432
+ }
31433
+ }
31434
+ }
31541
31435
  function buildSAPToolParameters(schema) {
31542
31436
  const schemaType = schema.type;
31543
31437
  if (schemaType !== void 0 && schemaType !== "object") {
@@ -31616,31 +31510,34 @@ function mapFinishReason(reason) {
31616
31510
 
31617
31511
  // src/sap-ai-language-model-v2.ts
31618
31512
  var SAPAILanguageModelV2 = class {
31513
+ /** The model identifier. */
31619
31514
  modelId;
31515
+ /** The Vercel AI SDK specification version. */
31620
31516
  specificationVersion = "v2";
31621
31517
  /**
31622
- * Returns the provider identifier.
31623
- * @returns The provider name
31518
+ * Gets the provider identifier string.
31519
+ * @returns The provider identifier.
31624
31520
  */
31625
31521
  get provider() {
31626
31522
  return this.v3Model.provider;
31627
31523
  }
31628
31524
  /**
31629
- * Returns supported URL patterns for different content types.
31630
- * @returns Record of content types to regex patterns
31525
+ * Gets the supported URL patterns for image input.
31526
+ * @returns A mapping of MIME type patterns to URL regex patterns.
31631
31527
  */
31632
31528
  get supportedUrls() {
31633
31529
  return this.v3Model.supportedUrls;
31634
31530
  }
31635
- /** Internal V3 model instance that handles all SAP AI Core logic */
31531
+ /** Internal V3 model instance that handles all SAP AI Core logic. */
31636
31532
  v3Model;
31637
31533
  /**
31638
31534
  * Creates a new SAP AI Language Model V2 instance.
31535
+ *
31536
+ * This constructor creates a V3 implementation internally and delegates all operations to it.
31537
+ * @param modelId - The model identifier (e.g., 'gpt-4o', 'claude-3-5-sonnet', 'gemini-2.0-flash').
31538
+ * @param settings - Model configuration settings (temperature, max tokens, filtering, etc.).
31539
+ * @param config - SAP AI Core deployment and destination configuration.
31639
31540
  * @internal
31640
- * @param modelId - The model identifier
31641
- * @param settings - Model-specific configuration settings
31642
- * @param config - Internal configuration (deployment config, destination, etc.)
31643
- * @throws {z.ZodError} If modelParams contains invalid values
31644
31541
  */
31645
31542
  constructor(modelId, settings, config) {
31646
31543
  this.modelId = modelId;
@@ -31649,40 +31546,10 @@ var SAPAILanguageModelV2 = class {
31649
31546
  /**
31650
31547
  * Generates a single completion (non-streaming).
31651
31548
  *
31652
- * This method implements the `LanguageModelV2.doGenerate` interface,
31653
- * delegating to the internal V3 implementation and transforming the result
31654
- * to V2 format.
31655
- *
31656
- * **Features:**
31657
- * - Tool calling support
31658
- * - Multi-modal input (text + images)
31659
- * - Data masking (if configured)
31660
- * - Content filtering (if configured)
31661
- * - Abort signal support (via Promise.race)
31662
- *
31663
- * **Note on Abort Signal:**
31664
- * The abort signal implementation uses Promise.race to reject the promise when
31665
- * aborted. However, this does not cancel the underlying HTTP request to SAP AI Core -
31666
- * the request continues executing on the server. This is a current limitation of the
31667
- * SAP AI SDK's API. See https://github.com/SAP/ai-sdk-js/issues/1429
31668
- * @param options - Generation options including prompt, tools, and settings
31669
- * @returns Promise resolving to the generation result with content, usage, and metadata
31670
- * @see {@link convertFinishReasonV3ToV2} for finish reason transformation
31671
- * @see {@link convertUsageV3ToV2} for usage statistics transformation
31672
- * @see {@link convertWarningsV3ToV2} for warnings transformation
31673
- * @since 1.0.0
31674
- * @example
31675
- * ```typescript
31676
- * const result = await model.doGenerate({
31677
- * prompt: [
31678
- * { role: 'user', content: [{ type: 'text', text: 'Hello!' }] }
31679
- * ]
31680
- * });
31681
- *
31682
- * console.log(result.content); // Generated content
31683
- * console.log(result.usage); // Token usage (V2 format)
31684
- * console.log(result.finishReason); // 'stop' (V2 string format)
31685
- * ```
31549
+ * Delegates to V3 implementation and transforms the result to V2 format.
31550
+ * Supports request cancellation via AbortSignal at the HTTP transport layer.
31551
+ * @param options - The Vercel AI SDK V2 generation call options.
31552
+ * @returns The generation result with content, usage, warnings, and provider metadata.
31686
31553
  */
31687
31554
  async doGenerate(options) {
31688
31555
  const v3Result = await this.v3Model.doGenerate(options);
@@ -31706,47 +31573,10 @@ var SAPAILanguageModelV2 = class {
31706
31573
  /**
31707
31574
  * Generates a streaming completion.
31708
31575
  *
31709
- * Implements `LanguageModelV2.doStream`, delegating to the internal V3 implementation
31710
- * and transforming the stream to V2 format.
31711
- *
31712
- * **Stream Events:**
31713
- * - `stream-start` - Initialization with warnings
31714
- * - `response-metadata` - Model, timestamp, response ID
31715
- * - `text-start` - Text block begins (with unique ID)
31716
- * - `text-delta` - Incremental text chunks
31717
- * - `text-end` - Text block completes
31718
- * - `tool-input-start/delta/end` - Tool input lifecycle
31719
- * - `tool-call` - Complete tool call
31720
- * - `finish` - Stream completes with usage (V2 format) and finish reason (V2 string)
31721
- * - `error` - Error occurred
31722
- *
31723
- * **Response ID:**
31724
- * Client-generated UUID in `response-metadata.id` and `providerMetadata['sap-ai'].responseId`.
31725
- * TODO: Use backend's `x-request-id` when `OrchestrationStreamResponse` exposes `rawResponse`.
31726
- * @see https://github.com/SAP/ai-sdk-js/issues/1429 - Enhancement request for rawResponse access
31727
- *
31728
- * **Abort Signal:**
31729
- * Same limitation as `doGenerate` - see its documentation for details.
31730
- * @see {@link https://sdk.vercel.ai/docs/ai-sdk-core/streaming Vercel AI SDK Streaming}
31731
- * @see {@link convertStreamV3ToV2} for stream transformation logic
31732
- * @see {@link convertStreamPartV3ToV2} for individual stream part conversion
31733
- * @param options - Streaming options including prompt, tools, and settings
31734
- * @returns Promise resolving to stream and request metadata
31735
- * @example
31736
- * ```typescript
31737
- * const { stream } = await model.doStream({
31738
- * prompt: [
31739
- * { role: 'user', content: [{ type: 'text', text: 'Write a story' }] }
31740
- * ]
31741
- * });
31742
- *
31743
- * for await (const part of stream) {
31744
- * if (part.type === 'text-delta') {
31745
- * process.stdout.write(part.delta);
31746
- * }
31747
- * }
31748
- * ```
31749
- * @since 1.0.0
31576
+ * Delegates to V3 implementation and transforms the stream to V2 format.
31577
+ * Supports request cancellation via AbortSignal at the HTTP transport layer.
31578
+ * @param options - The Vercel AI SDK V2 generation call options.
31579
+ * @returns A stream result with readable stream of V2 stream parts.
31750
31580
  */
31751
31581
  async doStream(options) {
31752
31582
  const v3Result = await this.v3Model.doStream(options);
@@ -31773,6 +31603,8 @@ var SAPAILanguageModelV2 = class {
31773
31603
  };
31774
31604
 
31775
31605
  // src/sap-ai-provider-v2.ts
31606
+ var import_provider4 = require("@ai-sdk/provider");
31607
+ var import_util2 = __toESM(require_dist(), 1);
31776
31608
  function createSAPAIProvider(options = {}) {
31777
31609
  if (options.defaultSettings?.modelParams) {
31778
31610
  validateModelParamsSettings(options.defaultSettings.modelParams);
@@ -31785,18 +31617,21 @@ function createSAPAIProvider(options = {}) {
31785
31617
  "createSAPAIProvider: both 'deploymentId' and 'resourceGroup' were provided; using 'deploymentId' and ignoring 'resourceGroup'."
31786
31618
  );
31787
31619
  }
31620
+ if (!process.env.SAP_CLOUD_SDK_LOG_LEVEL) {
31621
+ const logLevel = options.logLevel ?? "warn";
31622
+ (0, import_util2.setGlobalLogLevel)(logLevel);
31623
+ }
31788
31624
  const deploymentConfig = options.deploymentId ? { deploymentId: options.deploymentId } : { resourceGroup };
31789
31625
  const createModel = (modelId, settings = {}) => {
31790
31626
  const mergedSettings = {
31791
31627
  ...options.defaultSettings,
31792
31628
  ...settings,
31793
31629
  filtering: settings.filtering ?? options.defaultSettings?.filtering,
31794
- // Complex objects: override, do not merge
31795
31630
  masking: settings.masking ?? options.defaultSettings?.masking,
31796
- modelParams: {
31797
- ...options.defaultSettings?.modelParams ?? {},
31798
- ...settings.modelParams ?? {}
31799
- },
31631
+ modelParams: deepMerge(
31632
+ options.defaultSettings?.modelParams ?? {},
31633
+ settings.modelParams ?? {}
31634
+ ),
31800
31635
  tools: settings.tools ?? options.defaultSettings?.tools
31801
31636
  };
31802
31637
  return new SAPAILanguageModelV2(modelId, mergedSettings, {
@@ -31820,7 +31655,6 @@ function createSAPAIProvider(options = {}) {
31820
31655
  };
31821
31656
  provider.chat = createModel;
31822
31657
  provider.languageModel = createModel;
31823
- provider.embedding = createEmbeddingModel;
31824
31658
  provider.textEmbeddingModel = createEmbeddingModel;
31825
31659
  provider.imageModel = (modelId) => {
31826
31660
  throw new import_provider4.NoSuchModelError({
@@ -31847,6 +31681,7 @@ var import_orchestration5 = require("@sap-ai-sdk/orchestration");
31847
31681
  OrchestrationStreamChunkResponse,
31848
31682
  OrchestrationStreamResponse,
31849
31683
  SAPAIEmbeddingModel,
31684
+ SAPAILanguageModel,
31850
31685
  SAP_AI_PROVIDER_NAME,
31851
31686
  buildAzureContentSafetyFilter,
31852
31687
  buildDocumentGroundingConfig,
@@ -31855,7 +31690,6 @@ var import_orchestration5 = require("@sap-ai-sdk/orchestration");
31855
31690
  buildTranslationConfig,
31856
31691
  createSAPAIProvider,
31857
31692
  getProviderName,
31858
- isConfigReference,
31859
31693
  sapAIEmbeddingProviderOptions,
31860
31694
  sapAILanguageModelProviderOptions,
31861
31695
  sapai