@jerome-benoit/sap-ai-provider 4.2.2 → 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 +284 -277
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +95 -56
- package/dist/index.d.ts +95 -56
- package/dist/index.js +284 -278
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
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;
|
|
@@ -29743,6 +29743,7 @@ __export(index_exports, {
|
|
|
29743
29743
|
OrchestrationStreamChunkResponse: () => import_orchestration4.OrchestrationStreamChunkResponse,
|
|
29744
29744
|
OrchestrationStreamResponse: () => import_orchestration4.OrchestrationStreamResponse,
|
|
29745
29745
|
SAPAIEmbeddingModel: () => SAPAIEmbeddingModel,
|
|
29746
|
+
SAPAILanguageModel: () => SAPAILanguageModel,
|
|
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
|
|
@@ -29932,46 +29932,45 @@ function convertToAISDKError(error, context) {
|
|
|
29932
29932
|
});
|
|
29933
29933
|
}
|
|
29934
29934
|
}
|
|
29935
|
-
const responseHeaders = context?.responseHeaders ?? getAxiosResponseHeaders(error);
|
|
29936
29935
|
if (rootError instanceof Error) {
|
|
29937
29936
|
const errorMsg = rootError.message.toLowerCase();
|
|
29938
|
-
const
|
|
29937
|
+
const originalErrorMsg = rootError.message;
|
|
29939
29938
|
if (errorMsg.includes("authentication") || errorMsg.includes("unauthorized") || errorMsg.includes("aicore_service_key") || errorMsg.includes("invalid credentials") || errorMsg.includes("service credentials") || errorMsg.includes("service binding")) {
|
|
29940
29939
|
return new import_provider.LoadAPIKeyError({
|
|
29941
|
-
message: `SAP AI Core authentication failed: ${
|
|
29940
|
+
message: `SAP AI Core authentication failed: ${originalErrorMsg}
|
|
29942
29941
|
|
|
29943
29942
|
Make sure your AICORE_SERVICE_KEY environment variable is set correctly.
|
|
29944
29943
|
See: https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-service-key`
|
|
29945
29944
|
});
|
|
29946
29945
|
}
|
|
29947
29946
|
if (errorMsg.includes("econnrefused") || errorMsg.includes("enotfound") || errorMsg.includes("network") || errorMsg.includes("timeout")) {
|
|
29948
|
-
return
|
|
29949
|
-
|
|
29950
|
-
|
|
29951
|
-
|
|
29952
|
-
|
|
29953
|
-
|
|
29954
|
-
|
|
29955
|
-
|
|
29956
|
-
|
|
29947
|
+
return createAPICallError(
|
|
29948
|
+
error,
|
|
29949
|
+
{
|
|
29950
|
+
isRetryable: true,
|
|
29951
|
+
message: `Network error connecting to SAP AI Core: ${originalErrorMsg}`,
|
|
29952
|
+
statusCode: HTTP_STATUS.SERVICE_UNAVAILABLE
|
|
29953
|
+
},
|
|
29954
|
+
context
|
|
29955
|
+
);
|
|
29957
29956
|
}
|
|
29958
29957
|
if (errorMsg.includes("could not resolve destination")) {
|
|
29959
|
-
return
|
|
29960
|
-
|
|
29961
|
-
|
|
29962
|
-
|
|
29958
|
+
return createAPICallError(
|
|
29959
|
+
error,
|
|
29960
|
+
{
|
|
29961
|
+
isRetryable: false,
|
|
29962
|
+
message: `SAP AI Core destination error: ${originalErrorMsg}
|
|
29963
29963
|
|
|
29964
29964
|
Check your destination configuration or provide a valid destinationName.`,
|
|
29965
|
-
|
|
29966
|
-
|
|
29967
|
-
|
|
29968
|
-
|
|
29969
|
-
});
|
|
29965
|
+
statusCode: HTTP_STATUS.BAD_REQUEST
|
|
29966
|
+
},
|
|
29967
|
+
context
|
|
29968
|
+
);
|
|
29970
29969
|
}
|
|
29971
29970
|
if (errorMsg.includes("failed to resolve deployment") || errorMsg.includes("no deployment matched")) {
|
|
29972
|
-
const modelId = extractModelIdentifier(
|
|
29971
|
+
const modelId = extractModelIdentifier(originalErrorMsg);
|
|
29973
29972
|
return new import_provider.NoSuchModelError({
|
|
29974
|
-
message: `SAP AI Core deployment error: ${
|
|
29973
|
+
message: `SAP AI Core deployment error: ${originalErrorMsg}
|
|
29975
29974
|
|
|
29976
29975
|
Make sure you have a running orchestration deployment in your AI Core instance.
|
|
29977
29976
|
See: https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-deployment-for-orchestration`,
|
|
@@ -29980,129 +29979,165 @@ See: https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-depl
|
|
|
29980
29979
|
});
|
|
29981
29980
|
}
|
|
29982
29981
|
if (errorMsg.includes("filtered by the output filter")) {
|
|
29983
|
-
return
|
|
29984
|
-
|
|
29985
|
-
|
|
29986
|
-
|
|
29982
|
+
return createAPICallError(
|
|
29983
|
+
error,
|
|
29984
|
+
{
|
|
29985
|
+
isRetryable: false,
|
|
29986
|
+
message: `Content was filtered: ${originalErrorMsg}
|
|
29987
29987
|
|
|
29988
29988
|
The model's response was blocked by content safety filters. Try a different prompt.`,
|
|
29989
|
-
|
|
29990
|
-
|
|
29991
|
-
|
|
29992
|
-
|
|
29993
|
-
});
|
|
29989
|
+
statusCode: HTTP_STATUS.BAD_REQUEST
|
|
29990
|
+
},
|
|
29991
|
+
context
|
|
29992
|
+
);
|
|
29994
29993
|
}
|
|
29995
|
-
const statusMatch = /status code (\d+)/i.exec(
|
|
29994
|
+
const statusMatch = /status code (\d+)/i.exec(originalErrorMsg);
|
|
29996
29995
|
if (statusMatch) {
|
|
29997
29996
|
const extractedStatus = Number.parseInt(statusMatch[1], 10);
|
|
29998
|
-
return
|
|
29999
|
-
|
|
30000
|
-
|
|
30001
|
-
|
|
30002
|
-
|
|
30003
|
-
|
|
30004
|
-
|
|
30005
|
-
|
|
30006
|
-
|
|
29997
|
+
return createAPICallError(
|
|
29998
|
+
error,
|
|
29999
|
+
{
|
|
30000
|
+
isRetryable: isRetryable(extractedStatus),
|
|
30001
|
+
message: `SAP AI Core request failed: ${originalErrorMsg}`,
|
|
30002
|
+
statusCode: extractedStatus
|
|
30003
|
+
},
|
|
30004
|
+
context
|
|
30005
|
+
);
|
|
30007
30006
|
}
|
|
30008
30007
|
if (errorMsg.includes("consumed stream")) {
|
|
30009
|
-
return
|
|
30010
|
-
|
|
30011
|
-
|
|
30012
|
-
|
|
30013
|
-
|
|
30014
|
-
|
|
30015
|
-
|
|
30016
|
-
|
|
30017
|
-
|
|
30008
|
+
return createAPICallError(
|
|
30009
|
+
error,
|
|
30010
|
+
{
|
|
30011
|
+
isRetryable: false,
|
|
30012
|
+
message: `SAP AI Core stream consumption error: ${originalErrorMsg}`,
|
|
30013
|
+
statusCode: HTTP_STATUS.INTERNAL_ERROR
|
|
30014
|
+
},
|
|
30015
|
+
context
|
|
30016
|
+
);
|
|
30018
30017
|
}
|
|
30019
30018
|
if (errorMsg.includes("iterating over") || errorMsg.includes("parse message into json") || errorMsg.includes("received from") || errorMsg.includes("no body") || errorMsg.includes("invalid sse payload")) {
|
|
30020
|
-
return
|
|
30021
|
-
|
|
30022
|
-
|
|
30023
|
-
|
|
30024
|
-
|
|
30025
|
-
|
|
30026
|
-
|
|
30027
|
-
|
|
30028
|
-
|
|
30019
|
+
return createAPICallError(
|
|
30020
|
+
error,
|
|
30021
|
+
{
|
|
30022
|
+
isRetryable: true,
|
|
30023
|
+
message: `SAP AI Core streaming error: ${originalErrorMsg}`,
|
|
30024
|
+
statusCode: HTTP_STATUS.INTERNAL_ERROR
|
|
30025
|
+
},
|
|
30026
|
+
context
|
|
30027
|
+
);
|
|
30029
30028
|
}
|
|
30030
30029
|
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")) {
|
|
30031
|
-
return
|
|
30032
|
-
|
|
30033
|
-
|
|
30034
|
-
|
|
30035
|
-
|
|
30036
|
-
|
|
30037
|
-
|
|
30038
|
-
|
|
30039
|
-
|
|
30030
|
+
return createAPICallError(
|
|
30031
|
+
error,
|
|
30032
|
+
{
|
|
30033
|
+
isRetryable: false,
|
|
30034
|
+
message: `SAP AI Core configuration error: ${originalErrorMsg}`,
|
|
30035
|
+
statusCode: HTTP_STATUS.BAD_REQUEST
|
|
30036
|
+
},
|
|
30037
|
+
context
|
|
30038
|
+
);
|
|
30040
30039
|
}
|
|
30041
30040
|
if (errorMsg.includes("buffer is not available as globals")) {
|
|
30042
|
-
return
|
|
30043
|
-
|
|
30044
|
-
|
|
30045
|
-
|
|
30046
|
-
|
|
30047
|
-
|
|
30048
|
-
|
|
30049
|
-
|
|
30050
|
-
|
|
30041
|
+
return createAPICallError(
|
|
30042
|
+
error,
|
|
30043
|
+
{
|
|
30044
|
+
isRetryable: false,
|
|
30045
|
+
message: `SAP AI Core environment error: ${originalErrorMsg}`,
|
|
30046
|
+
statusCode: HTTP_STATUS.INTERNAL_ERROR
|
|
30047
|
+
},
|
|
30048
|
+
context
|
|
30049
|
+
);
|
|
30051
30050
|
}
|
|
30052
30051
|
if (errorMsg.includes("response stream is undefined")) {
|
|
30053
|
-
return
|
|
30054
|
-
|
|
30055
|
-
|
|
30056
|
-
|
|
30057
|
-
|
|
30058
|
-
|
|
30059
|
-
|
|
30060
|
-
|
|
30061
|
-
|
|
30052
|
+
return createAPICallError(
|
|
30053
|
+
error,
|
|
30054
|
+
{
|
|
30055
|
+
isRetryable: false,
|
|
30056
|
+
message: `SAP AI Core response stream error: ${originalErrorMsg}`,
|
|
30057
|
+
statusCode: HTTP_STATUS.INTERNAL_ERROR
|
|
30058
|
+
},
|
|
30059
|
+
context
|
|
30060
|
+
);
|
|
30062
30061
|
}
|
|
30063
30062
|
if (errorMsg.includes("response is required to process") || errorMsg.includes("stream is still open") || errorMsg.includes("data is not available yet")) {
|
|
30064
|
-
return
|
|
30065
|
-
|
|
30066
|
-
|
|
30067
|
-
|
|
30068
|
-
|
|
30069
|
-
|
|
30070
|
-
|
|
30071
|
-
|
|
30072
|
-
|
|
30063
|
+
return createAPICallError(
|
|
30064
|
+
error,
|
|
30065
|
+
{
|
|
30066
|
+
isRetryable: true,
|
|
30067
|
+
message: `SAP AI Core response processing error: ${originalErrorMsg}`,
|
|
30068
|
+
statusCode: HTTP_STATUS.INTERNAL_ERROR
|
|
30069
|
+
},
|
|
30070
|
+
context
|
|
30071
|
+
);
|
|
30073
30072
|
}
|
|
30074
30073
|
if (errorMsg.includes("failed to fetch the list of deployments")) {
|
|
30075
|
-
return
|
|
30076
|
-
|
|
30077
|
-
|
|
30078
|
-
|
|
30079
|
-
|
|
30080
|
-
|
|
30081
|
-
|
|
30082
|
-
|
|
30083
|
-
|
|
30074
|
+
return createAPICallError(
|
|
30075
|
+
error,
|
|
30076
|
+
{
|
|
30077
|
+
isRetryable: true,
|
|
30078
|
+
message: `SAP AI Core deployment retrieval error: ${originalErrorMsg}`,
|
|
30079
|
+
statusCode: HTTP_STATUS.SERVICE_UNAVAILABLE
|
|
30080
|
+
},
|
|
30081
|
+
context
|
|
30082
|
+
);
|
|
30084
30083
|
}
|
|
30085
30084
|
if (errorMsg.includes("received non-uint8array")) {
|
|
30086
|
-
return
|
|
30087
|
-
|
|
30088
|
-
|
|
30089
|
-
|
|
30090
|
-
|
|
30091
|
-
|
|
30092
|
-
|
|
30093
|
-
|
|
30094
|
-
|
|
30085
|
+
return createAPICallError(
|
|
30086
|
+
error,
|
|
30087
|
+
{
|
|
30088
|
+
isRetryable: false,
|
|
30089
|
+
message: `SAP AI Core stream buffer error: ${originalErrorMsg}`,
|
|
30090
|
+
statusCode: HTTP_STATUS.INTERNAL_ERROR
|
|
30091
|
+
},
|
|
30092
|
+
context
|
|
30093
|
+
);
|
|
30095
30094
|
}
|
|
30096
30095
|
}
|
|
30097
30096
|
const message = rootError instanceof Error ? rootError.message : typeof rootError === "string" ? rootError : "Unknown error occurred";
|
|
30098
30097
|
const fullMessage = context?.operation ? `SAP AI Core ${context.operation} failed: ${message}` : `SAP AI Core error: ${message}`;
|
|
30098
|
+
return createAPICallError(
|
|
30099
|
+
error,
|
|
30100
|
+
{
|
|
30101
|
+
isRetryable: false,
|
|
30102
|
+
message: fullMessage,
|
|
30103
|
+
statusCode: HTTP_STATUS.INTERNAL_ERROR
|
|
30104
|
+
},
|
|
30105
|
+
context
|
|
30106
|
+
);
|
|
30107
|
+
}
|
|
30108
|
+
function normalizeHeaders(headers) {
|
|
30109
|
+
if (!headers || typeof headers !== "object") return void 0;
|
|
30110
|
+
const record = headers;
|
|
30111
|
+
const entries = Object.entries(record).flatMap(([key, value]) => {
|
|
30112
|
+
if (typeof value === "string") return [[key, value]];
|
|
30113
|
+
if (Array.isArray(value)) {
|
|
30114
|
+
const strings = value.filter((item) => typeof item === "string").join("; ");
|
|
30115
|
+
return strings.length > 0 ? [[key, strings]] : [];
|
|
30116
|
+
}
|
|
30117
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
30118
|
+
return [[key, String(value)]];
|
|
30119
|
+
}
|
|
30120
|
+
return [];
|
|
30121
|
+
});
|
|
30122
|
+
if (entries.length === 0) return void 0;
|
|
30123
|
+
return Object.fromEntries(entries);
|
|
30124
|
+
}
|
|
30125
|
+
function createAPICallError(error, options, context) {
|
|
30126
|
+
const responseBody = getAxiosResponseBody(error);
|
|
30127
|
+
const responseHeaders = context?.responseHeaders ?? getAxiosResponseHeaders(error);
|
|
30128
|
+
const enrichMessage = options.enrichMessage ?? true;
|
|
30129
|
+
const message = enrichMessage && responseBody ? `${options.message}
|
|
30130
|
+
|
|
30131
|
+
SAP AI Core Error Response:
|
|
30132
|
+
${responseBody}` : options.message;
|
|
30099
30133
|
return new import_provider.APICallError({
|
|
30100
30134
|
cause: error,
|
|
30101
|
-
isRetryable:
|
|
30102
|
-
message
|
|
30135
|
+
isRetryable: options.isRetryable,
|
|
30136
|
+
message,
|
|
30103
30137
|
requestBodyValues: context?.requestBody,
|
|
30138
|
+
responseBody,
|
|
30104
30139
|
responseHeaders,
|
|
30105
|
-
statusCode:
|
|
30140
|
+
statusCode: options.statusCode,
|
|
30106
30141
|
url: context?.url ?? ""
|
|
30107
30142
|
});
|
|
30108
30143
|
}
|
|
@@ -30126,13 +30161,23 @@ function extractModelIdentifier(message, location) {
|
|
|
30126
30161
|
}
|
|
30127
30162
|
return void 0;
|
|
30128
30163
|
}
|
|
30129
|
-
function
|
|
30164
|
+
function getAxiosError(error) {
|
|
30130
30165
|
if (!(error instanceof Error)) return void 0;
|
|
30131
30166
|
const rootCause = (0, import_util.isErrorWithCause)(error) ? error.rootCause : error;
|
|
30132
|
-
if (typeof rootCause !== "object") return void 0;
|
|
30167
|
+
if (typeof rootCause !== "object" || rootCause === null) return void 0;
|
|
30133
30168
|
const maybeAxios = rootCause;
|
|
30134
30169
|
if (maybeAxios.isAxiosError !== true) return void 0;
|
|
30135
|
-
return
|
|
30170
|
+
return maybeAxios;
|
|
30171
|
+
}
|
|
30172
|
+
function getAxiosResponseBody(error) {
|
|
30173
|
+
const axiosError = getAxiosError(error);
|
|
30174
|
+
if (!axiosError?.response?.data) return void 0;
|
|
30175
|
+
return serializeAxiosResponseData(axiosError.response.data);
|
|
30176
|
+
}
|
|
30177
|
+
function getAxiosResponseHeaders(error) {
|
|
30178
|
+
const axiosError = getAxiosError(error);
|
|
30179
|
+
if (!axiosError) return void 0;
|
|
30180
|
+
return normalizeHeaders(axiosError.response?.headers);
|
|
30136
30181
|
}
|
|
30137
30182
|
function getStatusCodeFromSAPError(code) {
|
|
30138
30183
|
if (!code) return HTTP_STATUS.INTERNAL_ERROR;
|
|
@@ -30178,22 +30223,22 @@ function isOrchestrationErrorResponse(error) {
|
|
|
30178
30223
|
function isRetryable(statusCode) {
|
|
30179
30224
|
return statusCode === HTTP_STATUS.REQUEST_TIMEOUT || statusCode === HTTP_STATUS.CONFLICT || statusCode === HTTP_STATUS.RATE_LIMIT || statusCode >= HTTP_STATUS.INTERNAL_ERROR && statusCode < 600;
|
|
30180
30225
|
}
|
|
30181
|
-
function
|
|
30182
|
-
if (
|
|
30183
|
-
|
|
30184
|
-
|
|
30185
|
-
if (typeof
|
|
30186
|
-
|
|
30187
|
-
|
|
30188
|
-
|
|
30189
|
-
}
|
|
30190
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
30191
|
-
return [[key, String(value)]];
|
|
30226
|
+
function serializeAxiosResponseData(data, maxLength = 2e3) {
|
|
30227
|
+
if (data === void 0) return void 0;
|
|
30228
|
+
let serialized;
|
|
30229
|
+
try {
|
|
30230
|
+
if (typeof data === "string") {
|
|
30231
|
+
serialized = data;
|
|
30232
|
+
} else {
|
|
30233
|
+
serialized = JSON.stringify(data, null, 2);
|
|
30192
30234
|
}
|
|
30193
|
-
|
|
30194
|
-
|
|
30195
|
-
|
|
30196
|
-
|
|
30235
|
+
} catch {
|
|
30236
|
+
serialized = `[Unable to serialize: ${typeof data}]`;
|
|
30237
|
+
}
|
|
30238
|
+
if (serialized.length > maxLength) {
|
|
30239
|
+
return serialized.slice(0, maxLength) + "...[truncated]";
|
|
30240
|
+
}
|
|
30241
|
+
return serialized;
|
|
30197
30242
|
}
|
|
30198
30243
|
function tryExtractSAPErrorFromMessage(message) {
|
|
30199
30244
|
const jsonMatch = /\{[\s\S]*\}/.exec(message);
|
|
@@ -30299,6 +30344,14 @@ var SAPAIEmbeddingModel = class {
|
|
|
30299
30344
|
supportsParallelCalls = true;
|
|
30300
30345
|
config;
|
|
30301
30346
|
settings;
|
|
30347
|
+
/**
|
|
30348
|
+
* Creates a new SAP AI Embedding Model instance.
|
|
30349
|
+
*
|
|
30350
|
+
* This is the main implementation that handles all SAP AI Core embedding logic.
|
|
30351
|
+
* @param modelId - The model identifier (e.g., 'text-embedding-ada-002', 'text-embedding-3-small').
|
|
30352
|
+
* @param settings - Model configuration settings (embedding type, model parameters, etc.).
|
|
30353
|
+
* @param config - SAP AI Core deployment and destination configuration.
|
|
30354
|
+
*/
|
|
30302
30355
|
constructor(modelId, settings = {}, config) {
|
|
30303
30356
|
if (settings.modelParams) {
|
|
30304
30357
|
validateEmbeddingModelParamsSettings(settings.modelParams);
|
|
@@ -30311,8 +30364,10 @@ var SAPAIEmbeddingModel = class {
|
|
|
30311
30364
|
}
|
|
30312
30365
|
/**
|
|
30313
30366
|
* Generates embeddings for the given input values.
|
|
30314
|
-
*
|
|
30315
|
-
*
|
|
30367
|
+
*
|
|
30368
|
+
* Validates input count, merges settings, calls SAP AI SDK, and normalizes embeddings.
|
|
30369
|
+
* @param options - The Vercel AI SDK V3 embedding call options.
|
|
30370
|
+
* @returns The embedding result with vectors, usage data, and warnings.
|
|
30316
30371
|
*/
|
|
30317
30372
|
async doEmbed(options) {
|
|
30318
30373
|
const { abortSignal, providerOptions, values } = options;
|
|
@@ -30403,9 +30458,6 @@ var SAPAIEmbeddingModel = class {
|
|
|
30403
30458
|
}
|
|
30404
30459
|
};
|
|
30405
30460
|
|
|
30406
|
-
// src/sap-ai-provider.ts
|
|
30407
|
-
var import_provider4 = require("@ai-sdk/provider");
|
|
30408
|
-
|
|
30409
30461
|
// src/sap-ai-language-model.ts
|
|
30410
30462
|
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
30411
30463
|
var import_orchestration2 = require("@sap-ai-sdk/orchestration");
|
|
@@ -30576,6 +30628,20 @@ function convertToSAPMessages(prompt, options = {}) {
|
|
|
30576
30628
|
}
|
|
30577
30629
|
|
|
30578
30630
|
// src/sap-ai-language-model.ts
|
|
30631
|
+
var PARAM_MAPPINGS = [
|
|
30632
|
+
{ camelCaseKey: "maxTokens", optionKey: "maxOutputTokens", outputKey: "max_tokens" },
|
|
30633
|
+
{ camelCaseKey: "temperature", optionKey: "temperature", outputKey: "temperature" },
|
|
30634
|
+
{ camelCaseKey: "topP", optionKey: "topP", outputKey: "top_p" },
|
|
30635
|
+
{ camelCaseKey: "topK", optionKey: "topK", outputKey: "top_k" },
|
|
30636
|
+
{
|
|
30637
|
+
camelCaseKey: "frequencyPenalty",
|
|
30638
|
+
optionKey: "frequencyPenalty",
|
|
30639
|
+
outputKey: "frequency_penalty"
|
|
30640
|
+
},
|
|
30641
|
+
{ camelCaseKey: "presencePenalty", optionKey: "presencePenalty", outputKey: "presence_penalty" },
|
|
30642
|
+
{ camelCaseKey: "seed", optionKey: "seed", outputKey: "seed" },
|
|
30643
|
+
{ camelCaseKey: "parallel_tool_calls", outputKey: "parallel_tool_calls" }
|
|
30644
|
+
];
|
|
30579
30645
|
var StreamIdGenerator = class {
|
|
30580
30646
|
generateResponseId() {
|
|
30581
30647
|
return crypto.randomUUID();
|
|
@@ -30623,8 +30689,10 @@ var SAPAILanguageModel = class {
|
|
|
30623
30689
|
settings;
|
|
30624
30690
|
/**
|
|
30625
30691
|
* Creates a new SAP AI Language Model instance.
|
|
30626
|
-
*
|
|
30627
|
-
*
|
|
30692
|
+
*
|
|
30693
|
+
* This is the main implementation that handles all SAP AI Core orchestration logic.
|
|
30694
|
+
* @param modelId - The model identifier (e.g., 'gpt-4o', 'claude-3-5-sonnet', 'gemini-2.0-flash').
|
|
30695
|
+
* @param settings - Model configuration settings (temperature, max tokens, filtering, etc.).
|
|
30628
30696
|
* @param config - SAP AI Core deployment and destination configuration.
|
|
30629
30697
|
* @internal
|
|
30630
30698
|
*/
|
|
@@ -30638,83 +30706,23 @@ var SAPAILanguageModel = class {
|
|
|
30638
30706
|
}
|
|
30639
30707
|
/**
|
|
30640
30708
|
* Generates a single completion (non-streaming).
|
|
30641
|
-
*
|
|
30642
|
-
*
|
|
30643
|
-
*
|
|
30709
|
+
*
|
|
30710
|
+
* Builds orchestration configuration, converts messages, validates parameters,
|
|
30711
|
+
* calls SAP AI SDK, and processes the response.
|
|
30712
|
+
* Supports request cancellation via AbortSignal at the HTTP transport layer.
|
|
30713
|
+
* @param options - The Vercel AI SDK V3 generation call options.
|
|
30714
|
+
* @returns The generation result with content, usage, warnings, and provider metadata.
|
|
30644
30715
|
*/
|
|
30645
30716
|
async doGenerate(options) {
|
|
30646
30717
|
try {
|
|
30647
30718
|
const { messages, orchestrationConfig, warnings } = await this.buildOrchestrationConfig(options);
|
|
30648
30719
|
const client = this.createClient(orchestrationConfig);
|
|
30649
|
-
const
|
|
30650
|
-
const
|
|
30651
|
-
|
|
30652
|
-
|
|
30653
|
-
|
|
30654
|
-
|
|
30655
|
-
...promptTemplating.prompt.tools ? { tools: promptTemplating.prompt.tools } : {},
|
|
30656
|
-
...promptTemplating.prompt.response_format ? { response_format: promptTemplating.prompt.response_format } : {},
|
|
30657
|
-
...(() => {
|
|
30658
|
-
const masking = orchestrationConfig.masking;
|
|
30659
|
-
return masking && Object.keys(masking).length > 0 ? { masking } : {};
|
|
30660
|
-
})(),
|
|
30661
|
-
...(() => {
|
|
30662
|
-
const filtering = orchestrationConfig.filtering;
|
|
30663
|
-
return filtering && Object.keys(filtering).length > 0 ? { filtering } : {};
|
|
30664
|
-
})(),
|
|
30665
|
-
...(() => {
|
|
30666
|
-
const grounding = orchestrationConfig.grounding;
|
|
30667
|
-
return grounding && Object.keys(grounding).length > 0 ? { grounding } : {};
|
|
30668
|
-
})(),
|
|
30669
|
-
...(() => {
|
|
30670
|
-
const translation = orchestrationConfig.translation;
|
|
30671
|
-
return translation && Object.keys(translation).length > 0 ? { translation } : {};
|
|
30672
|
-
})()
|
|
30673
|
-
};
|
|
30674
|
-
const response = await (async () => {
|
|
30675
|
-
const completionPromise = client.chatCompletion(requestBody);
|
|
30676
|
-
if (options.abortSignal) {
|
|
30677
|
-
return Promise.race([
|
|
30678
|
-
completionPromise,
|
|
30679
|
-
new Promise((_, reject) => {
|
|
30680
|
-
if (options.abortSignal?.aborted) {
|
|
30681
|
-
reject(
|
|
30682
|
-
new Error(
|
|
30683
|
-
`Request aborted: ${String(options.abortSignal.reason ?? "unknown reason")}`
|
|
30684
|
-
)
|
|
30685
|
-
);
|
|
30686
|
-
return;
|
|
30687
|
-
}
|
|
30688
|
-
options.abortSignal?.addEventListener(
|
|
30689
|
-
"abort",
|
|
30690
|
-
() => {
|
|
30691
|
-
reject(
|
|
30692
|
-
new Error(
|
|
30693
|
-
`Request aborted: ${String(options.abortSignal?.reason ?? "unknown reason")}`
|
|
30694
|
-
)
|
|
30695
|
-
);
|
|
30696
|
-
},
|
|
30697
|
-
{ once: true }
|
|
30698
|
-
);
|
|
30699
|
-
})
|
|
30700
|
-
]);
|
|
30701
|
-
}
|
|
30702
|
-
return completionPromise;
|
|
30703
|
-
})();
|
|
30704
|
-
const responseHeadersRaw = response.rawResponse.headers;
|
|
30705
|
-
const responseHeaders = responseHeadersRaw ? Object.fromEntries(
|
|
30706
|
-
Object.entries(responseHeadersRaw).flatMap(([key, value]) => {
|
|
30707
|
-
if (typeof value === "string") return [[key, value]];
|
|
30708
|
-
if (Array.isArray(value)) {
|
|
30709
|
-
const strings = value.filter((item) => typeof item === "string").join("; ");
|
|
30710
|
-
return strings.length > 0 ? [[key, strings]] : [];
|
|
30711
|
-
}
|
|
30712
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
30713
|
-
return [[key, String(value)]];
|
|
30714
|
-
}
|
|
30715
|
-
return [];
|
|
30716
|
-
})
|
|
30717
|
-
) : void 0;
|
|
30720
|
+
const requestBody = this.buildRequestBody(messages, orchestrationConfig);
|
|
30721
|
+
const response = await client.chatCompletion(
|
|
30722
|
+
requestBody,
|
|
30723
|
+
options.abortSignal ? { signal: options.abortSignal } : void 0
|
|
30724
|
+
);
|
|
30725
|
+
const responseHeaders = normalizeHeaders(response.rawResponse.headers);
|
|
30718
30726
|
const content = [];
|
|
30719
30727
|
const textContent = response.getContent();
|
|
30720
30728
|
if (textContent) {
|
|
@@ -30788,31 +30796,18 @@ var SAPAILanguageModel = class {
|
|
|
30788
30796
|
}
|
|
30789
30797
|
/**
|
|
30790
30798
|
* Generates a streaming completion.
|
|
30791
|
-
*
|
|
30792
|
-
*
|
|
30799
|
+
*
|
|
30800
|
+
* Builds orchestration configuration, creates streaming client, and transforms
|
|
30801
|
+
* the stream with proper event handling (text blocks, tool calls, finish reason).
|
|
30802
|
+
* Supports request cancellation via AbortSignal at the HTTP transport layer.
|
|
30803
|
+
* @param options - The Vercel AI SDK V3 generation call options.
|
|
30793
30804
|
* @returns A stream result with async iterable stream parts.
|
|
30794
30805
|
*/
|
|
30795
30806
|
async doStream(options) {
|
|
30796
30807
|
try {
|
|
30797
30808
|
const { messages, orchestrationConfig, warnings } = await this.buildOrchestrationConfig(options);
|
|
30798
30809
|
const client = this.createClient(orchestrationConfig);
|
|
30799
|
-
const
|
|
30800
|
-
const requestBody = {
|
|
30801
|
-
messages,
|
|
30802
|
-
model: {
|
|
30803
|
-
...orchestrationConfig.promptTemplating.model
|
|
30804
|
-
},
|
|
30805
|
-
...promptTemplating.prompt.tools ? { tools: promptTemplating.prompt.tools } : {},
|
|
30806
|
-
...promptTemplating.prompt.response_format ? { response_format: promptTemplating.prompt.response_format } : {},
|
|
30807
|
-
...(() => {
|
|
30808
|
-
const masking = orchestrationConfig.masking;
|
|
30809
|
-
return masking && Object.keys(masking).length > 0 ? { masking } : {};
|
|
30810
|
-
})(),
|
|
30811
|
-
...(() => {
|
|
30812
|
-
const filtering = orchestrationConfig.filtering;
|
|
30813
|
-
return filtering && Object.keys(filtering).length > 0 ? { filtering } : {};
|
|
30814
|
-
})()
|
|
30815
|
-
};
|
|
30810
|
+
const requestBody = this.buildRequestBody(messages, orchestrationConfig);
|
|
30816
30811
|
const streamResponse = await client.stream(requestBody, options.abortSignal, {
|
|
30817
30812
|
promptTemplating: { include_usage: true }
|
|
30818
30813
|
});
|
|
@@ -31167,20 +31162,14 @@ var SAPAILanguageModel = class {
|
|
|
31167
31162
|
this.settings.modelParams ?? {},
|
|
31168
31163
|
sapOptions?.modelParams ?? {}
|
|
31169
31164
|
);
|
|
31170
|
-
|
|
31171
|
-
|
|
31172
|
-
|
|
31173
|
-
|
|
31174
|
-
|
|
31175
|
-
|
|
31176
|
-
if (options.
|
|
31177
|
-
|
|
31178
|
-
if (frequencyPenalty !== void 0) {
|
|
31179
|
-
modelParams.frequency_penalty = frequencyPenalty;
|
|
31180
|
-
}
|
|
31181
|
-
const presencePenalty = options.presencePenalty ?? sapOptions?.modelParams?.presencePenalty ?? this.settings.modelParams?.presencePenalty;
|
|
31182
|
-
if (presencePenalty !== void 0) {
|
|
31183
|
-
modelParams.presence_penalty = presencePenalty;
|
|
31165
|
+
applyParameterOverrides(
|
|
31166
|
+
modelParams,
|
|
31167
|
+
options,
|
|
31168
|
+
sapOptions?.modelParams,
|
|
31169
|
+
this.settings.modelParams
|
|
31170
|
+
);
|
|
31171
|
+
if (options.stopSequences && options.stopSequences.length > 0) {
|
|
31172
|
+
modelParams.stop = options.stopSequences;
|
|
31184
31173
|
}
|
|
31185
31174
|
if (supportsN) {
|
|
31186
31175
|
const nValue = sapOptions?.modelParams?.n ?? this.settings.modelParams?.n;
|
|
@@ -31190,16 +31179,6 @@ var SAPAILanguageModel = class {
|
|
|
31190
31179
|
} else {
|
|
31191
31180
|
delete modelParams.n;
|
|
31192
31181
|
}
|
|
31193
|
-
const parallelToolCalls = sapOptions?.modelParams?.parallel_tool_calls ?? this.settings.modelParams?.parallel_tool_calls;
|
|
31194
|
-
if (parallelToolCalls !== void 0) {
|
|
31195
|
-
modelParams.parallel_tool_calls = parallelToolCalls;
|
|
31196
|
-
}
|
|
31197
|
-
if (options.stopSequences && options.stopSequences.length > 0) {
|
|
31198
|
-
modelParams.stop = options.stopSequences;
|
|
31199
|
-
}
|
|
31200
|
-
if (options.seed !== void 0) {
|
|
31201
|
-
modelParams.seed = options.seed;
|
|
31202
|
-
}
|
|
31203
31182
|
validateModelParamsWithWarnings(
|
|
31204
31183
|
{
|
|
31205
31184
|
frequencyPenalty: options.frequencyPenalty,
|
|
@@ -31250,25 +31229,35 @@ var SAPAILanguageModel = class {
|
|
|
31250
31229
|
...responseFormat ? { response_format: responseFormat } : {}
|
|
31251
31230
|
}
|
|
31252
31231
|
},
|
|
31253
|
-
...(
|
|
31254
|
-
|
|
31255
|
-
|
|
31256
|
-
|
|
31257
|
-
...(() => {
|
|
31258
|
-
const filtering = this.settings.filtering;
|
|
31259
|
-
return filtering && Object.keys(filtering).length > 0 ? { filtering } : {};
|
|
31260
|
-
})(),
|
|
31261
|
-
...(() => {
|
|
31262
|
-
const grounding = this.settings.grounding;
|
|
31263
|
-
return grounding && Object.keys(grounding).length > 0 ? { grounding } : {};
|
|
31264
|
-
})(),
|
|
31265
|
-
...(() => {
|
|
31266
|
-
const translation = this.settings.translation;
|
|
31267
|
-
return translation && Object.keys(translation).length > 0 ? { translation } : {};
|
|
31268
|
-
})()
|
|
31232
|
+
...this.settings.masking && Object.keys(this.settings.masking).length > 0 ? { masking: this.settings.masking } : {},
|
|
31233
|
+
...this.settings.filtering && Object.keys(this.settings.filtering).length > 0 ? { filtering: this.settings.filtering } : {},
|
|
31234
|
+
...this.settings.grounding && Object.keys(this.settings.grounding).length > 0 ? { grounding: this.settings.grounding } : {},
|
|
31235
|
+
...this.settings.translation && Object.keys(this.settings.translation).length > 0 ? { translation: this.settings.translation } : {}
|
|
31269
31236
|
};
|
|
31270
31237
|
return { messages, orchestrationConfig, warnings };
|
|
31271
31238
|
}
|
|
31239
|
+
/**
|
|
31240
|
+
* Builds the request body for SAP AI SDK chat completion or streaming.
|
|
31241
|
+
* @param messages - The chat messages to send.
|
|
31242
|
+
* @param orchestrationConfig - The orchestration configuration.
|
|
31243
|
+
* @returns The request body object.
|
|
31244
|
+
* @internal
|
|
31245
|
+
*/
|
|
31246
|
+
buildRequestBody(messages, orchestrationConfig) {
|
|
31247
|
+
const promptTemplating = orchestrationConfig.promptTemplating;
|
|
31248
|
+
return {
|
|
31249
|
+
messages,
|
|
31250
|
+
model: {
|
|
31251
|
+
...orchestrationConfig.promptTemplating.model
|
|
31252
|
+
},
|
|
31253
|
+
...promptTemplating.prompt.tools ? { tools: promptTemplating.prompt.tools } : {},
|
|
31254
|
+
...promptTemplating.prompt.response_format ? { response_format: promptTemplating.prompt.response_format } : {},
|
|
31255
|
+
...orchestrationConfig.masking && Object.keys(orchestrationConfig.masking).length > 0 ? { masking: orchestrationConfig.masking } : {},
|
|
31256
|
+
...orchestrationConfig.filtering && Object.keys(orchestrationConfig.filtering).length > 0 ? { filtering: orchestrationConfig.filtering } : {},
|
|
31257
|
+
...orchestrationConfig.grounding && Object.keys(orchestrationConfig.grounding).length > 0 ? { grounding: orchestrationConfig.grounding } : {},
|
|
31258
|
+
...orchestrationConfig.translation && Object.keys(orchestrationConfig.translation).length > 0 ? { translation: orchestrationConfig.translation } : {}
|
|
31259
|
+
};
|
|
31260
|
+
}
|
|
31272
31261
|
/**
|
|
31273
31262
|
* Creates an SAP AI SDK OrchestrationClient with the given configuration.
|
|
31274
31263
|
* @param config - The SAP AI SDK orchestration module configuration.
|
|
@@ -31279,6 +31268,18 @@ var SAPAILanguageModel = class {
|
|
|
31279
31268
|
return new import_orchestration2.OrchestrationClient(config, this.config.deploymentConfig, this.config.destination);
|
|
31280
31269
|
}
|
|
31281
31270
|
};
|
|
31271
|
+
function applyParameterOverrides(modelParams, options, sapModelParams, settingsModelParams) {
|
|
31272
|
+
const params = modelParams;
|
|
31273
|
+
for (const mapping of PARAM_MAPPINGS) {
|
|
31274
|
+
const value = (mapping.optionKey ? options[mapping.optionKey] : void 0) ?? (mapping.camelCaseKey ? sapModelParams?.[mapping.camelCaseKey] : void 0) ?? (mapping.camelCaseKey ? settingsModelParams?.[mapping.camelCaseKey] : void 0);
|
|
31275
|
+
if (value !== void 0) {
|
|
31276
|
+
params[mapping.outputKey] = value;
|
|
31277
|
+
}
|
|
31278
|
+
if (mapping.camelCaseKey && mapping.camelCaseKey !== mapping.outputKey) {
|
|
31279
|
+
Reflect.deleteProperty(params, mapping.camelCaseKey);
|
|
31280
|
+
}
|
|
31281
|
+
}
|
|
31282
|
+
}
|
|
31282
31283
|
function buildSAPToolParameters(schema) {
|
|
31283
31284
|
const schemaType = schema.type;
|
|
31284
31285
|
if (schemaType !== void 0 && schemaType !== "object") {
|
|
@@ -31356,6 +31357,8 @@ function mapFinishReason(reason) {
|
|
|
31356
31357
|
}
|
|
31357
31358
|
|
|
31358
31359
|
// src/sap-ai-provider.ts
|
|
31360
|
+
var import_provider4 = require("@ai-sdk/provider");
|
|
31361
|
+
var import_util2 = __toESM(require_dist(), 1);
|
|
31359
31362
|
function createSAPAIProvider(options = {}) {
|
|
31360
31363
|
if (options.defaultSettings?.modelParams) {
|
|
31361
31364
|
validateModelParamsSettings(options.defaultSettings.modelParams);
|
|
@@ -31368,6 +31371,10 @@ function createSAPAIProvider(options = {}) {
|
|
|
31368
31371
|
"createSAPAIProvider: both 'deploymentId' and 'resourceGroup' were provided; using 'deploymentId' and ignoring 'resourceGroup'."
|
|
31369
31372
|
);
|
|
31370
31373
|
}
|
|
31374
|
+
if (!process.env.SAP_CLOUD_SDK_LOG_LEVEL) {
|
|
31375
|
+
const logLevel = options.logLevel ?? "warn";
|
|
31376
|
+
(0, import_util2.setGlobalLogLevel)(logLevel);
|
|
31377
|
+
}
|
|
31371
31378
|
const deploymentConfig = options.deploymentId ? { deploymentId: options.deploymentId } : { resourceGroup };
|
|
31372
31379
|
const createModel = (modelId, settings = {}) => {
|
|
31373
31380
|
const mergedSettings = {
|
|
@@ -31431,6 +31438,7 @@ var import_orchestration5 = require("@sap-ai-sdk/orchestration");
|
|
|
31431
31438
|
OrchestrationStreamChunkResponse,
|
|
31432
31439
|
OrchestrationStreamResponse,
|
|
31433
31440
|
SAPAIEmbeddingModel,
|
|
31441
|
+
SAPAILanguageModel,
|
|
31434
31442
|
SAP_AI_PROVIDER_NAME,
|
|
31435
31443
|
buildAzureContentSafetyFilter,
|
|
31436
31444
|
buildDocumentGroundingConfig,
|
|
@@ -31439,7 +31447,6 @@ var import_orchestration5 = require("@sap-ai-sdk/orchestration");
|
|
|
31439
31447
|
buildTranslationConfig,
|
|
31440
31448
|
createSAPAIProvider,
|
|
31441
31449
|
getProviderName,
|
|
31442
|
-
isConfigReference,
|
|
31443
31450
|
sapAIEmbeddingProviderOptions,
|
|
31444
31451
|
sapAILanguageModelProviderOptions,
|
|
31445
31452
|
sapai
|