@jerome-benoit/sap-ai-provider 4.4.14 → 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 (28) hide show
  1. package/README.md +10 -0
  2. package/dist/{chunk-KI7PB43L.js → chunk-SD6CRCHX.js} +9 -7
  3. package/dist/chunk-SD6CRCHX.js.map +1 -0
  4. package/dist/{chunk-ZOLGAP4J.js → chunk-U5TGXMXL.js} +69 -69
  5. package/dist/{chunk-ZOLGAP4J.js.map → chunk-U5TGXMXL.js.map} +1 -1
  6. package/dist/{chunk-U7BF2UBR.js → chunk-X3RVS75R.js} +2 -2
  7. package/dist/chunk-YWOWXJGS.js +54 -0
  8. package/dist/chunk-YWOWXJGS.js.map +1 -0
  9. package/dist/{chunk-UNZSD2AO.js → chunk-ZTTUNOQ4.js} +4 -4
  10. package/dist/foundation-models-embedding-model-strategy-3AL3KDCE.js +58 -0
  11. package/dist/foundation-models-embedding-model-strategy-3AL3KDCE.js.map +1 -0
  12. package/dist/{foundation-models-language-model-strategy-I33LH7BS.js → foundation-models-language-model-strategy-X6RMOTAL.js} +5 -5
  13. package/dist/index.cjs +177 -156
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.js +6 -6
  16. package/dist/orchestration-embedding-model-strategy-VCSK76HX.js +60 -0
  17. package/dist/orchestration-embedding-model-strategy-VCSK76HX.js.map +1 -0
  18. package/dist/{orchestration-language-model-strategy-ZLUQWL3S.js → orchestration-language-model-strategy-YFINEDMS.js} +5 -5
  19. package/package.json +8 -6
  20. package/dist/chunk-KI7PB43L.js.map +0 -1
  21. package/dist/foundation-models-embedding-model-strategy-MOCNAFHN.js +0 -69
  22. package/dist/foundation-models-embedding-model-strategy-MOCNAFHN.js.map +0 -1
  23. package/dist/orchestration-embedding-model-strategy-RNDJFXXP.js +0 -79
  24. package/dist/orchestration-embedding-model-strategy-RNDJFXXP.js.map +0 -1
  25. /package/dist/{chunk-U7BF2UBR.js.map → chunk-X3RVS75R.js.map} +0 -0
  26. /package/dist/{chunk-UNZSD2AO.js.map → chunk-ZTTUNOQ4.js.map} +0 -0
  27. /package/dist/{foundation-models-language-model-strategy-I33LH7BS.js.map → foundation-models-language-model-strategy-X6RMOTAL.js.map} +0 -0
  28. /package/dist/{orchestration-language-model-strategy-ZLUQWL3S.js.map → orchestration-language-model-strategy-YFINEDMS.js.map} +0 -0
package/README.md CHANGED
@@ -262,6 +262,16 @@ const chatModel = provider.chat("gpt-4.1");
262
262
  const embeddingModel = provider.embedding("text-embedding-3-small");
263
263
  ```
264
264
 
265
+ **Available methods:**
266
+
267
+ | Method | Description |
268
+ | ---------------------------------- | --------------------------------------------- |
269
+ | `provider(modelId)` | Callable syntax, creates language model |
270
+ | `provider.chat(modelId)` | Creates language model (alias) |
271
+ | `provider.languageModel(modelId)` | Creates language model (ProviderV3 standard) |
272
+ | `provider.embedding(modelId)` | Creates embedding model |
273
+ | `provider.embeddingModel(modelId)` | Creates embedding model (ProviderV3 standard) |
274
+
265
275
  All methods accept an optional second parameter for model-specific settings.
266
276
 
267
277
  ## Authentication
@@ -60,12 +60,14 @@ function convertToSAPMessages(prompt, options = {}) {
60
60
  }
61
61
  }
62
62
  }
63
- const assistantMessage = {
64
- content: text || "",
65
- role: "assistant",
66
- tool_calls: toolCalls.length > 0 ? toolCalls : void 0
67
- };
68
- messages.push(assistantMessage);
63
+ if (text || toolCalls.length > 0) {
64
+ const assistantMessage = {
65
+ content: text,
66
+ role: "assistant",
67
+ tool_calls: toolCalls.length > 0 ? toolCalls : void 0
68
+ };
69
+ messages.push(assistantMessage);
70
+ }
69
71
  break;
70
72
  }
71
73
  case "system": {
@@ -192,4 +194,4 @@ export {
192
194
  escapeOrchestrationPlaceholders,
193
195
  unescapeOrchestrationPlaceholders
194
196
  };
195
- //# sourceMappingURL=chunk-KI7PB43L.js.map
197
+ //# sourceMappingURL=chunk-SD6CRCHX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/convert-to-sap-messages.ts"],"sourcesContent":["import type {\n AssistantChatMessage,\n ChatMessage,\n SystemChatMessage,\n ToolChatMessage,\n UserChatMessage,\n} from \"@sap-ai-sdk/orchestration\";\n\nimport {\n InvalidPromptError,\n LanguageModelV3Prompt,\n UnsupportedFunctionalityError,\n} from \"@ai-sdk/provider\";\nimport { Buffer } from \"node:buffer\";\n\n/**\n * Options for converting Vercel AI SDK prompts to SAP AI SDK messages.\n * @see {@link convertToSAPMessages}\n */\nexport interface ConvertToSAPMessagesOptions {\n /**\n * Whether to escape Jinja2 template delimiters (`{{`, `{%`, `{#`) in message content.\n * This prevents SAP orchestration from interpreting user content as template syntax.\n * @default true\n */\n readonly escapeTemplatePlaceholders?: boolean;\n /**\n * Whether to include assistant reasoning parts (wrapped in `<think>` tags).\n * @default false\n */\n readonly includeReasoning?: boolean;\n}\n\n/**\n * @internal\n */\nconst ZERO_WIDTH_SPACE = \"\\u200B\";\n\n/**\n * Safely serializes a value to JSON string, handling edge cases that would cause JSON.stringify to throw.\n *\n * Handles:\n * - Circular references (objects that reference themselves)\n * - BigInt values (converted to string representation)\n * - Undefined values and symbols (handled by JSON.stringify's default behavior)\n * @param value - The value to serialize.\n * @returns JSON string representation, or a fallback string representation if serialization fails.\n * @internal\n */\nfunction safeJsonStringify(value: unknown): string {\n try {\n return JSON.stringify(value, (_key, val) =>\n typeof val === \"bigint\" ? val.toString() : (val as unknown),\n );\n } catch {\n return String(value);\n }\n}\n\n/**\n * @internal\n */\nconst JINJA2_DELIMITERS_PATTERN = /\\{(?=[{%#])/g;\n\n/**\n * @internal\n */\nconst JINJA2_DELIMITERS_ESCAPED_PATTERN = new RegExp(`\\\\{${ZERO_WIDTH_SPACE}([{%#])`, \"g\");\n\n/**\n * @internal\n */\ninterface UserContentItem {\n readonly image_url?: {\n readonly url: string;\n };\n readonly text?: string;\n readonly type: \"image_url\" | \"text\";\n}\n\n/**\n * Converts Vercel AI SDK prompt to SAP AI SDK ChatMessage array.\n *\n * Handles all Vercel AI SDK message types:\n * - `system` → `SystemChatMessage`\n * - `user` (text/images) → `UserChatMessage`\n * - `assistant` (text/tool-calls) → `AssistantChatMessage`\n * - `tool` (tool results) → `ToolChatMessage`\n * @param prompt - The Vercel AI SDK LanguageModelV3Prompt to convert.\n * @param options - Conversion options.\n * @param options.escapeTemplatePlaceholders - Whether to escape Jinja2 template delimiters (default: true).\n * @param options.includeReasoning - Whether to include assistant reasoning parts (default: false).\n * @returns SAP AI SDK ChatMessage array ready for orchestration requests.\n * @throws {UnsupportedFunctionalityError} When encountering unsupported content types or file formats.\n * @throws {InvalidPromptError} When encountering unsupported message roles.\n */\nexport function convertToSAPMessages(\n prompt: LanguageModelV3Prompt,\n options: ConvertToSAPMessagesOptions = {},\n): ChatMessage[] {\n const messages: ChatMessage[] = [];\n const includeReasoning = options.includeReasoning ?? false;\n const escapeTemplatePlaceholders = options.escapeTemplatePlaceholders ?? true;\n\n const maybeEscape = (text: string): string =>\n escapeTemplatePlaceholders ? escapeOrchestrationPlaceholders(text) : text;\n\n for (const message of prompt) {\n switch (message.role) {\n case \"assistant\": {\n let text = \"\";\n const toolCalls: {\n function: { arguments: string; name: string };\n id: string;\n type: \"function\";\n }[] = [];\n\n for (const part of message.content) {\n switch (part.type) {\n case \"reasoning\": {\n if (includeReasoning && part.text) {\n text += `<think>${maybeEscape(part.text)}</think>`;\n }\n break;\n }\n case \"text\": {\n text += maybeEscape(part.text);\n break;\n }\n case \"tool-call\": {\n // Normalize tool call input to JSON string (Vercel AI SDK provides strings or objects)\n let argumentsJson: string;\n if (typeof part.input === \"string\") {\n argumentsJson = part.input;\n } else {\n argumentsJson = JSON.stringify(part.input);\n }\n\n // Escape tool call arguments if needed (they may contain placeholder syntax)\n toolCalls.push({\n function: {\n arguments: maybeEscape(argumentsJson),\n name: part.toolName,\n },\n id: part.toolCallId,\n type: \"function\",\n });\n break;\n }\n }\n }\n\n if (text || toolCalls.length > 0) {\n const assistantMessage: AssistantChatMessage = {\n content: text,\n role: \"assistant\",\n tool_calls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n messages.push(assistantMessage);\n }\n break;\n }\n\n case \"system\": {\n const systemMessage: SystemChatMessage = {\n content: maybeEscape(message.content),\n role: \"system\",\n };\n messages.push(systemMessage);\n break;\n }\n\n case \"tool\": {\n for (const part of message.content) {\n if (part.type === \"tool-result\") {\n const serializedOutput = safeJsonStringify(part.output);\n const toolMessage: ToolChatMessage = {\n content: maybeEscape(serializedOutput),\n role: \"tool\",\n tool_call_id: part.toolCallId,\n };\n messages.push(toolMessage);\n }\n }\n break;\n }\n\n case \"user\": {\n const contentParts: UserContentItem[] = [];\n\n for (const part of message.content) {\n switch (part.type) {\n case \"file\": {\n if (!part.mediaType.startsWith(\"image/\")) {\n throw new UnsupportedFunctionalityError({\n functionality: \"Only image files are supported\",\n });\n }\n\n const supportedFormats = [\n \"image/png\",\n \"image/jpeg\",\n \"image/jpg\",\n \"image/gif\",\n \"image/webp\",\n ];\n if (!supportedFormats.includes(part.mediaType.toLowerCase())) {\n console.warn(\n `Image format ${part.mediaType} may not be supported by all models. ` +\n `Recommended formats: PNG, JPEG, GIF, WebP`,\n );\n }\n\n let imageUrl: string;\n if (part.data instanceof URL) {\n imageUrl = part.data.toString();\n } else if (typeof part.data === \"string\") {\n imageUrl = `data:${part.mediaType};base64,${part.data}`;\n } else if (part.data instanceof Uint8Array) {\n const base64Data = Buffer.from(part.data).toString(\"base64\");\n imageUrl = `data:${part.mediaType};base64,${base64Data}`;\n } else if (Buffer.isBuffer(part.data)) {\n const base64Data = Buffer.from(part.data).toString(\"base64\");\n imageUrl = `data:${part.mediaType};base64,${base64Data}`;\n } else {\n const maybeBufferLike = part.data as unknown;\n\n if (\n maybeBufferLike !== null &&\n typeof maybeBufferLike === \"object\" &&\n \"toString\" in (maybeBufferLike as Record<string, unknown>)\n ) {\n const base64Data = (\n maybeBufferLike as {\n toString: (encoding?: string) => string;\n }\n ).toString(\"base64\");\n imageUrl = `data:${part.mediaType};base64,${base64Data}`;\n } else {\n throw new UnsupportedFunctionalityError({\n functionality:\n \"Unsupported file data type for image. Expected URL, base64 string, or Uint8Array.\",\n });\n }\n }\n\n contentParts.push({\n image_url: {\n url: imageUrl,\n },\n type: \"image_url\",\n });\n break;\n }\n case \"text\": {\n contentParts.push({\n text: maybeEscape(part.text),\n type: \"text\",\n });\n break;\n }\n default: {\n throw new UnsupportedFunctionalityError({\n functionality: `Content type ${(part as { type: string }).type}`,\n });\n }\n }\n }\n\n const firstPart = contentParts[0];\n const userMessage: UserChatMessage =\n contentParts.length === 1 && firstPart?.type === \"text\"\n ? {\n content: firstPart.text ?? \"\",\n role: \"user\",\n }\n : {\n content: contentParts as UserChatMessage[\"content\"],\n role: \"user\",\n };\n\n messages.push(userMessage);\n break;\n }\n\n default: {\n const _exhaustiveCheck: never = message;\n throw new InvalidPromptError({\n message: `Unsupported role: ${(_exhaustiveCheck as { role: string }).role}`,\n prompt: JSON.stringify(message),\n });\n }\n }\n }\n\n return messages;\n}\n\n/**\n * Escapes Jinja2 template delimiters by inserting zero-width spaces.\n *\n * Converts `{{`, `{%`, `{#` to `{\\u200B{`, `{\\u200B%`, `{\\u200B#` respectively.\n * This prevents SAP orchestration from interpreting user content as template syntax.\n * @param text - The text to escape.\n * @returns The escaped text with zero-width spaces inserted.\n * @see {@link unescapeOrchestrationPlaceholders} for the reverse operation.\n */\nexport function escapeOrchestrationPlaceholders(text: string): string {\n if (!text) return text;\n return text.replaceAll(JINJA2_DELIMITERS_PATTERN, `{${ZERO_WIDTH_SPACE}`);\n}\n\n/**\n * Reverses escaping by removing zero-width spaces from template delimiters.\n *\n * Useful for processing model responses that may contain escaped delimiters.\n * @param text - The text to unescape.\n * @returns The unescaped text with zero-width spaces removed.\n * @see {@link escapeOrchestrationPlaceholders} for the escaping operation.\n */\nexport function unescapeOrchestrationPlaceholders(text: string): string {\n if (!text) return text;\n return text.replaceAll(JINJA2_DELIMITERS_ESCAPED_PATTERN, \"{$1\");\n}\n"],"mappings":"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","names":[]}
@@ -29876,72 +29876,6 @@ var sapAIEmbeddingProviderOptions = lazySchema(
29876
29876
  )
29877
29877
  );
29878
29878
 
29879
- // src/deep-merge.ts
29880
- var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
29881
- var MAX_DEPTH = 100;
29882
- function deepMerge(...sources) {
29883
- return mergeInternal(sources);
29884
- }
29885
- function cloneDeep(obj, seen, depth) {
29886
- if (depth > MAX_DEPTH) {
29887
- throw new Error("Maximum merge depth exceeded");
29888
- }
29889
- if (seen.has(obj)) {
29890
- throw new Error("Circular reference detected during deep merge");
29891
- }
29892
- seen.add(obj);
29893
- const result = {};
29894
- for (const key of Object.keys(obj)) {
29895
- if (!isSafeKey(key)) continue;
29896
- const value = obj[key];
29897
- result[key] = isPlainObject(value) ? cloneDeep(value, seen, depth + 1) : value;
29898
- }
29899
- return result;
29900
- }
29901
- function isPlainObject(value) {
29902
- if (value === null || typeof value !== "object") return false;
29903
- const proto = Object.getPrototypeOf(value);
29904
- return proto === Object.prototype || proto === null;
29905
- }
29906
- function isSafeKey(key) {
29907
- return !DANGEROUS_KEYS.has(key);
29908
- }
29909
- function mergeInternal(sources) {
29910
- let result = {};
29911
- for (const source of sources) {
29912
- if (source == null) continue;
29913
- result = mergeTwo(result, source, /* @__PURE__ */ new WeakSet(), 0);
29914
- }
29915
- return result;
29916
- }
29917
- function mergeTwo(target, source, seen, depth) {
29918
- if (depth > MAX_DEPTH) {
29919
- throw new Error("Maximum merge depth exceeded");
29920
- }
29921
- if (seen.has(source)) {
29922
- throw new Error("Circular reference detected during deep merge");
29923
- }
29924
- seen.add(source);
29925
- for (const key of Object.keys(source)) {
29926
- if (!isSafeKey(key)) continue;
29927
- const sourceValue = source[key];
29928
- const targetValue = target[key];
29929
- if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
29930
- target[key] = mergeTwo(
29931
- cloneDeep(targetValue, /* @__PURE__ */ new WeakSet(), depth + 1),
29932
- sourceValue,
29933
- seen,
29934
- depth + 1
29935
- );
29936
- } else if (isPlainObject(sourceValue)) {
29937
- target[key] = cloneDeep(sourceValue, seen, depth + 1);
29938
- } else {
29939
- target[key] = sourceValue;
29940
- }
29941
- }
29942
- return target;
29943
- }
29944
-
29945
29879
  // src/sap-ai-error.ts
29946
29880
  var import_util = __toESM(require_dist(), 1);
29947
29881
  import { APICallError, LoadAPIKeyError, NoSuchModelError } from "@ai-sdk/provider";
@@ -30430,8 +30364,74 @@ function tryExtractSAPErrorFromMessage(message) {
30430
30364
  }
30431
30365
  }
30432
30366
 
30367
+ // src/deep-merge.ts
30368
+ var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
30369
+ var MAX_DEPTH = 100;
30370
+ function deepMerge(...sources) {
30371
+ return mergeInternal(sources);
30372
+ }
30373
+ function cloneDeep(obj, seen, depth) {
30374
+ if (depth > MAX_DEPTH) {
30375
+ throw new Error("Maximum merge depth exceeded");
30376
+ }
30377
+ if (seen.has(obj)) {
30378
+ throw new Error("Circular reference detected during deep merge");
30379
+ }
30380
+ seen.add(obj);
30381
+ const result = {};
30382
+ for (const key of Object.keys(obj)) {
30383
+ if (!isSafeKey(key)) continue;
30384
+ const value = obj[key];
30385
+ result[key] = isPlainObject(value) ? cloneDeep(value, seen, depth + 1) : value;
30386
+ }
30387
+ return result;
30388
+ }
30389
+ function isPlainObject(value) {
30390
+ if (value === null || typeof value !== "object") return false;
30391
+ const proto = Object.getPrototypeOf(value);
30392
+ return proto === Object.prototype || proto === null;
30393
+ }
30394
+ function isSafeKey(key) {
30395
+ return !DANGEROUS_KEYS.has(key);
30396
+ }
30397
+ function mergeInternal(sources) {
30398
+ let result = {};
30399
+ for (const source of sources) {
30400
+ if (source == null) continue;
30401
+ result = mergeTwo(result, source, /* @__PURE__ */ new WeakSet(), 0);
30402
+ }
30403
+ return result;
30404
+ }
30405
+ function mergeTwo(target, source, seen, depth) {
30406
+ if (depth > MAX_DEPTH) {
30407
+ throw new Error("Maximum merge depth exceeded");
30408
+ }
30409
+ if (seen.has(source)) {
30410
+ throw new Error("Circular reference detected during deep merge");
30411
+ }
30412
+ seen.add(source);
30413
+ for (const key of Object.keys(source)) {
30414
+ if (!isSafeKey(key)) continue;
30415
+ const sourceValue = source[key];
30416
+ const targetValue = target[key];
30417
+ if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
30418
+ target[key] = mergeTwo(
30419
+ cloneDeep(targetValue, /* @__PURE__ */ new WeakSet(), depth + 1),
30420
+ sourceValue,
30421
+ seen,
30422
+ depth + 1
30423
+ );
30424
+ } else if (isPlainObject(sourceValue)) {
30425
+ target[key] = cloneDeep(sourceValue, seen, depth + 1);
30426
+ } else {
30427
+ target[key] = sourceValue;
30428
+ }
30429
+ }
30430
+ return target;
30431
+ }
30432
+
30433
30433
  // src/version.ts
30434
- var VERSION = true ? "4.4.14" : "0.0.0-test";
30434
+ var VERSION = true ? "4.4.16" : "0.0.0-test";
30435
30435
 
30436
30436
  export {
30437
30437
  __toESM,
@@ -30443,12 +30443,12 @@ export {
30443
30443
  orchestrationConfigRefSchema,
30444
30444
  sapAILanguageModelProviderOptions,
30445
30445
  sapAIEmbeddingProviderOptions,
30446
- deepMerge,
30447
30446
  require_dist,
30448
30447
  ApiSwitchError,
30449
30448
  UnsupportedFeatureError,
30450
30449
  convertToAISDKError,
30451
30450
  normalizeHeaders,
30451
+ deepMerge,
30452
30452
  VERSION
30453
30453
  };
30454
30454
  /*! Bundled license information:
@@ -30484,4 +30484,4 @@ mime-types/index.js:
30484
30484
  axios/dist/node/axios.cjs:
30485
30485
  (*! Axios v1.13.5 Copyright (c) 2026 Matt Zabriskie and contributors *)
30486
30486
  */
30487
- //# sourceMappingURL=chunk-ZOLGAP4J.js.map
30487
+ //# sourceMappingURL=chunk-U5TGXMXL.js.map