@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 +448 -614
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +145 -830
- package/dist/index.d.ts +145 -830
- package/dist/index.js +448 -615
- package/dist/index.js.map +1 -1
- package/package.json +4 -5
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 =
|
|
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
|
|
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
|
|
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 (
|
|
26349
|
+
if (isPlainObject2(result[targetKey]) && isPlainObject2(val)) {
|
|
26350
26350
|
result[targetKey] = merge(result[targetKey], val);
|
|
26351
|
-
} else if (
|
|
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
|
|
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: ${
|
|
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
|
|
29959
|
-
|
|
29960
|
-
|
|
29961
|
-
|
|
29962
|
-
|
|
29963
|
-
|
|
29964
|
-
|
|
29965
|
-
|
|
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
|
|
29970
|
-
|
|
29971
|
-
|
|
29972
|
-
|
|
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
|
-
|
|
29976
|
-
|
|
29977
|
-
|
|
29978
|
-
|
|
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(
|
|
30042
|
+
const modelId = extractModelIdentifier(originalErrorMsg);
|
|
29983
30043
|
return new import_provider.NoSuchModelError({
|
|
29984
|
-
message: `SAP AI Core deployment error: ${
|
|
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
|
|
29994
|
-
|
|
29995
|
-
|
|
29996
|
-
|
|
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
|
-
|
|
30000
|
-
|
|
30001
|
-
|
|
30002
|
-
|
|
30003
|
-
});
|
|
30060
|
+
statusCode: HTTP_STATUS.BAD_REQUEST
|
|
30061
|
+
},
|
|
30062
|
+
context
|
|
30063
|
+
);
|
|
30004
30064
|
}
|
|
30005
|
-
const statusMatch = /status code (\d+)/i.exec(
|
|
30065
|
+
const statusMatch = /status code (\d+)/i.exec(originalErrorMsg);
|
|
30006
30066
|
if (statusMatch) {
|
|
30007
|
-
const extractedStatus = parseInt(statusMatch[1], 10);
|
|
30008
|
-
return
|
|
30009
|
-
|
|
30010
|
-
|
|
30011
|
-
|
|
30012
|
-
|
|
30013
|
-
|
|
30014
|
-
|
|
30015
|
-
|
|
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
|
|
30020
|
-
|
|
30021
|
-
|
|
30022
|
-
|
|
30023
|
-
|
|
30024
|
-
|
|
30025
|
-
|
|
30026
|
-
|
|
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
|
|
30031
|
-
|
|
30032
|
-
|
|
30033
|
-
|
|
30034
|
-
|
|
30035
|
-
|
|
30036
|
-
|
|
30037
|
-
|
|
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
|
|
30042
|
-
|
|
30043
|
-
|
|
30044
|
-
|
|
30045
|
-
|
|
30046
|
-
|
|
30047
|
-
|
|
30048
|
-
|
|
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
|
|
30053
|
-
|
|
30054
|
-
|
|
30055
|
-
|
|
30056
|
-
|
|
30057
|
-
|
|
30058
|
-
|
|
30059
|
-
|
|
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
|
|
30064
|
-
|
|
30065
|
-
|
|
30066
|
-
|
|
30067
|
-
|
|
30068
|
-
|
|
30069
|
-
|
|
30070
|
-
|
|
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
|
|
30075
|
-
|
|
30076
|
-
|
|
30077
|
-
|
|
30078
|
-
|
|
30079
|
-
|
|
30080
|
-
|
|
30081
|
-
|
|
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
|
|
30086
|
-
|
|
30087
|
-
|
|
30088
|
-
|
|
30089
|
-
|
|
30090
|
-
|
|
30091
|
-
|
|
30092
|
-
|
|
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
|
|
30097
|
-
|
|
30098
|
-
|
|
30099
|
-
|
|
30100
|
-
|
|
30101
|
-
|
|
30102
|
-
|
|
30103
|
-
|
|
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:
|
|
30112
|
-
message
|
|
30206
|
+
isRetryable: options.isRetryable,
|
|
30207
|
+
message,
|
|
30113
30208
|
requestBodyValues: context?.requestBody,
|
|
30209
|
+
responseBody,
|
|
30114
30210
|
responseHeaders,
|
|
30115
|
-
statusCode:
|
|
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
|
|
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
|
|
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
|
|
30192
|
-
if (
|
|
30193
|
-
|
|
30194
|
-
|
|
30195
|
-
if (typeof
|
|
30196
|
-
|
|
30197
|
-
|
|
30198
|
-
|
|
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
|
-
|
|
30204
|
-
|
|
30205
|
-
|
|
30206
|
-
|
|
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
|
-
*
|
|
30387
|
-
*
|
|
30388
|
-
* @param
|
|
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
|
-
*
|
|
30404
|
-
*
|
|
30405
|
-
* @
|
|
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
|
|
30472
|
-
* @param perCallModelParams -
|
|
30473
|
-
* @returns
|
|
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
|
|
30495
|
-
*
|
|
30496
|
-
* @
|
|
30497
|
-
* @
|
|
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
|
-
*
|
|
30540
|
-
*
|
|
30541
|
-
*
|
|
30542
|
-
*
|
|
30543
|
-
*
|
|
30544
|
-
*
|
|
30545
|
-
* @param options -
|
|
30546
|
-
* @
|
|
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
|
-
/**
|
|
30814
|
+
/** Whether the model supports parallel tool calls. */
|
|
30799
30815
|
supportsParallelToolCalls = true;
|
|
30800
|
-
/**
|
|
30816
|
+
/** Whether the model supports streaming responses. */
|
|
30801
30817
|
supportsStreaming = true;
|
|
30802
|
-
/**
|
|
30818
|
+
/** Whether the model supports structured JSON outputs. */
|
|
30803
30819
|
supportsStructuredOutputs = true;
|
|
30804
|
-
/**
|
|
30820
|
+
/** Whether the model supports tool/function calling. */
|
|
30805
30821
|
supportsToolCalls = true;
|
|
30806
30822
|
/**
|
|
30807
|
-
*
|
|
30808
|
-
* @returns The provider
|
|
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
|
-
*
|
|
30815
|
-
* @returns
|
|
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
|
|
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
|
-
*
|
|
30844
|
-
*
|
|
30845
|
-
*
|
|
30846
|
-
*
|
|
30847
|
-
*
|
|
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
|
|
30878
|
-
const
|
|
30879
|
-
|
|
30880
|
-
|
|
30881
|
-
|
|
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
|
-
*
|
|
31021
|
-
*
|
|
31022
|
-
*
|
|
31023
|
-
*
|
|
31024
|
-
*
|
|
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
|
|
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
|
|
31338
|
-
* @param url - The URL to check
|
|
31339
|
-
* @returns True if the URL
|
|
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
|
|
31350
|
-
* @param options -
|
|
31351
|
-
* @returns
|
|
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
|
-
|
|
31432
|
-
|
|
31433
|
-
|
|
31434
|
-
|
|
31435
|
-
|
|
31436
|
-
|
|
31437
|
-
|
|
31438
|
-
|
|
31439
|
-
|
|
31440
|
-
|
|
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
|
-
|
|
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
|
-
|
|
31514
|
-
|
|
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
|
-
*
|
|
31533
|
-
* @param
|
|
31534
|
-
* @
|
|
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
|
-
*
|
|
31623
|
-
* @returns The provider
|
|
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
|
-
*
|
|
31630
|
-
* @returns
|
|
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
|
-
*
|
|
31653
|
-
*
|
|
31654
|
-
*
|
|
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
|
-
*
|
|
31710
|
-
*
|
|
31711
|
-
*
|
|
31712
|
-
*
|
|
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
|
-
|
|
31798
|
-
|
|
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
|