@jerome-benoit/sap-ai-provider-v2 4.4.1 → 4.4.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.
Files changed (31) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-N3IRJKV2.js → chunk-3PATA44Z.js} +40 -5
  3. package/dist/chunk-3PATA44Z.js.map +1 -0
  4. package/dist/{chunk-6SUOKHXD.js → chunk-6RYKBAYB.js} +68 -6
  5. package/dist/chunk-6RYKBAYB.js.map +1 -0
  6. package/dist/{chunk-TY46HBVE.js → chunk-QO36FSA3.js} +4 -10
  7. package/dist/chunk-QO36FSA3.js.map +1 -0
  8. package/dist/{foundation-models-embedding-model-strategy-AVAK533Z.js → foundation-models-embedding-model-strategy-HXF3JQP5.js} +15 -37
  9. package/dist/foundation-models-embedding-model-strategy-HXF3JQP5.js.map +1 -0
  10. package/dist/{foundation-models-language-model-strategy-PUANSTGO.js → foundation-models-language-model-strategy-U47ATXIF.js} +14 -40
  11. package/dist/foundation-models-language-model-strategy-U47ATXIF.js.map +1 -0
  12. package/dist/index.cjs +188 -224
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +16 -14
  15. package/dist/index.d.ts +16 -14
  16. package/dist/index.js +7 -9
  17. package/dist/index.js.map +1 -1
  18. package/dist/{orchestration-embedding-model-strategy-6EI454PR.js → orchestration-embedding-model-strategy-RHNYULEI.js} +10 -9
  19. package/dist/orchestration-embedding-model-strategy-RHNYULEI.js.map +1 -0
  20. package/dist/{orchestration-language-model-strategy-JZX7CLO3.js → orchestration-language-model-strategy-7W4CC2NK.js} +10 -37
  21. package/dist/orchestration-language-model-strategy-7W4CC2NK.js.map +1 -0
  22. package/package.json +3 -3
  23. package/dist/chunk-6SUOKHXD.js.map +0 -1
  24. package/dist/chunk-F3R75MRP.js +0 -65
  25. package/dist/chunk-F3R75MRP.js.map +0 -1
  26. package/dist/chunk-N3IRJKV2.js.map +0 -1
  27. package/dist/chunk-TY46HBVE.js.map +0 -1
  28. package/dist/foundation-models-embedding-model-strategy-AVAK533Z.js.map +0 -1
  29. package/dist/foundation-models-language-model-strategy-PUANSTGO.js.map +0 -1
  30. package/dist/orchestration-embedding-model-strategy-6EI454PR.js.map +0 -1
  31. package/dist/orchestration-language-model-strategy-JZX7CLO3.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SAP AI Core Provider for Vercel AI SDK
2
2
 
3
- [![npm](https://img.shields.io/npm/v/@jerome-benoit/sap-ai-provider/latest?label=npm&color=blue)](https://www.npmjs.com/package/@jerome-benoit/sap-ai-provider)
3
+ [![npm](https://img.shields.io/npm/v/@jerome-benoit/sap-ai-provider-v2/latest?label=npm&color=blue)](https://www.npmjs.com/package/@jerome-benoit/sap-ai-provider-v2)
4
4
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
5
5
  [![Vercel AI SDK](https://img.shields.io/badge/Vercel%20AI%20SDK-5.0+-black.svg)](https://sdk.vercel.ai/docs)
6
6
  [![Language Model](https://img.shields.io/badge/Language%20Model-V2-orange.svg)](https://sdk.vercel.ai/docs/ai-sdk-core/provider-management)
@@ -1,4 +1,5 @@
1
1
  // src/strategy-utils.ts
2
+ import { z } from "zod";
2
3
  var StreamIdGenerator = class {
3
4
  /**
4
5
  * Generates a unique response ID.
@@ -26,10 +27,17 @@ function applyParameterOverrides(modelParams, options, sapModelParams, settingsM
26
27
  }
27
28
  }
28
29
  }
29
- function buildModelDeployment(config) {
30
+ function buildModelDeployment(config, modelVersion) {
30
31
  const deploymentConfig = config.deploymentConfig;
32
+ if ("deploymentId" in deploymentConfig) {
33
+ return { deploymentId: deploymentConfig.deploymentId };
34
+ }
31
35
  const resourceGroup = "resourceGroup" in deploymentConfig ? deploymentConfig.resourceGroup : void 0;
32
- return resourceGroup ? { modelName: config.modelId, resourceGroup } : { modelName: config.modelId };
36
+ return {
37
+ modelName: config.modelId,
38
+ ...modelVersion && { modelVersion },
39
+ ...resourceGroup && { resourceGroup }
40
+ };
33
41
  }
34
42
  function buildSAPToolParameters(schema) {
35
43
  const schemaType = schema.type;
@@ -94,6 +102,34 @@ function createInitialStreamState() {
94
102
  }
95
103
  };
96
104
  }
105
+ function extractToolParameters(tool) {
106
+ const inputSchema = tool.inputSchema;
107
+ const toolWithParams = tool;
108
+ if (toolWithParams.parameters && isZodSchema(toolWithParams.parameters)) {
109
+ try {
110
+ const jsonSchema = z.toJSONSchema(toolWithParams.parameters);
111
+ const schemaRecord = jsonSchema;
112
+ delete schemaRecord.$schema;
113
+ return { parameters: buildSAPToolParameters(schemaRecord) };
114
+ } catch (error) {
115
+ return {
116
+ parameters: buildSAPToolParameters({}),
117
+ warning: {
118
+ details: `Failed to convert tool Zod schema: ${error instanceof Error ? error.message : String(error)}. Falling back to empty object schema.`,
119
+ feature: `tool schema conversion for ${tool.name}`,
120
+ type: "unsupported"
121
+ }
122
+ };
123
+ }
124
+ }
125
+ if (inputSchema && Object.keys(inputSchema).length > 0) {
126
+ const hasProperties = inputSchema.properties && typeof inputSchema.properties === "object" && Object.keys(inputSchema.properties).length > 0;
127
+ if (hasProperties) {
128
+ return { parameters: buildSAPToolParameters(inputSchema) };
129
+ }
130
+ }
131
+ return { parameters: buildSAPToolParameters({}) };
132
+ }
97
133
  function hasCallableParse(obj) {
98
134
  return typeof obj.parse === "function";
99
135
  }
@@ -148,11 +184,10 @@ export {
148
184
  StreamIdGenerator,
149
185
  applyParameterOverrides,
150
186
  buildModelDeployment,
151
- buildSAPToolParameters,
152
187
  createAISDKRequestBodySummary,
153
188
  createInitialStreamState,
154
- isZodSchema,
189
+ extractToolParameters,
155
190
  mapFinishReason,
156
191
  normalizeEmbedding
157
192
  };
158
- //# sourceMappingURL=chunk-N3IRJKV2.js.map
193
+ //# sourceMappingURL=chunk-3PATA44Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/strategy-utils.ts"],"sourcesContent":["/**\n * Shared utilities for SAP AI Core strategy implementations.\n *\n * Contains common functions used by both Orchestration and Foundation Models strategies\n * to avoid code duplication and ensure consistency.\n */\nimport type {\n EmbeddingModelV3Embedding,\n LanguageModelV3CallOptions,\n LanguageModelV3FinishReason,\n LanguageModelV3FunctionTool,\n SharedV3Warning,\n} from \"@ai-sdk/provider\";\nimport type { DeploymentIdConfig, ResourceGroupConfig } from \"@sap-ai-sdk/ai-api/internal.js\";\nimport type { ZodType } from \"zod\";\n\nimport { z } from \"zod\";\n\n/**\n * Base configuration for model deployment resolution.\n * Shared fields used by buildModelDeployment helper.\n * @internal\n */\nexport interface BaseModelDeploymentConfig {\n /** Deployment configuration (ID-based or resource group-based). */\n readonly deploymentConfig: DeploymentIdConfig | ResourceGroupConfig;\n /** The model identifier (e.g., 'gpt-4o', 'text-embedding-ada-002'). */\n readonly modelId: string;\n}\n\n/**\n * Result of extracting tool parameters from an AI SDK tool.\n * @internal\n */\nexport interface ExtractedToolParameters {\n /** The extracted SAP-compatible parameters. */\n readonly parameters: SAPToolParameters;\n /** Optional warning if schema conversion failed. */\n readonly warning?: SharedV3Warning;\n}\n\n/**\n * Extended function tool interface with optional parameters property.\n * @internal\n */\nexport interface FunctionToolWithParameters extends LanguageModelV3FunctionTool {\n readonly parameters?: unknown;\n}\n\n/**\n * Parameter mapping for AI SDK options → SAP model params.\n *\n * Used to map between different parameter naming conventions:\n * - AI SDK uses camelCase (e.g., `maxOutputTokens`)\n * - SAP APIs use snake_case (e.g., `max_tokens`)\n * @internal\n */\nexport interface ParamMapping {\n /** camelCase key in modelParams to read from and remove (e.g., 'maxTokens', 'topP'). */\n readonly camelCaseKey?: string;\n /** AI SDK option key (e.g., 'maxOutputTokens', 'topP'). */\n readonly optionKey?: string;\n /** Output key for SAP API (e.g., 'max_tokens', 'top_p'). */\n readonly outputKey: string;\n}\n\n/**\n * SAP-compatible tool parameters structure.\n * Must have type \"object\" as required by the SAP AI APIs.\n * @internal\n */\nexport type SAPToolParameters = Record<string, unknown> & {\n type: \"object\";\n};\n\n/**\n * State object for tracking streaming response processing.\n * @internal\n */\nexport interface StreamState {\n /** Whether a text block is currently active. */\n activeText: boolean;\n /** The finish reason for the response. */\n finishReason: LanguageModelV3FinishReason;\n /** Whether this is the first chunk in the stream. */\n isFirstChunk: boolean;\n /** Token usage tracking. */\n usage: {\n inputTokens: {\n cacheRead: number | undefined;\n cacheWrite: number | undefined;\n noCache: number | undefined;\n total: number | undefined;\n };\n outputTokens: {\n reasoning: number | undefined;\n text: number | undefined;\n total: number | undefined;\n };\n };\n}\n\n/**\n * Generates unique IDs for streaming response parts.\n *\n * Uses crypto.randomUUID() for cryptographically secure unique identifiers.\n * @internal\n */\nexport class StreamIdGenerator {\n /**\n * Generates a unique response ID.\n * @returns A UUID string for identifying the response.\n */\n generateResponseId(): string {\n return crypto.randomUUID();\n }\n\n /**\n * Generates a unique text block ID.\n * @returns A UUID string for identifying a text block.\n */\n generateTextBlockId(): string {\n return crypto.randomUUID();\n }\n}\n\n/**\n * Applies parameter overrides from AI SDK options and modelParams.\n * @param modelParams - The model parameters object to modify.\n * @param options - AI SDK call options.\n * @param sapModelParams - Provider options model params.\n * @param settingsModelParams - Settings model params.\n * @param mappings - Parameter mappings for this strategy.\n * @internal\n */\nexport function applyParameterOverrides(\n modelParams: Record<string, unknown>,\n options: Record<string, unknown>,\n sapModelParams: Record<string, unknown> | undefined,\n settingsModelParams: Record<string, unknown> | undefined,\n mappings: readonly ParamMapping[],\n): void {\n for (const mapping of mappings) {\n const value =\n (mapping.optionKey ? options[mapping.optionKey] : undefined) ??\n (mapping.camelCaseKey ? sapModelParams?.[mapping.camelCaseKey] : undefined) ??\n (mapping.camelCaseKey ? settingsModelParams?.[mapping.camelCaseKey] : undefined);\n\n if (value !== undefined) {\n modelParams[mapping.outputKey] = value;\n }\n\n if (mapping.camelCaseKey && mapping.camelCaseKey !== mapping.outputKey) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete modelParams[mapping.camelCaseKey];\n }\n }\n}\n\n/**\n * Builds a ModelDeployment object for the Foundation Models API SDK.\n *\n * Supports both deployment resolution strategies:\n * - Direct deploymentId: Uses the specific deployment directly\n * - Model-based: Uses modelName with optional modelVersion and resourceGroup\n * @param config - The strategy configuration containing deployment info and model ID.\n * @param modelVersion - Optional model version for model-based resolution.\n * @returns A ModelDeployment object for the Foundation Models API SDK.\n * @internal\n */\nexport function buildModelDeployment(\n config: BaseModelDeploymentConfig,\n modelVersion?: string,\n): { deploymentId: string } | { modelName: string; modelVersion?: string; resourceGroup?: string } {\n const deploymentConfig = config.deploymentConfig;\n\n // Use deploymentId directly if provided\n if (\"deploymentId\" in deploymentConfig) {\n return { deploymentId: deploymentConfig.deploymentId };\n }\n\n // Build model-based deployment with optional version and resourceGroup\n const resourceGroup =\n \"resourceGroup\" in deploymentConfig ? deploymentConfig.resourceGroup : undefined;\n\n return {\n modelName: config.modelId,\n ...(modelVersion && { modelVersion }),\n ...(resourceGroup && { resourceGroup }),\n };\n}\n\n/**\n * Builds SAP AI SDK-compatible tool parameters from a JSON schema.\n *\n * Handles edge cases:\n * - Non-object schemas are converted to empty object schemas\n * - Preserves additional schema fields (description, etc.)\n * - Validates properties and required arrays\n * @param schema - The JSON schema to convert.\n * @returns The SAP-compatible tool parameters object.\n * @internal\n */\nexport function buildSAPToolParameters(schema: Record<string, unknown>): SAPToolParameters {\n const schemaType = schema.type;\n\n // Non-object schemas are not supported - return empty object schema\n if (schemaType !== undefined && schemaType !== \"object\") {\n return {\n properties: {},\n required: [],\n type: \"object\",\n };\n }\n\n const properties =\n schema.properties && typeof schema.properties === \"object\"\n ? (schema.properties as Record<string, unknown>)\n : {};\n\n const required =\n Array.isArray(schema.required) && schema.required.every((item) => typeof item === \"string\")\n ? schema.required\n : [];\n\n // Preserve additional fields like description, additionalProperties, etc.\n const additionalFields = Object.fromEntries(\n Object.entries(schema).filter(\n ([key]) => key !== \"type\" && key !== \"properties\" && key !== \"required\",\n ),\n );\n\n return {\n properties,\n required,\n type: \"object\",\n ...additionalFields,\n };\n}\n\n/**\n * Creates a summary of Vercel AI SDK request options for error context.\n *\n * Extracts key information without including sensitive prompt data.\n * Used for debugging and error reporting.\n * @param options - The language model call options to summarize.\n * @returns An object summarizing the request for debugging.\n * @internal\n */\nexport function createAISDKRequestBodySummary(options: LanguageModelV3CallOptions): {\n hasImageParts: boolean;\n maxOutputTokens?: number;\n promptMessages: number;\n responseFormatType?: string;\n seed?: number;\n stopSequences?: number;\n temperature?: number;\n toolChoiceType?: string;\n tools: number;\n topK?: number;\n topP?: number;\n} {\n return {\n hasImageParts: options.prompt.some(\n (message) =>\n message.role === \"user\" &&\n message.content.some((part) => part.type === \"file\" && part.mediaType.startsWith(\"image/\")),\n ),\n maxOutputTokens: options.maxOutputTokens,\n promptMessages: options.prompt.length,\n responseFormatType: options.responseFormat?.type,\n seed: options.seed,\n stopSequences: options.stopSequences?.length,\n temperature: options.temperature,\n toolChoiceType: options.toolChoice?.type,\n tools: options.tools?.length ?? 0,\n topK: options.topK,\n topP: options.topP,\n };\n}\n\n/**\n * Creates the initial stream state for processing streaming responses.\n *\n * Provides consistent initial state across both Orchestration and Foundation Models strategies.\n * @returns The initial stream state object.\n * @internal\n */\nexport function createInitialStreamState(): StreamState {\n return {\n activeText: false,\n finishReason: {\n raw: undefined,\n unified: \"other\" as const,\n },\n isFirstChunk: true,\n usage: {\n inputTokens: {\n cacheRead: undefined,\n cacheWrite: undefined,\n noCache: undefined,\n total: undefined,\n },\n outputTokens: {\n reasoning: undefined,\n text: undefined,\n total: undefined,\n },\n },\n };\n}\n\n/**\n * Extracts SAP-compatible tool parameters from an AI SDK function tool.\n *\n * Handles multiple schema formats:\n * - Zod schemas (converted via z.toJSONSchema)\n * - JSON Schema objects with properties\n * - Empty/missing schemas (returns empty object schema)\n * @param tool - The AI SDK function tool to extract parameters from.\n * @returns The extracted parameters and optional warning.\n * @internal\n */\nexport function extractToolParameters(tool: LanguageModelV3FunctionTool): ExtractedToolParameters {\n const inputSchema = tool.inputSchema as Record<string, unknown> | undefined;\n const toolWithParams = tool as FunctionToolWithParameters;\n\n if (toolWithParams.parameters && isZodSchema(toolWithParams.parameters)) {\n try {\n const jsonSchema = z.toJSONSchema(toolWithParams.parameters);\n const schemaRecord = jsonSchema as Record<string, unknown>;\n delete schemaRecord.$schema;\n return { parameters: buildSAPToolParameters(schemaRecord) };\n } catch (error) {\n return {\n parameters: buildSAPToolParameters({}),\n warning: {\n details: `Failed to convert tool Zod schema: ${error instanceof Error ? error.message : String(error)}. Falling back to empty object schema.`,\n feature: `tool schema conversion for ${tool.name}`,\n type: \"unsupported\",\n },\n };\n }\n }\n\n if (inputSchema && Object.keys(inputSchema).length > 0) {\n const hasProperties =\n inputSchema.properties &&\n typeof inputSchema.properties === \"object\" &&\n Object.keys(inputSchema.properties).length > 0;\n\n if (hasProperties) {\n return { parameters: buildSAPToolParameters(inputSchema) };\n }\n }\n\n return { parameters: buildSAPToolParameters({}) };\n}\n\n/**\n * Checks if an object has a callable parse method.\n * @param obj - The object to check for a parse method.\n * @returns True if the object has a callable parse method.\n * @internal\n */\nexport function hasCallableParse(\n obj: Record<string, unknown>,\n): obj is Record<string, unknown> & { parse: (...args: unknown[]) => unknown } {\n return typeof obj.parse === \"function\";\n}\n\n/**\n * Type guard for Zod schema objects.\n *\n * Detects Zod schemas by checking for the presence of `_def` and a callable `parse` method.\n * @param obj - The object to check.\n * @returns True if the object is a Zod schema.\n * @internal\n */\nexport function isZodSchema(obj: unknown): obj is ZodType {\n if (obj === null || typeof obj !== \"object\") {\n return false;\n }\n const record = obj as Record<string, unknown>;\n return \"_def\" in record && \"parse\" in record && hasCallableParse(record);\n}\n\n/**\n * Maps provider finish reasons to Vercel AI SDK LanguageModelV3FinishReason.\n *\n * Handles various finish reason formats from different model providers:\n * - OpenAI: \"stop\", \"length\", \"tool_calls\", \"content_filter\"\n * - Anthropic: \"end_turn\", \"stop_sequence\", \"max_tokens\"\n * - Amazon: \"eos\", \"max_tokens_reached\"\n * - Others: \"error\", \"function_call\", \"tool_call\"\n * @param reason - The raw finish reason string from the provider.\n * @returns The unified finish reason with both raw and unified representations.\n * @internal\n */\nexport function mapFinishReason(reason: null | string | undefined): LanguageModelV3FinishReason {\n const raw = reason ?? undefined;\n\n if (!reason) {\n return { raw, unified: \"other\" };\n }\n\n switch (reason.toLowerCase()) {\n case \"content_filter\":\n return { raw, unified: \"content-filter\" };\n case \"end_turn\":\n case \"eos\":\n case \"stop\":\n case \"stop_sequence\":\n return { raw, unified: \"stop\" };\n case \"error\":\n return { raw, unified: \"error\" };\n case \"function_call\":\n case \"tool_call\":\n case \"tool_calls\":\n return { raw, unified: \"tool-calls\" };\n case \"length\":\n case \"max_tokens\":\n case \"max_tokens_reached\":\n return { raw, unified: \"length\" };\n default:\n return { raw, unified: \"other\" };\n }\n}\n\n/**\n * Converts SAP AI SDK embedding (number[] or base64) to Vercel AI SDK format.\n *\n * Handles both formats that can be returned by embedding APIs:\n * - Direct number arrays (most common)\n * - Base64-encoded float32 arrays (for bandwidth efficiency)\n * @param embedding - The embedding as number array or base64 string.\n * @returns The normalized embedding as a number array.\n * @internal\n */\nexport function normalizeEmbedding(embedding: number[] | string): EmbeddingModelV3Embedding {\n if (Array.isArray(embedding)) {\n return embedding;\n }\n // Base64-encoded float32 values\n const buffer = Buffer.from(embedding, \"base64\");\n const float32Array = new Float32Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.length / Float32Array.BYTES_PER_ELEMENT,\n );\n return Array.from(float32Array);\n}\n"],"mappings":"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","names":[]}
@@ -26269,7 +26269,7 @@ var require_axios = __commonJS({
26269
26269
  var isNumber = typeOfTest("number");
26270
26270
  var isObject = (thing) => thing !== null && typeof thing === "object";
26271
26271
  var isBoolean = (thing) => thing === true || thing === false;
26272
- var isPlainObject = (val) => {
26272
+ var isPlainObject2 = (val) => {
26273
26273
  if (kindOf(val) !== "object") {
26274
26274
  return false;
26275
26275
  }
@@ -26351,9 +26351,9 @@ var require_axios = __commonJS({
26351
26351
  const result = {};
26352
26352
  const assignValue = (val, key) => {
26353
26353
  const targetKey = caseless && findKey(result, key) || key;
26354
- if (isPlainObject(result[targetKey]) && isPlainObject(val)) {
26354
+ if (isPlainObject2(result[targetKey]) && isPlainObject2(val)) {
26355
26355
  result[targetKey] = merge(result[targetKey], val);
26356
- } else if (isPlainObject(val)) {
26356
+ } else if (isPlainObject2(val)) {
26357
26357
  result[targetKey] = merge({}, val);
26358
26358
  } else if (isArray(val)) {
26359
26359
  result[targetKey] = val.slice();
@@ -26585,7 +26585,7 @@ var require_axios = __commonJS({
26585
26585
  isNumber,
26586
26586
  isBoolean,
26587
26587
  isObject,
26588
- isPlainObject,
26588
+ isPlainObject: isPlainObject2,
26589
26589
  isEmptyObject,
26590
26590
  isReadableStream,
26591
26591
  isRequest,
@@ -29841,6 +29841,67 @@ var sapAIEmbeddingProviderOptions = lazySchema(
29841
29841
  )
29842
29842
  );
29843
29843
 
29844
+ // src/deep-merge.ts
29845
+ var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
29846
+ var MAX_DEPTH = 100;
29847
+ function deepMerge(...sources) {
29848
+ return mergeInternal(sources);
29849
+ }
29850
+ function cloneDeep(obj, seen, depth) {
29851
+ if (depth > MAX_DEPTH) {
29852
+ throw new Error("Maximum merge depth exceeded");
29853
+ }
29854
+ if (seen.has(obj)) {
29855
+ throw new Error("Circular reference detected during deep merge");
29856
+ }
29857
+ seen.add(obj);
29858
+ const result = {};
29859
+ for (const key of Object.keys(obj)) {
29860
+ if (!isSafeKey(key)) continue;
29861
+ const value = obj[key];
29862
+ result[key] = isPlainObject(value) ? cloneDeep(value, seen, depth + 1) : value;
29863
+ }
29864
+ return result;
29865
+ }
29866
+ function isPlainObject(value) {
29867
+ if (value === null || typeof value !== "object") return false;
29868
+ const proto = Object.getPrototypeOf(value);
29869
+ return proto === Object.prototype || proto === null;
29870
+ }
29871
+ function isSafeKey(key) {
29872
+ return !DANGEROUS_KEYS.has(key);
29873
+ }
29874
+ function mergeInternal(sources) {
29875
+ let result = {};
29876
+ for (const source of sources) {
29877
+ if (source == null) continue;
29878
+ result = mergeTwo(result, source, /* @__PURE__ */ new WeakSet(), 0);
29879
+ }
29880
+ return result;
29881
+ }
29882
+ function mergeTwo(target, source, seen, depth) {
29883
+ if (depth > MAX_DEPTH) {
29884
+ throw new Error("Maximum merge depth exceeded");
29885
+ }
29886
+ if (seen.has(source)) {
29887
+ throw new Error("Circular reference detected during deep merge");
29888
+ }
29889
+ seen.add(source);
29890
+ for (const key of Object.keys(source)) {
29891
+ if (!isSafeKey(key)) continue;
29892
+ const sourceValue = source[key];
29893
+ const targetValue = target[key];
29894
+ if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
29895
+ target[key] = mergeTwo({ ...targetValue }, sourceValue, seen, depth + 1);
29896
+ } else if (isPlainObject(sourceValue)) {
29897
+ target[key] = cloneDeep(sourceValue, seen, depth + 1);
29898
+ } else {
29899
+ target[key] = sourceValue;
29900
+ }
29901
+ }
29902
+ return target;
29903
+ }
29904
+
29844
29905
  // src/sap-ai-error.ts
29845
29906
  var import_util = __toESM(require_dist(), 1);
29846
29907
  import { APICallError, LoadAPIKeyError, NoSuchModelError } from "@ai-sdk/provider";
@@ -30313,7 +30374,7 @@ function tryExtractSAPErrorFromMessage(message) {
30313
30374
  }
30314
30375
 
30315
30376
  // src/version.ts
30316
- var VERSION = true ? "4.4.1" : "0.0.0-test";
30377
+ var VERSION = true ? "4.4.4" : "0.0.0-test";
30317
30378
 
30318
30379
  export {
30319
30380
  __toESM,
@@ -30324,6 +30385,7 @@ export {
30324
30385
  validateModelParamsWithWarnings,
30325
30386
  sapAILanguageModelProviderOptions,
30326
30387
  sapAIEmbeddingProviderOptions,
30388
+ deepMerge,
30327
30389
  require_dist,
30328
30390
  ApiSwitchError,
30329
30391
  UnsupportedFeatureError,
@@ -30364,4 +30426,4 @@ mime-types/index.js:
30364
30426
  axios/dist/node/axios.cjs:
30365
30427
  (*! Axios v1.13.4 Copyright (c) 2026 Matt Zabriskie and contributors *)
30366
30428
  */
30367
- //# sourceMappingURL=chunk-6SUOKHXD.js.map
30429
+ //# sourceMappingURL=chunk-6RYKBAYB.js.map