@jerome-benoit/sap-ai-provider 4.4.15 → 4.4.16

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 (25) hide show
  1. package/README.md +10 -0
  2. package/dist/{chunk-JV2ULRVE.js → chunk-U5TGXMXL.js} +69 -69
  3. package/dist/{chunk-JV2ULRVE.js.map → chunk-U5TGXMXL.js.map} +1 -1
  4. package/dist/{chunk-3JJ7OXMW.js → chunk-X3RVS75R.js} +2 -2
  5. package/dist/chunk-YWOWXJGS.js +54 -0
  6. package/dist/chunk-YWOWXJGS.js.map +1 -0
  7. package/dist/{chunk-CXZSTU4M.js → chunk-ZTTUNOQ4.js} +3 -3
  8. package/dist/foundation-models-embedding-model-strategy-3AL3KDCE.js +58 -0
  9. package/dist/foundation-models-embedding-model-strategy-3AL3KDCE.js.map +1 -0
  10. package/dist/{foundation-models-language-model-strategy-ZCRPVWAV.js → foundation-models-language-model-strategy-X6RMOTAL.js} +4 -4
  11. package/dist/index.cjs +169 -150
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.js +5 -5
  14. package/dist/orchestration-embedding-model-strategy-VCSK76HX.js +60 -0
  15. package/dist/orchestration-embedding-model-strategy-VCSK76HX.js.map +1 -0
  16. package/dist/{orchestration-language-model-strategy-NEW76M3M.js → orchestration-language-model-strategy-YFINEDMS.js} +4 -4
  17. package/package.json +5 -5
  18. package/dist/foundation-models-embedding-model-strategy-OEKTLGZN.js +0 -69
  19. package/dist/foundation-models-embedding-model-strategy-OEKTLGZN.js.map +0 -1
  20. package/dist/orchestration-embedding-model-strategy-QRHQIEEK.js +0 -79
  21. package/dist/orchestration-embedding-model-strategy-QRHQIEEK.js.map +0 -1
  22. /package/dist/{chunk-3JJ7OXMW.js.map → chunk-X3RVS75R.js.map} +0 -0
  23. /package/dist/{chunk-CXZSTU4M.js.map → chunk-ZTTUNOQ4.js.map} +0 -0
  24. /package/dist/{foundation-models-language-model-strategy-ZCRPVWAV.js.map → foundation-models-language-model-strategy-X6RMOTAL.js.map} +0 -0
  25. /package/dist/{orchestration-language-model-strategy-NEW76M3M.js.map → orchestration-language-model-strategy-YFINEDMS.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  getProviderName,
5
5
  sapAIEmbeddingProviderOptions,
6
6
  validateModelParamsWithWarnings
7
- } from "./chunk-JV2ULRVE.js";
7
+ } from "./chunk-U5TGXMXL.js";
8
8
 
9
9
  // src/strategy-utils.ts
10
10
  import { TooManyEmbeddingValuesForCallError } from "@ai-sdk/provider";
@@ -633,4 +633,4 @@ export {
633
633
  normalizeEmbedding,
634
634
  prepareEmbeddingCall
635
635
  };
636
- //# sourceMappingURL=chunk-3JJ7OXMW.js.map
636
+ //# sourceMappingURL=chunk-X3RVS75R.js.map
@@ -0,0 +1,54 @@
1
+ import {createRequire as __createRequire} from 'module';var require=__createRequire(import.meta.url);
2
+ import {
3
+ buildEmbeddingResult,
4
+ prepareEmbeddingCall
5
+ } from "./chunk-X3RVS75R.js";
6
+ import {
7
+ VERSION,
8
+ convertToAISDKError
9
+ } from "./chunk-U5TGXMXL.js";
10
+
11
+ // src/base-embedding-model-strategy.ts
12
+ var BaseEmbeddingModelStrategy = class {
13
+ /**
14
+ * Template method implementing the shared embedding algorithm.
15
+ * @param config - Strategy configuration.
16
+ * @param settings - Embedding model settings.
17
+ * @param options - AI SDK call options.
18
+ * @param maxEmbeddingsPerCall - Maximum embeddings per call.
19
+ * @returns Complete embedding result for AI SDK.
20
+ * @internal
21
+ */
22
+ async doEmbed(config, settings, options, maxEmbeddingsPerCall) {
23
+ const { abortSignal, values } = options;
24
+ const { embeddingOptions, providerName } = await prepareEmbeddingCall(
25
+ { maxEmbeddingsPerCall, modelId: config.modelId, provider: config.provider },
26
+ options
27
+ );
28
+ const embeddingType = embeddingOptions?.type ?? settings.type ?? "text";
29
+ try {
30
+ const client = this.createClient(config, settings, embeddingOptions);
31
+ const response = await this.executeCall(client, values, embeddingType, abortSignal);
32
+ const embeddings = this.extractEmbeddings(response);
33
+ const totalTokens = this.extractTokenCount(response);
34
+ return buildEmbeddingResult({
35
+ embeddings,
36
+ modelId: config.modelId,
37
+ providerName,
38
+ totalTokens,
39
+ version: VERSION
40
+ });
41
+ } catch (error) {
42
+ throw convertToAISDKError(error, {
43
+ operation: "doEmbed",
44
+ requestBody: { values: values.length },
45
+ url: this.getUrl()
46
+ });
47
+ }
48
+ }
49
+ };
50
+
51
+ export {
52
+ BaseEmbeddingModelStrategy
53
+ };
54
+ //# sourceMappingURL=chunk-YWOWXJGS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/base-embedding-model-strategy.ts"],"sourcesContent":["/** Base class for embedding model strategies using the Template Method pattern. */\nimport type {\n EmbeddingModelV3CallOptions,\n EmbeddingModelV3Embedding,\n EmbeddingModelV3Result,\n} from \"@ai-sdk/provider\";\n\nimport type { SAPAIEmbeddingSettings } from \"./sap-ai-settings.js\";\nimport type { EmbeddingModelAPIStrategy, EmbeddingModelStrategyConfig } from \"./sap-ai-strategy.js\";\n\nimport { convertToAISDKError } from \"./sap-ai-error.js\";\nimport {\n buildEmbeddingResult,\n type EmbeddingProviderOptions,\n type EmbeddingType,\n prepareEmbeddingCall,\n} from \"./strategy-utils.js\";\nimport { VERSION } from \"./version.js\";\n\n/**\n * Abstract base class for embedding model strategies using the Template Method pattern.\n * @template TClient - The SDK client type (e.g., AzureOpenAiEmbeddingClient, OrchestrationEmbeddingClient).\n * @template TResponse - The API response type from the SDK client.\n * @internal\n */\nexport abstract class BaseEmbeddingModelStrategy<\n TClient,\n TResponse,\n> implements EmbeddingModelAPIStrategy {\n /**\n * Template method implementing the shared embedding algorithm.\n * @param config - Strategy configuration.\n * @param settings - Embedding model settings.\n * @param options - AI SDK call options.\n * @param maxEmbeddingsPerCall - Maximum embeddings per call.\n * @returns Complete embedding result for AI SDK.\n * @internal\n */\n async doEmbed(\n config: EmbeddingModelStrategyConfig,\n settings: SAPAIEmbeddingSettings,\n options: EmbeddingModelV3CallOptions,\n maxEmbeddingsPerCall: number,\n ): Promise<EmbeddingModelV3Result> {\n const { abortSignal, values } = options;\n\n const { embeddingOptions, providerName } = await prepareEmbeddingCall(\n { maxEmbeddingsPerCall, modelId: config.modelId, provider: config.provider },\n options,\n );\n\n const embeddingType =\n embeddingOptions?.type ?? (settings.type as EmbeddingType | undefined) ?? \"text\";\n\n try {\n const client = this.createClient(config, settings, embeddingOptions);\n\n const response = await this.executeCall(client, values, embeddingType, abortSignal);\n\n const embeddings = this.extractEmbeddings(response);\n const totalTokens = this.extractTokenCount(response);\n\n return buildEmbeddingResult({\n embeddings,\n modelId: config.modelId,\n providerName,\n totalTokens,\n version: VERSION,\n });\n } catch (error) {\n throw convertToAISDKError(error, {\n operation: \"doEmbed\",\n requestBody: { values: values.length },\n url: this.getUrl(),\n });\n }\n }\n\n /**\n * Creates the appropriate SDK client for this API.\n * @param config - Strategy configuration.\n * @param settings - Embedding model settings.\n * @param embeddingOptions - Parsed provider options from the call.\n * @returns SDK client instance.\n * @internal\n */\n protected abstract createClient(\n config: EmbeddingModelStrategyConfig,\n settings: SAPAIEmbeddingSettings,\n embeddingOptions: EmbeddingProviderOptions | undefined,\n ): TClient;\n\n /**\n * Executes the embedding API call.\n * @param client - SDK client instance.\n * @param values - Input strings to embed.\n * @param embeddingType - Type of embedding (text, query, document).\n * @param abortSignal - Optional abort signal.\n * @returns SDK response containing embeddings.\n * @internal\n */\n protected abstract executeCall(\n client: TClient,\n values: string[],\n embeddingType: EmbeddingType,\n abortSignal: AbortSignal | undefined,\n ): Promise<TResponse>;\n\n /**\n * Extracts embeddings from the SDK response.\n * @param response - SDK response containing embedding data.\n * @returns Array of normalized embedding vectors.\n * @internal\n */\n protected abstract extractEmbeddings(response: TResponse): EmbeddingModelV3Embedding[];\n\n /**\n * Extracts total token count from the SDK response.\n * @param response - SDK response containing usage data.\n * @returns Total token count used for the embedding request.\n * @internal\n */\n protected abstract extractTokenCount(response: TResponse): number;\n\n /**\n * Returns the URL identifier for this API (used in error messages).\n * @returns URL string identifier.\n * @internal\n */\n protected abstract getUrl(): string;\n}\n"],"mappings":";;;;;;;;;;;AAyBO,IAAe,6BAAf,MAGgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUrC,MAAM,QACJ,QACA,UACA,SACA,sBACiC;AACjC,UAAM,EAAE,aAAa,OAAO,IAAI;AAEhC,UAAM,EAAE,kBAAkB,aAAa,IAAI,MAAM;AAAA,MAC/C,EAAE,sBAAsB,SAAS,OAAO,SAAS,UAAU,OAAO,SAAS;AAAA,MAC3E;AAAA,IACF;AAEA,UAAM,gBACJ,kBAAkB,QAAS,SAAS,QAAsC;AAE5E,QAAI;AACF,YAAM,SAAS,KAAK,aAAa,QAAQ,UAAU,gBAAgB;AAEnE,YAAM,WAAW,MAAM,KAAK,YAAY,QAAQ,QAAQ,eAAe,WAAW;AAElF,YAAM,aAAa,KAAK,kBAAkB,QAAQ;AAClD,YAAM,cAAc,KAAK,kBAAkB,QAAQ;AAEnD,aAAO,qBAAqB;AAAA,QAC1B;AAAA,QACA,SAAS,OAAO;AAAA,QAChB;AAAA,QACA;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,oBAAoB,OAAO;AAAA,QAC/B,WAAW;AAAA,QACX,aAAa,EAAE,QAAQ,OAAO,OAAO;AAAA,QACrC,KAAK,KAAK,OAAO;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF;AAsDF;","names":[]}
@@ -9,14 +9,14 @@ import {
9
9
  createAISDKRequestBodySummary,
10
10
  createStreamTransformer,
11
11
  mapToolChoice
12
- } from "./chunk-3JJ7OXMW.js";
12
+ } from "./chunk-X3RVS75R.js";
13
13
  import {
14
14
  VERSION,
15
15
  convertToAISDKError,
16
16
  getProviderName,
17
17
  normalizeHeaders,
18
18
  sapAILanguageModelProviderOptions
19
- } from "./chunk-JV2ULRVE.js";
19
+ } from "./chunk-U5TGXMXL.js";
20
20
 
21
21
  // src/base-language-model-strategy.ts
22
22
  import { parseProviderOptions } from "@ai-sdk/provider-utils";
@@ -181,4 +181,4 @@ var BaseLanguageModelStrategy = class {
181
181
  export {
182
182
  BaseLanguageModelStrategy
183
183
  };
184
- //# sourceMappingURL=chunk-CXZSTU4M.js.map
184
+ //# sourceMappingURL=chunk-ZTTUNOQ4.js.map
@@ -0,0 +1,58 @@
1
+ import {createRequire as __createRequire} from 'module';var require=__createRequire(import.meta.url);
2
+ import {
3
+ BaseEmbeddingModelStrategy
4
+ } from "./chunk-YWOWXJGS.js";
5
+ import {
6
+ buildModelDeployment,
7
+ hasKeys,
8
+ normalizeEmbedding
9
+ } from "./chunk-X3RVS75R.js";
10
+ import {
11
+ deepMerge
12
+ } from "./chunk-U5TGXMXL.js";
13
+
14
+ // src/foundation-models-embedding-model-strategy.ts
15
+ var FoundationModelsEmbeddingModelStrategy = class extends BaseEmbeddingModelStrategy {
16
+ ClientClass;
17
+ requestContext;
18
+ constructor(ClientClass) {
19
+ super();
20
+ this.ClientClass = ClientClass;
21
+ }
22
+ createClient(config, settings, embeddingOptions) {
23
+ this.requestContext = { embeddingOptions, settings };
24
+ return new this.ClientClass(
25
+ buildModelDeployment(config, settings.modelVersion),
26
+ config.destination
27
+ );
28
+ }
29
+ async executeCall(client, values, _embeddingType, abortSignal) {
30
+ const request = this.buildRequest(values, this.requestContext);
31
+ return client.run(request, abortSignal ? { signal: abortSignal } : void 0);
32
+ }
33
+ extractEmbeddings(response) {
34
+ const embeddingData = response._data.data;
35
+ const sortedEmbeddings = embeddingData.slice().sort((a, b) => a.index - b.index);
36
+ return sortedEmbeddings.map((item) => normalizeEmbedding(item.embedding));
37
+ }
38
+ extractTokenCount(response) {
39
+ return response._data.usage.total_tokens;
40
+ }
41
+ getUrl() {
42
+ return "sap-ai:foundation-models/embeddings";
43
+ }
44
+ buildRequest(values, context) {
45
+ const mergedParams = deepMerge(
46
+ context?.settings.modelParams,
47
+ context?.embeddingOptions?.modelParams
48
+ );
49
+ return {
50
+ input: values,
51
+ ...hasKeys(mergedParams) ? mergedParams : {}
52
+ };
53
+ }
54
+ };
55
+ export {
56
+ FoundationModelsEmbeddingModelStrategy
57
+ };
58
+ //# sourceMappingURL=foundation-models-embedding-model-strategy-3AL3KDCE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/foundation-models-embedding-model-strategy.ts"],"sourcesContent":["/** Foundation Models embedding model strategy using `@sap-ai-sdk/foundation-models`. */\nimport type { EmbeddingModelV3Embedding } from \"@ai-sdk/provider\";\nimport type {\n AzureOpenAiEmbeddingClient,\n AzureOpenAiEmbeddingParameters,\n AzureOpenAiEmbeddingResponse,\n} from \"@sap-ai-sdk/foundation-models\";\n\nimport type { SAPAIEmbeddingSettings } from \"./sap-ai-settings.js\";\nimport type { EmbeddingModelStrategyConfig } from \"./sap-ai-strategy.js\";\nimport type { EmbeddingProviderOptions } from \"./strategy-utils.js\";\n\nimport { BaseEmbeddingModelStrategy } from \"./base-embedding-model-strategy.js\";\nimport { deepMerge } from \"./deep-merge.js\";\nimport { buildModelDeployment, hasKeys, normalizeEmbedding } from \"./strategy-utils.js\";\n\n/**\n * Request context passed from createClient to executeCall.\n * @internal\n */\ninterface FMEmbeddingRequestContext {\n embeddingOptions: EmbeddingProviderOptions | undefined;\n settings: SAPAIEmbeddingSettings;\n}\n\n/** @internal */\ntype FoundationModelsEmbeddingClientClass = typeof AzureOpenAiEmbeddingClient;\n\n/**\n * Embedding model strategy for the Foundation Models API.\n *\n * Provides direct access to Azure OpenAI embedding models.\n * @internal\n */\nexport class FoundationModelsEmbeddingModelStrategy extends BaseEmbeddingModelStrategy<\n AzureOpenAiEmbeddingClient,\n AzureOpenAiEmbeddingResponse\n> {\n private readonly ClientClass: FoundationModelsEmbeddingClientClass;\n private requestContext: FMEmbeddingRequestContext | undefined;\n\n constructor(ClientClass: FoundationModelsEmbeddingClientClass) {\n super();\n this.ClientClass = ClientClass;\n }\n\n protected createClient(\n config: EmbeddingModelStrategyConfig,\n settings: SAPAIEmbeddingSettings,\n embeddingOptions: EmbeddingProviderOptions | undefined,\n ): AzureOpenAiEmbeddingClient {\n this.requestContext = { embeddingOptions, settings };\n return new this.ClientClass(\n buildModelDeployment(config, settings.modelVersion),\n config.destination,\n );\n }\n\n protected async executeCall(\n client: AzureOpenAiEmbeddingClient,\n values: string[],\n _embeddingType: unknown,\n abortSignal: AbortSignal | undefined,\n ): Promise<AzureOpenAiEmbeddingResponse> {\n const request = this.buildRequest(values, this.requestContext);\n return client.run(request, abortSignal ? { signal: abortSignal } : undefined);\n }\n\n protected extractEmbeddings(response: AzureOpenAiEmbeddingResponse): EmbeddingModelV3Embedding[] {\n // SDK types include `& Record<string, any>` which requires explicit extraction\n const embeddingData = response._data.data;\n const sortedEmbeddings = embeddingData.slice().sort((a, b) => a.index - b.index);\n return sortedEmbeddings.map((item) => normalizeEmbedding(item.embedding as number[]));\n }\n\n protected extractTokenCount(response: AzureOpenAiEmbeddingResponse): number {\n return response._data.usage.total_tokens;\n }\n\n protected getUrl(): string {\n return \"sap-ai:foundation-models/embeddings\";\n }\n\n private buildRequest(\n values: string[],\n context: FMEmbeddingRequestContext | undefined,\n ): AzureOpenAiEmbeddingParameters {\n const mergedParams = deepMerge(\n context?.settings.modelParams as Record<string, unknown> | undefined,\n context?.embeddingOptions?.modelParams,\n );\n\n return {\n input: values,\n ...(hasKeys(mergedParams) ? mergedParams : {}),\n } as AzureOpenAiEmbeddingParameters;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAkCO,IAAM,yCAAN,cAAqD,2BAG1D;AAAA,EACiB;AAAA,EACT;AAAA,EAER,YAAY,aAAmD;AAC7D,UAAM;AACN,SAAK,cAAc;AAAA,EACrB;AAAA,EAEU,aACR,QACA,UACA,kBAC4B;AAC5B,SAAK,iBAAiB,EAAE,kBAAkB,SAAS;AACnD,WAAO,IAAI,KAAK;AAAA,MACd,qBAAqB,QAAQ,SAAS,YAAY;AAAA,MAClD,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAgB,YACd,QACA,QACA,gBACA,aACuC;AACvC,UAAM,UAAU,KAAK,aAAa,QAAQ,KAAK,cAAc;AAC7D,WAAO,OAAO,IAAI,SAAS,cAAc,EAAE,QAAQ,YAAY,IAAI,MAAS;AAAA,EAC9E;AAAA,EAEU,kBAAkB,UAAqE;AAE/F,UAAM,gBAAgB,SAAS,MAAM;AACrC,UAAM,mBAAmB,cAAc,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC/E,WAAO,iBAAiB,IAAI,CAAC,SAAS,mBAAmB,KAAK,SAAqB,CAAC;AAAA,EACtF;AAAA,EAEU,kBAAkB,UAAgD;AAC1E,WAAO,SAAS,MAAM,MAAM;AAAA,EAC9B;AAAA,EAEU,SAAiB;AACzB,WAAO;AAAA,EACT;AAAA,EAEQ,aACN,QACA,SACgC;AAChC,UAAM,eAAe;AAAA,MACnB,SAAS,SAAS;AAAA,MAClB,SAAS,kBAAkB;AAAA,IAC7B;AAEA,WAAO;AAAA,MACL,OAAO;AAAA,MACP,GAAI,QAAQ,YAAY,IAAI,eAAe,CAAC;AAAA,IAC9C;AAAA,EACF;AACF;","names":[]}
@@ -1,14 +1,14 @@
1
1
  import {createRequire as __createRequire} from 'module';var require=__createRequire(import.meta.url);
2
2
  import {
3
3
  BaseLanguageModelStrategy
4
- } from "./chunk-CXZSTU4M.js";
4
+ } from "./chunk-ZTTUNOQ4.js";
5
5
  import "./chunk-SD6CRCHX.js";
6
6
  import {
7
7
  buildModelDeployment,
8
8
  convertResponseFormat,
9
9
  convertToolsToSAPFormat
10
- } from "./chunk-3JJ7OXMW.js";
11
- import "./chunk-JV2ULRVE.js";
10
+ } from "./chunk-X3RVS75R.js";
11
+ import "./chunk-U5TGXMXL.js";
12
12
 
13
13
  // src/foundation-models-language-model-strategy.ts
14
14
  var FOUNDATION_MODELS_PARAM_MAPPINGS = [
@@ -84,4 +84,4 @@ var FoundationModelsLanguageModelStrategy = class extends BaseLanguageModelStrat
84
84
  export {
85
85
  FoundationModelsLanguageModelStrategy
86
86
  };
87
- //# sourceMappingURL=foundation-models-language-model-strategy-ZCRPVWAV.js.map
87
+ //# sourceMappingURL=foundation-models-language-model-strategy-X6RMOTAL.js.map
package/dist/index.cjs CHANGED
@@ -323,78 +323,6 @@ var init_sap_ai_provider_options = __esm({
323
323
  }
324
324
  });
325
325
 
326
- // src/deep-merge.ts
327
- function deepMerge(...sources) {
328
- return mergeInternal(sources);
329
- }
330
- function cloneDeep(obj, seen, depth) {
331
- if (depth > MAX_DEPTH) {
332
- throw new Error("Maximum merge depth exceeded");
333
- }
334
- if (seen.has(obj)) {
335
- throw new Error("Circular reference detected during deep merge");
336
- }
337
- seen.add(obj);
338
- const result = {};
339
- for (const key of Object.keys(obj)) {
340
- if (!isSafeKey(key)) continue;
341
- const value = obj[key];
342
- result[key] = isPlainObject(value) ? cloneDeep(value, seen, depth + 1) : value;
343
- }
344
- return result;
345
- }
346
- function isPlainObject(value) {
347
- if (value === null || typeof value !== "object") return false;
348
- const proto = Object.getPrototypeOf(value);
349
- return proto === Object.prototype || proto === null;
350
- }
351
- function isSafeKey(key) {
352
- return !DANGEROUS_KEYS.has(key);
353
- }
354
- function mergeInternal(sources) {
355
- let result = {};
356
- for (const source of sources) {
357
- if (source == null) continue;
358
- result = mergeTwo(result, source, /* @__PURE__ */ new WeakSet(), 0);
359
- }
360
- return result;
361
- }
362
- function mergeTwo(target, source, seen, depth) {
363
- if (depth > MAX_DEPTH) {
364
- throw new Error("Maximum merge depth exceeded");
365
- }
366
- if (seen.has(source)) {
367
- throw new Error("Circular reference detected during deep merge");
368
- }
369
- seen.add(source);
370
- for (const key of Object.keys(source)) {
371
- if (!isSafeKey(key)) continue;
372
- const sourceValue = source[key];
373
- const targetValue = target[key];
374
- if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
375
- target[key] = mergeTwo(
376
- cloneDeep(targetValue, /* @__PURE__ */ new WeakSet(), depth + 1),
377
- sourceValue,
378
- seen,
379
- depth + 1
380
- );
381
- } else if (isPlainObject(sourceValue)) {
382
- target[key] = cloneDeep(sourceValue, seen, depth + 1);
383
- } else {
384
- target[key] = sourceValue;
385
- }
386
- }
387
- return target;
388
- }
389
- var DANGEROUS_KEYS, MAX_DEPTH;
390
- var init_deep_merge = __esm({
391
- "src/deep-merge.ts"() {
392
- "use strict";
393
- DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
394
- MAX_DEPTH = 100;
395
- }
396
- });
397
-
398
326
  // node_modules/@sap-cloud-sdk/util/dist/array.js
399
327
  var require_array = __commonJS({
400
328
  "node_modules/@sap-cloud-sdk/util/dist/array.js"(exports2) {
@@ -30634,6 +30562,78 @@ The model's response was blocked by content safety filters. Try a different prom
30634
30562
  }
30635
30563
  });
30636
30564
 
30565
+ // src/deep-merge.ts
30566
+ function deepMerge(...sources) {
30567
+ return mergeInternal(sources);
30568
+ }
30569
+ function cloneDeep(obj, seen, depth) {
30570
+ if (depth > MAX_DEPTH) {
30571
+ throw new Error("Maximum merge depth exceeded");
30572
+ }
30573
+ if (seen.has(obj)) {
30574
+ throw new Error("Circular reference detected during deep merge");
30575
+ }
30576
+ seen.add(obj);
30577
+ const result = {};
30578
+ for (const key of Object.keys(obj)) {
30579
+ if (!isSafeKey(key)) continue;
30580
+ const value = obj[key];
30581
+ result[key] = isPlainObject(value) ? cloneDeep(value, seen, depth + 1) : value;
30582
+ }
30583
+ return result;
30584
+ }
30585
+ function isPlainObject(value) {
30586
+ if (value === null || typeof value !== "object") return false;
30587
+ const proto = Object.getPrototypeOf(value);
30588
+ return proto === Object.prototype || proto === null;
30589
+ }
30590
+ function isSafeKey(key) {
30591
+ return !DANGEROUS_KEYS.has(key);
30592
+ }
30593
+ function mergeInternal(sources) {
30594
+ let result = {};
30595
+ for (const source of sources) {
30596
+ if (source == null) continue;
30597
+ result = mergeTwo(result, source, /* @__PURE__ */ new WeakSet(), 0);
30598
+ }
30599
+ return result;
30600
+ }
30601
+ function mergeTwo(target, source, seen, depth) {
30602
+ if (depth > MAX_DEPTH) {
30603
+ throw new Error("Maximum merge depth exceeded");
30604
+ }
30605
+ if (seen.has(source)) {
30606
+ throw new Error("Circular reference detected during deep merge");
30607
+ }
30608
+ seen.add(source);
30609
+ for (const key of Object.keys(source)) {
30610
+ if (!isSafeKey(key)) continue;
30611
+ const sourceValue = source[key];
30612
+ const targetValue = target[key];
30613
+ if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
30614
+ target[key] = mergeTwo(
30615
+ cloneDeep(targetValue, /* @__PURE__ */ new WeakSet(), depth + 1),
30616
+ sourceValue,
30617
+ seen,
30618
+ depth + 1
30619
+ );
30620
+ } else if (isPlainObject(sourceValue)) {
30621
+ target[key] = cloneDeep(sourceValue, seen, depth + 1);
30622
+ } else {
30623
+ target[key] = sourceValue;
30624
+ }
30625
+ }
30626
+ return target;
30627
+ }
30628
+ var DANGEROUS_KEYS, MAX_DEPTH;
30629
+ var init_deep_merge = __esm({
30630
+ "src/deep-merge.ts"() {
30631
+ "use strict";
30632
+ DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
30633
+ MAX_DEPTH = 100;
30634
+ }
30635
+ });
30636
+
30637
30637
  // src/strategy-utils.ts
30638
30638
  function applyParameterOverrides(modelParams, options, sapModelParams, settingsModelParams, mappings) {
30639
30639
  for (const mapping of mappings) {
@@ -31260,72 +31260,110 @@ var VERSION;
31260
31260
  var init_version = __esm({
31261
31261
  "src/version.ts"() {
31262
31262
  "use strict";
31263
- VERSION = true ? "4.4.15" : "0.0.0-test";
31263
+ VERSION = true ? "4.4.16" : "0.0.0-test";
31264
31264
  }
31265
31265
  });
31266
31266
 
31267
- // src/foundation-models-embedding-model-strategy.ts
31268
- var foundation_models_embedding_model_strategy_exports = {};
31269
- __export(foundation_models_embedding_model_strategy_exports, {
31270
- FoundationModelsEmbeddingModelStrategy: () => FoundationModelsEmbeddingModelStrategy
31271
- });
31272
- var FoundationModelsEmbeddingModelStrategy;
31273
- var init_foundation_models_embedding_model_strategy = __esm({
31274
- "src/foundation-models-embedding-model-strategy.ts"() {
31267
+ // src/base-embedding-model-strategy.ts
31268
+ var BaseEmbeddingModelStrategy;
31269
+ var init_base_embedding_model_strategy = __esm({
31270
+ "src/base-embedding-model-strategy.ts"() {
31275
31271
  "use strict";
31276
- init_deep_merge();
31277
31272
  init_sap_ai_error();
31278
31273
  init_strategy_utils();
31279
31274
  init_version();
31280
- FoundationModelsEmbeddingModelStrategy = class {
31281
- ClientClass;
31282
- constructor(ClientClass) {
31283
- this.ClientClass = ClientClass;
31284
- }
31275
+ BaseEmbeddingModelStrategy = class {
31276
+ /**
31277
+ * Template method implementing the shared embedding algorithm.
31278
+ * @param config - Strategy configuration.
31279
+ * @param settings - Embedding model settings.
31280
+ * @param options - AI SDK call options.
31281
+ * @param maxEmbeddingsPerCall - Maximum embeddings per call.
31282
+ * @returns Complete embedding result for AI SDK.
31283
+ * @internal
31284
+ */
31285
31285
  async doEmbed(config, settings, options, maxEmbeddingsPerCall) {
31286
31286
  const { abortSignal, values } = options;
31287
31287
  const { embeddingOptions, providerName } = await prepareEmbeddingCall(
31288
31288
  { maxEmbeddingsPerCall, modelId: config.modelId, provider: config.provider },
31289
31289
  options
31290
31290
  );
31291
+ const embeddingType = embeddingOptions?.type ?? settings.type ?? "text";
31291
31292
  try {
31292
- const client = this.createClient(config, settings.modelVersion);
31293
- const request = this.buildRequest(values, settings, embeddingOptions);
31294
- const response = await client.run(request, abortSignal ? { signal: abortSignal } : void 0);
31295
- const embeddingData = response.getEmbeddings();
31296
- const tokenUsage = response._data.usage;
31297
- const embeddings = embeddingData.map(
31298
- (embedding) => normalizeEmbedding(embedding)
31299
- );
31293
+ const client = this.createClient(config, settings, embeddingOptions);
31294
+ const response = await this.executeCall(client, values, embeddingType, abortSignal);
31295
+ const embeddings = this.extractEmbeddings(response);
31296
+ const totalTokens = this.extractTokenCount(response);
31300
31297
  return buildEmbeddingResult({
31301
31298
  embeddings,
31302
31299
  modelId: config.modelId,
31303
31300
  providerName,
31304
- totalTokens: tokenUsage.total_tokens,
31301
+ totalTokens,
31305
31302
  version: VERSION
31306
31303
  });
31307
31304
  } catch (error) {
31308
31305
  throw convertToAISDKError(error, {
31309
31306
  operation: "doEmbed",
31310
31307
  requestBody: { values: values.length },
31311
- url: "sap-ai:foundation-models/embeddings"
31308
+ url: this.getUrl()
31312
31309
  });
31313
31310
  }
31314
31311
  }
31315
- buildRequest(values, settings, embeddingOptions) {
31312
+ };
31313
+ }
31314
+ });
31315
+
31316
+ // src/foundation-models-embedding-model-strategy.ts
31317
+ var foundation_models_embedding_model_strategy_exports = {};
31318
+ __export(foundation_models_embedding_model_strategy_exports, {
31319
+ FoundationModelsEmbeddingModelStrategy: () => FoundationModelsEmbeddingModelStrategy
31320
+ });
31321
+ var FoundationModelsEmbeddingModelStrategy;
31322
+ var init_foundation_models_embedding_model_strategy = __esm({
31323
+ "src/foundation-models-embedding-model-strategy.ts"() {
31324
+ "use strict";
31325
+ init_base_embedding_model_strategy();
31326
+ init_deep_merge();
31327
+ init_strategy_utils();
31328
+ FoundationModelsEmbeddingModelStrategy = class extends BaseEmbeddingModelStrategy {
31329
+ ClientClass;
31330
+ requestContext;
31331
+ constructor(ClientClass) {
31332
+ super();
31333
+ this.ClientClass = ClientClass;
31334
+ }
31335
+ createClient(config, settings, embeddingOptions) {
31336
+ this.requestContext = { embeddingOptions, settings };
31337
+ return new this.ClientClass(
31338
+ buildModelDeployment(config, settings.modelVersion),
31339
+ config.destination
31340
+ );
31341
+ }
31342
+ async executeCall(client, values, _embeddingType, abortSignal) {
31343
+ const request = this.buildRequest(values, this.requestContext);
31344
+ return client.run(request, abortSignal ? { signal: abortSignal } : void 0);
31345
+ }
31346
+ extractEmbeddings(response) {
31347
+ const embeddingData = response._data.data;
31348
+ const sortedEmbeddings = embeddingData.slice().sort((a, b) => a.index - b.index);
31349
+ return sortedEmbeddings.map((item) => normalizeEmbedding(item.embedding));
31350
+ }
31351
+ extractTokenCount(response) {
31352
+ return response._data.usage.total_tokens;
31353
+ }
31354
+ getUrl() {
31355
+ return "sap-ai:foundation-models/embeddings";
31356
+ }
31357
+ buildRequest(values, context) {
31316
31358
  const mergedParams = deepMerge(
31317
- settings.modelParams,
31318
- embeddingOptions?.modelParams
31359
+ context?.settings.modelParams,
31360
+ context?.embeddingOptions?.modelParams
31319
31361
  );
31320
31362
  return {
31321
31363
  input: values,
31322
31364
  ...hasKeys(mergedParams) ? mergedParams : {}
31323
31365
  };
31324
31366
  }
31325
- createClient(config, modelVersion) {
31326
- const modelDeployment = buildModelDeployment(config, modelVersion);
31327
- return new this.ClientClass(modelDeployment, config.destination);
31328
- }
31329
31367
  };
31330
31368
  }
31331
31369
  });
@@ -31339,70 +31377,51 @@ var OrchestrationEmbeddingModelStrategy;
31339
31377
  var init_orchestration_embedding_model_strategy = __esm({
31340
31378
  "src/orchestration-embedding-model-strategy.ts"() {
31341
31379
  "use strict";
31380
+ init_base_embedding_model_strategy();
31342
31381
  init_deep_merge();
31343
- init_sap_ai_error();
31344
31382
  init_strategy_utils();
31345
- init_version();
31346
- OrchestrationEmbeddingModelStrategy = class {
31383
+ OrchestrationEmbeddingModelStrategy = class extends BaseEmbeddingModelStrategy {
31347
31384
  ClientClass;
31348
31385
  constructor(ClientClass) {
31386
+ super();
31349
31387
  this.ClientClass = ClientClass;
31350
31388
  }
31351
- async doEmbed(config, settings, options, maxEmbeddingsPerCall) {
31352
- const { abortSignal, values } = options;
31353
- const { embeddingOptions, providerName } = await prepareEmbeddingCall(
31354
- { maxEmbeddingsPerCall, modelId: config.modelId, provider: config.provider },
31355
- options
31389
+ createClient(config, settings, embeddingOptions) {
31390
+ const mergedParams = deepMerge(
31391
+ settings.modelParams ?? {},
31392
+ embeddingOptions?.modelParams ?? {}
31356
31393
  );
31357
- const embeddingType = embeddingOptions?.type ?? settings.type ?? "text";
31358
- try {
31359
- const client = this.createClient(
31360
- config,
31361
- settings.modelParams,
31362
- embeddingOptions?.modelParams,
31363
- settings.modelVersion,
31364
- settings.masking
31365
- );
31366
- const response = await client.embed(
31367
- { input: values, type: embeddingType },
31368
- abortSignal ? { signal: abortSignal } : void 0
31369
- );
31370
- const embeddingData = response.getEmbeddings();
31371
- const tokenUsage = response.getTokenUsage();
31372
- const sortedEmbeddings = [...embeddingData].sort((a, b) => a.index - b.index);
31373
- const embeddings = sortedEmbeddings.map(
31374
- (data) => normalizeEmbedding(data.embedding)
31375
- );
31376
- return buildEmbeddingResult({
31377
- embeddings,
31378
- modelId: config.modelId,
31379
- providerName,
31380
- totalTokens: tokenUsage.total_tokens,
31381
- version: VERSION
31382
- });
31383
- } catch (error) {
31384
- throw convertToAISDKError(error, {
31385
- operation: "doEmbed",
31386
- requestBody: { values: values.length },
31387
- url: "sap-ai:orchestration/embeddings"
31388
- });
31389
- }
31390
- }
31391
- createClient(config, settingsModelParams, perCallModelParams, modelVersion, masking) {
31392
- const mergedParams = deepMerge(settingsModelParams ?? {}, perCallModelParams ?? {});
31393
31394
  const embeddingConfig = {
31394
31395
  model: {
31395
31396
  name: config.modelId,
31396
31397
  ...hasKeys(mergedParams) ? { params: mergedParams } : {},
31397
- ...modelVersion ? { version: modelVersion } : {}
31398
+ ...settings.modelVersion ? { version: settings.modelVersion } : {}
31398
31399
  }
31399
31400
  };
31400
31401
  const moduleConfig = {
31401
31402
  embeddings: embeddingConfig,
31402
- ...masking && hasKeys(masking) ? { masking } : {}
31403
+ ...settings.masking && hasKeys(settings.masking) ? { masking: settings.masking } : {}
31403
31404
  };
31404
31405
  return new this.ClientClass(moduleConfig, config.deploymentConfig, config.destination);
31405
31406
  }
31407
+ async executeCall(client, values, embeddingType, abortSignal) {
31408
+ return client.embed(
31409
+ { input: values, type: embeddingType },
31410
+ abortSignal ? { signal: abortSignal } : void 0
31411
+ );
31412
+ }
31413
+ extractEmbeddings(response) {
31414
+ const embeddingData = response.getEmbeddings();
31415
+ const sortedEmbeddings = [...embeddingData].sort((a, b) => a.index - b.index);
31416
+ return sortedEmbeddings.map((data) => normalizeEmbedding(data.embedding));
31417
+ }
31418
+ extractTokenCount(response) {
31419
+ const tokenUsage = response.getTokenUsage();
31420
+ return tokenUsage.total_tokens;
31421
+ }
31422
+ getUrl() {
31423
+ return "sap-ai:orchestration/embeddings";
31424
+ }
31406
31425
  };
31407
31426
  }
31408
31427
  });