@jerome-benoit/sap-ai-provider 3.0.0 → 4.0.0-rc.1
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/README.md +60 -24
- package/dist/index.cjs +169 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -43
- package/dist/index.d.ts +76 -43
- package/dist/index.js +169 -64
- package/dist/index.js.map +1 -1
- package/package.json +7 -5
package/dist/index.js
CHANGED
|
@@ -24771,7 +24771,7 @@ var require_form_data = __commonJS({
|
|
|
24771
24771
|
var parseUrl = __require("url").parse;
|
|
24772
24772
|
var fs = __require("fs");
|
|
24773
24773
|
var Stream = __require("stream").Stream;
|
|
24774
|
-
var
|
|
24774
|
+
var crypto2 = __require("crypto");
|
|
24775
24775
|
var mime = require_mime_types();
|
|
24776
24776
|
var asynckit = require_asynckit();
|
|
24777
24777
|
var setToStringTag = require_es_set_tostringtag();
|
|
@@ -24977,7 +24977,7 @@ var require_form_data = __commonJS({
|
|
|
24977
24977
|
return Buffer.concat([dataBuffer, Buffer.from(this._lastBoundary())]);
|
|
24978
24978
|
};
|
|
24979
24979
|
FormData2.prototype._generateBoundary = function() {
|
|
24980
|
-
this._boundary = "--------------------------" +
|
|
24980
|
+
this._boundary = "--------------------------" + crypto2.randomBytes(12).toString("hex");
|
|
24981
24981
|
};
|
|
24982
24982
|
FormData2.prototype.getLengthSync = function() {
|
|
24983
24983
|
var knownLength = this._overheadLength + this._valueLength;
|
|
@@ -26207,7 +26207,7 @@ var require_axios = __commonJS({
|
|
|
26207
26207
|
"node_modules/axios/dist/node/axios.cjs"(exports, module) {
|
|
26208
26208
|
"use strict";
|
|
26209
26209
|
var FormData$1 = require_form_data();
|
|
26210
|
-
var
|
|
26210
|
+
var crypto2 = __require("crypto");
|
|
26211
26211
|
var url = __require("url");
|
|
26212
26212
|
var proxyFromEnv = require_proxy_from_env();
|
|
26213
26213
|
var http = __require("http");
|
|
@@ -26222,7 +26222,7 @@ var require_axios = __commonJS({
|
|
|
26222
26222
|
return e && typeof e === "object" && "default" in e ? e : { "default": e };
|
|
26223
26223
|
}
|
|
26224
26224
|
var FormData__default = /* @__PURE__ */ _interopDefaultLegacy(FormData$1);
|
|
26225
|
-
var crypto__default = /* @__PURE__ */ _interopDefaultLegacy(
|
|
26225
|
+
var crypto__default = /* @__PURE__ */ _interopDefaultLegacy(crypto2);
|
|
26226
26226
|
var url__default = /* @__PURE__ */ _interopDefaultLegacy(url);
|
|
26227
26227
|
var proxyFromEnv__default = /* @__PURE__ */ _interopDefaultLegacy(proxyFromEnv);
|
|
26228
26228
|
var http__default = /* @__PURE__ */ _interopDefaultLegacy(http);
|
|
@@ -29888,12 +29888,14 @@ function convertToSAPMessages(prompt, options = {}) {
|
|
|
29888
29888
|
}
|
|
29889
29889
|
case "tool": {
|
|
29890
29890
|
for (const part of message.content) {
|
|
29891
|
-
|
|
29892
|
-
|
|
29893
|
-
|
|
29894
|
-
|
|
29895
|
-
|
|
29896
|
-
|
|
29891
|
+
if (part.type === "tool-result") {
|
|
29892
|
+
const toolMessage = {
|
|
29893
|
+
role: "tool",
|
|
29894
|
+
tool_call_id: part.toolCallId,
|
|
29895
|
+
content: JSON.stringify(part.output)
|
|
29896
|
+
};
|
|
29897
|
+
messages.push(toolMessage);
|
|
29898
|
+
}
|
|
29897
29899
|
}
|
|
29898
29900
|
break;
|
|
29899
29901
|
}
|
|
@@ -30062,6 +30064,16 @@ See: https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-serv
|
|
|
30062
30064
|
}
|
|
30063
30065
|
|
|
30064
30066
|
// src/sap-ai-chat-language-model.ts
|
|
30067
|
+
var StreamIdGenerator = class {
|
|
30068
|
+
/**
|
|
30069
|
+
* Generates a unique ID for a text block.
|
|
30070
|
+
*
|
|
30071
|
+
* @returns RFC 4122-compliant UUID string
|
|
30072
|
+
*/
|
|
30073
|
+
generateTextBlockId() {
|
|
30074
|
+
return crypto.randomUUID();
|
|
30075
|
+
}
|
|
30076
|
+
};
|
|
30065
30077
|
function validateModelParameters(params, warnings) {
|
|
30066
30078
|
if (params.temperature !== void 0 && (params.temperature < 0 || params.temperature > 2)) {
|
|
30067
30079
|
warnings.push({
|
|
@@ -30153,7 +30165,7 @@ function buildSAPToolParameters(schema) {
|
|
|
30153
30165
|
};
|
|
30154
30166
|
}
|
|
30155
30167
|
var SAPAIChatLanguageModel = class {
|
|
30156
|
-
specificationVersion = "
|
|
30168
|
+
specificationVersion = "v3";
|
|
30157
30169
|
modelId;
|
|
30158
30170
|
config;
|
|
30159
30171
|
settings;
|
|
@@ -30176,10 +30188,14 @@ var SAPAIChatLanguageModel = class {
|
|
|
30176
30188
|
* Checks if a URL is supported for file/image uploads.
|
|
30177
30189
|
*
|
|
30178
30190
|
* @param url - The URL to check
|
|
30179
|
-
* @returns True if the URL protocol is HTTPS or data
|
|
30191
|
+
* @returns True if the URL protocol is HTTPS or data with valid image format
|
|
30180
30192
|
*/
|
|
30181
30193
|
supportsUrl(url) {
|
|
30182
|
-
|
|
30194
|
+
if (url.protocol === "https:") return true;
|
|
30195
|
+
if (url.protocol === "data:") {
|
|
30196
|
+
return /^data:image\//i.test(url.href);
|
|
30197
|
+
}
|
|
30198
|
+
return false;
|
|
30183
30199
|
}
|
|
30184
30200
|
/**
|
|
30185
30201
|
* Returns supported URL patterns for different content types.
|
|
@@ -30192,9 +30208,45 @@ var SAPAIChatLanguageModel = class {
|
|
|
30192
30208
|
};
|
|
30193
30209
|
}
|
|
30194
30210
|
/**
|
|
30195
|
-
*
|
|
30211
|
+
* Generates text completion using SAP AI Core's Orchestration API.
|
|
30212
|
+
*
|
|
30213
|
+
* This method implements the `LanguageModelV3.doGenerate` interface,
|
|
30214
|
+
* providing synchronous (non-streaming) text generation with support for:
|
|
30215
|
+
* - Multi-turn conversations with system/user/assistant messages
|
|
30216
|
+
* - Tool calling (function calling) with structured outputs
|
|
30217
|
+
* - Multi-modal inputs (text + images)
|
|
30218
|
+
* - Data masking via SAP DPI
|
|
30219
|
+
* - Content filtering via Azure Content Safety or Llama Guard
|
|
30220
|
+
*
|
|
30221
|
+
* **Return Structure:**
|
|
30222
|
+
* - Finish reason: `{ unified: string, raw?: string }`
|
|
30223
|
+
* - Usage: Nested structure with token breakdown `{ inputTokens: { total, ... }, outputTokens: { total, ... } }`
|
|
30224
|
+
* - Warnings: Array of warnings with `type` and optional `feature` field
|
|
30225
|
+
*
|
|
30226
|
+
* @param options - Generation options including prompt, tools, temperature, etc.
|
|
30227
|
+
* @returns Promise resolving to generation result with content, usage, and metadata
|
|
30228
|
+
*
|
|
30229
|
+
* @throws {InvalidPromptError} If prompt format is invalid
|
|
30230
|
+
* @throws {InvalidArgumentError} If arguments are malformed
|
|
30231
|
+
* @throws {APICallError} If the SAP AI Core API call fails
|
|
30232
|
+
*
|
|
30233
|
+
* @example
|
|
30234
|
+
* ```typescript
|
|
30235
|
+
* const result = await model.doGenerate({
|
|
30236
|
+
* prompt: [
|
|
30237
|
+
* { role: 'user', content: [{ type: 'text', text: 'Hello!' }] }
|
|
30238
|
+
* ],
|
|
30239
|
+
* temperature: 0.7,
|
|
30240
|
+
* maxTokens: 100
|
|
30241
|
+
* });
|
|
30242
|
+
*
|
|
30243
|
+
* console.log(result.content); // Array of V3 content parts
|
|
30244
|
+
* console.log(result.finishReason.unified); // "stop", "length", "tool-calls", etc.
|
|
30245
|
+
* console.log(result.usage.inputTokens.total); // Total input tokens
|
|
30246
|
+
* ```
|
|
30196
30247
|
*
|
|
30197
|
-
* @
|
|
30248
|
+
* @since 1.0.0
|
|
30249
|
+
* @since 4.0.0 Updated to LanguageModelV3 interface
|
|
30198
30250
|
*/
|
|
30199
30251
|
get provider() {
|
|
30200
30252
|
return this.config.provider;
|
|
@@ -30261,11 +30313,11 @@ var SAPAIChatLanguageModel = class {
|
|
|
30261
30313
|
const schemaRecord = jsonSchema;
|
|
30262
30314
|
delete schemaRecord.$schema;
|
|
30263
30315
|
parameters = buildSAPToolParameters(schemaRecord);
|
|
30264
|
-
} catch {
|
|
30316
|
+
} catch (error) {
|
|
30265
30317
|
warnings.push({
|
|
30266
|
-
type: "unsupported
|
|
30267
|
-
tool
|
|
30268
|
-
details:
|
|
30318
|
+
type: "unsupported",
|
|
30319
|
+
feature: `tool schema conversion for ${tool.name}`,
|
|
30320
|
+
details: `Failed to convert tool Zod schema: ${error instanceof Error ? error.message : String(error)}. Falling back to empty object schema.`
|
|
30269
30321
|
});
|
|
30270
30322
|
parameters = buildSAPToolParameters({});
|
|
30271
30323
|
}
|
|
@@ -30289,8 +30341,9 @@ var SAPAIChatLanguageModel = class {
|
|
|
30289
30341
|
};
|
|
30290
30342
|
} else {
|
|
30291
30343
|
warnings.push({
|
|
30292
|
-
type: "unsupported
|
|
30293
|
-
tool
|
|
30344
|
+
type: "unsupported",
|
|
30345
|
+
feature: `tool type for ${tool.name}`,
|
|
30346
|
+
details: "Only 'function' tool type is supported."
|
|
30294
30347
|
});
|
|
30295
30348
|
return null;
|
|
30296
30349
|
}
|
|
@@ -30342,8 +30395,8 @@ var SAPAIChatLanguageModel = class {
|
|
|
30342
30395
|
);
|
|
30343
30396
|
if (options.toolChoice && options.toolChoice.type !== "auto") {
|
|
30344
30397
|
warnings.push({
|
|
30345
|
-
type: "unsupported
|
|
30346
|
-
|
|
30398
|
+
type: "unsupported",
|
|
30399
|
+
feature: "toolChoice",
|
|
30347
30400
|
details: `SAP AI SDK does not support toolChoice '${options.toolChoice.type}'. Using default 'auto' behavior.`
|
|
30348
30401
|
});
|
|
30349
30402
|
}
|
|
@@ -30403,7 +30456,7 @@ var SAPAIChatLanguageModel = class {
|
|
|
30403
30456
|
/**
|
|
30404
30457
|
* Generates a single completion (non-streaming).
|
|
30405
30458
|
*
|
|
30406
|
-
* This method implements the `
|
|
30459
|
+
* This method implements the `LanguageModelV3.doGenerate` interface,
|
|
30407
30460
|
* sending a request to SAP AI Core and returning the complete response.
|
|
30408
30461
|
*
|
|
30409
30462
|
* **Features:**
|
|
@@ -30411,6 +30464,13 @@ var SAPAIChatLanguageModel = class {
|
|
|
30411
30464
|
* - Multi-modal input (text + images)
|
|
30412
30465
|
* - Data masking (if configured)
|
|
30413
30466
|
* - Content filtering (if configured)
|
|
30467
|
+
* - Abort signal support (via Promise.race)
|
|
30468
|
+
*
|
|
30469
|
+
* **Note on Abort Signal:**
|
|
30470
|
+
* The abort signal implementation uses Promise.race to reject the promise when
|
|
30471
|
+
* the signal is aborted. However, this does not cancel the underlying HTTP request
|
|
30472
|
+
* to SAP AI Core - the request continues executing on the server. This is a
|
|
30473
|
+
* limitation of the SAP AI SDK's chatCompletion API.
|
|
30414
30474
|
*
|
|
30415
30475
|
* @param options - Generation options including prompt, tools, and settings
|
|
30416
30476
|
* @returns Promise resolving to the generation result with content, usage, and metadata
|
|
@@ -30483,7 +30543,7 @@ var SAPAIChatLanguageModel = class {
|
|
|
30483
30543
|
Object.entries(responseHeadersRaw).flatMap(([key, value]) => {
|
|
30484
30544
|
if (typeof value === "string") return [[key, value]];
|
|
30485
30545
|
if (Array.isArray(value)) {
|
|
30486
|
-
const strings = value.filter((item) => typeof item === "string").join("
|
|
30546
|
+
const strings = value.filter((item) => typeof item === "string").join("; ");
|
|
30487
30547
|
return strings.length > 0 ? [[key, strings]] : [];
|
|
30488
30548
|
}
|
|
30489
30549
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
@@ -30524,9 +30584,17 @@ var SAPAIChatLanguageModel = class {
|
|
|
30524
30584
|
content,
|
|
30525
30585
|
finishReason,
|
|
30526
30586
|
usage: {
|
|
30527
|
-
inputTokens:
|
|
30528
|
-
|
|
30529
|
-
|
|
30587
|
+
inputTokens: {
|
|
30588
|
+
total: tokenUsage.prompt_tokens,
|
|
30589
|
+
noCache: tokenUsage.prompt_tokens,
|
|
30590
|
+
cacheRead: void 0,
|
|
30591
|
+
cacheWrite: void 0
|
|
30592
|
+
},
|
|
30593
|
+
outputTokens: {
|
|
30594
|
+
total: tokenUsage.completion_tokens,
|
|
30595
|
+
text: tokenUsage.completion_tokens,
|
|
30596
|
+
reasoning: void 0
|
|
30597
|
+
}
|
|
30530
30598
|
},
|
|
30531
30599
|
providerMetadata: {
|
|
30532
30600
|
"sap-ai": {
|
|
@@ -30557,19 +30625,28 @@ var SAPAIChatLanguageModel = class {
|
|
|
30557
30625
|
/**
|
|
30558
30626
|
* Generates a streaming completion.
|
|
30559
30627
|
*
|
|
30560
|
-
* This method implements the `
|
|
30628
|
+
* This method implements the `LanguageModelV3.doStream` interface,
|
|
30561
30629
|
* sending a streaming request to SAP AI Core and returning a stream of response parts.
|
|
30562
30630
|
*
|
|
30563
30631
|
* **Stream Events:**
|
|
30564
|
-
* - `stream-start` - Stream initialization
|
|
30632
|
+
* - `stream-start` - Stream initialization with warnings
|
|
30565
30633
|
* - `response-metadata` - Response metadata (model, timestamp)
|
|
30566
|
-
* - `text-start` - Text
|
|
30567
|
-
* - `text-delta` - Incremental text chunks
|
|
30568
|
-
* - `text-end` - Text
|
|
30569
|
-
* - `tool-
|
|
30634
|
+
* - `text-start` - Text block begins (with unique ID)
|
|
30635
|
+
* - `text-delta` - Incremental text chunks (with block ID)
|
|
30636
|
+
* - `text-end` - Text block completes (with accumulated text)
|
|
30637
|
+
* - `tool-input-start` - Tool input begins
|
|
30638
|
+
* - `tool-input-delta` - Tool input chunk
|
|
30639
|
+
* - `tool-input-end` - Tool input completes
|
|
30640
|
+
* - `tool-call` - Complete tool call
|
|
30570
30641
|
* - `finish` - Stream completes with usage and finish reason
|
|
30571
30642
|
* - `error` - Error occurred
|
|
30572
30643
|
*
|
|
30644
|
+
* **Stream Structure:**
|
|
30645
|
+
* - Text blocks have explicit lifecycle with unique IDs
|
|
30646
|
+
* - Finish reason format: `{ unified: string, raw?: string }`
|
|
30647
|
+
* - Usage format: `{ inputTokens: { total, ... }, outputTokens: { total, ... } }`
|
|
30648
|
+
* - Warnings only in `stream-start` event
|
|
30649
|
+
*
|
|
30573
30650
|
* @param options - Streaming options including prompt, tools, and settings
|
|
30574
30651
|
* @returns Promise resolving to stream and request metadata
|
|
30575
30652
|
*
|
|
@@ -30585,8 +30662,13 @@ var SAPAIChatLanguageModel = class {
|
|
|
30585
30662
|
* if (part.type === 'text-delta') {
|
|
30586
30663
|
* process.stdout.write(part.delta);
|
|
30587
30664
|
* }
|
|
30665
|
+
* if (part.type === 'text-end') {
|
|
30666
|
+
* console.log('Block complete:', part.id, part.text);
|
|
30667
|
+
* }
|
|
30588
30668
|
* }
|
|
30589
30669
|
* ```
|
|
30670
|
+
*
|
|
30671
|
+
* @since 4.0.0
|
|
30590
30672
|
*/
|
|
30591
30673
|
async doStream(options) {
|
|
30592
30674
|
try {
|
|
@@ -30614,12 +30696,25 @@ var SAPAIChatLanguageModel = class {
|
|
|
30614
30696
|
options.abortSignal,
|
|
30615
30697
|
{ promptTemplating: { include_usage: true } }
|
|
30616
30698
|
);
|
|
30699
|
+
const idGenerator = new StreamIdGenerator();
|
|
30700
|
+
let textBlockId = null;
|
|
30617
30701
|
const streamState = {
|
|
30618
|
-
finishReason:
|
|
30702
|
+
finishReason: {
|
|
30703
|
+
unified: "other",
|
|
30704
|
+
raw: void 0
|
|
30705
|
+
},
|
|
30619
30706
|
usage: {
|
|
30620
|
-
inputTokens:
|
|
30621
|
-
|
|
30622
|
-
|
|
30707
|
+
inputTokens: {
|
|
30708
|
+
total: void 0,
|
|
30709
|
+
noCache: void 0,
|
|
30710
|
+
cacheRead: void 0,
|
|
30711
|
+
cacheWrite: void 0
|
|
30712
|
+
},
|
|
30713
|
+
outputTokens: {
|
|
30714
|
+
total: void 0,
|
|
30715
|
+
text: void 0,
|
|
30716
|
+
reasoning: void 0
|
|
30717
|
+
}
|
|
30623
30718
|
},
|
|
30624
30719
|
isFirstChunk: true,
|
|
30625
30720
|
activeText: false
|
|
@@ -30647,19 +30742,25 @@ var SAPAIChatLanguageModel = class {
|
|
|
30647
30742
|
}
|
|
30648
30743
|
const deltaToolCalls = chunk.getDeltaToolCalls();
|
|
30649
30744
|
if (Array.isArray(deltaToolCalls) && deltaToolCalls.length > 0) {
|
|
30650
|
-
streamState.finishReason =
|
|
30745
|
+
streamState.finishReason = {
|
|
30746
|
+
unified: "tool-calls",
|
|
30747
|
+
raw: void 0
|
|
30748
|
+
};
|
|
30651
30749
|
}
|
|
30652
30750
|
const deltaContent = chunk.getDeltaContent();
|
|
30653
|
-
if (typeof deltaContent === "string" && deltaContent.length > 0 && streamState.finishReason !== "tool-calls") {
|
|
30751
|
+
if (typeof deltaContent === "string" && deltaContent.length > 0 && streamState.finishReason.unified !== "tool-calls") {
|
|
30654
30752
|
if (!streamState.activeText) {
|
|
30655
|
-
|
|
30753
|
+
textBlockId = idGenerator.generateTextBlockId();
|
|
30754
|
+
controller.enqueue({ type: "text-start", id: textBlockId });
|
|
30656
30755
|
streamState.activeText = true;
|
|
30657
30756
|
}
|
|
30658
|
-
|
|
30659
|
-
|
|
30660
|
-
|
|
30661
|
-
|
|
30662
|
-
|
|
30757
|
+
if (textBlockId) {
|
|
30758
|
+
controller.enqueue({
|
|
30759
|
+
type: "text-delta",
|
|
30760
|
+
id: textBlockId,
|
|
30761
|
+
delta: deltaContent
|
|
30762
|
+
});
|
|
30763
|
+
}
|
|
30663
30764
|
}
|
|
30664
30765
|
if (Array.isArray(deltaToolCalls) && deltaToolCalls.length > 0) {
|
|
30665
30766
|
for (const toolCallChunk of deltaToolCalls) {
|
|
@@ -30709,7 +30810,7 @@ var SAPAIChatLanguageModel = class {
|
|
|
30709
30810
|
const chunkFinishReason = chunk.getFinishReason();
|
|
30710
30811
|
if (chunkFinishReason) {
|
|
30711
30812
|
streamState.finishReason = mapFinishReason(chunkFinishReason);
|
|
30712
|
-
if (streamState.finishReason === "tool-calls") {
|
|
30813
|
+
if (streamState.finishReason.unified === "tool-calls") {
|
|
30713
30814
|
const toolCalls2 = Array.from(toolCallsInProgress.values());
|
|
30714
30815
|
for (const tc of toolCalls2) {
|
|
30715
30816
|
if (tc.didEmitCall) {
|
|
@@ -30738,8 +30839,8 @@ var SAPAIChatLanguageModel = class {
|
|
|
30738
30839
|
input: tc.arguments
|
|
30739
30840
|
});
|
|
30740
30841
|
}
|
|
30741
|
-
if (streamState.activeText) {
|
|
30742
|
-
controller.enqueue({ type: "text-end", id:
|
|
30842
|
+
if (streamState.activeText && textBlockId) {
|
|
30843
|
+
controller.enqueue({ type: "text-end", id: textBlockId });
|
|
30743
30844
|
streamState.activeText = false;
|
|
30744
30845
|
}
|
|
30745
30846
|
}
|
|
@@ -30775,20 +30876,24 @@ var SAPAIChatLanguageModel = class {
|
|
|
30775
30876
|
input: tc.arguments
|
|
30776
30877
|
});
|
|
30777
30878
|
}
|
|
30778
|
-
if (streamState.activeText) {
|
|
30779
|
-
controller.enqueue({ type: "text-end", id:
|
|
30879
|
+
if (streamState.activeText && textBlockId) {
|
|
30880
|
+
controller.enqueue({ type: "text-end", id: textBlockId });
|
|
30780
30881
|
}
|
|
30781
30882
|
const finalFinishReason = streamResponse.getFinishReason();
|
|
30782
30883
|
if (finalFinishReason) {
|
|
30783
30884
|
streamState.finishReason = mapFinishReason(finalFinishReason);
|
|
30784
30885
|
} else if (didEmitAnyToolCalls) {
|
|
30785
|
-
streamState.finishReason =
|
|
30886
|
+
streamState.finishReason = {
|
|
30887
|
+
unified: "tool-calls",
|
|
30888
|
+
raw: void 0
|
|
30889
|
+
};
|
|
30786
30890
|
}
|
|
30787
30891
|
const finalUsage = streamResponse.getTokenUsage();
|
|
30788
30892
|
if (finalUsage) {
|
|
30789
|
-
streamState.usage.inputTokens = finalUsage.prompt_tokens;
|
|
30790
|
-
streamState.usage.
|
|
30791
|
-
streamState.usage.
|
|
30893
|
+
streamState.usage.inputTokens.total = finalUsage.prompt_tokens;
|
|
30894
|
+
streamState.usage.inputTokens.noCache = finalUsage.prompt_tokens;
|
|
30895
|
+
streamState.usage.outputTokens.total = finalUsage.completion_tokens;
|
|
30896
|
+
streamState.usage.outputTokens.text = finalUsage.completion_tokens;
|
|
30792
30897
|
}
|
|
30793
30898
|
controller.enqueue({
|
|
30794
30899
|
type: "finish",
|
|
@@ -30819,8 +30924,7 @@ var SAPAIChatLanguageModel = class {
|
|
|
30819
30924
|
stream: transformedStream,
|
|
30820
30925
|
request: {
|
|
30821
30926
|
body: requestBody
|
|
30822
|
-
}
|
|
30823
|
-
warnings: warningsOut
|
|
30927
|
+
}
|
|
30824
30928
|
};
|
|
30825
30929
|
} catch (error) {
|
|
30826
30930
|
throw convertToAISDKError(error, {
|
|
@@ -30832,27 +30936,28 @@ var SAPAIChatLanguageModel = class {
|
|
|
30832
30936
|
}
|
|
30833
30937
|
};
|
|
30834
30938
|
function mapFinishReason(reason) {
|
|
30835
|
-
|
|
30939
|
+
const raw = reason;
|
|
30940
|
+
if (!reason) return { unified: "other", raw };
|
|
30836
30941
|
switch (reason.toLowerCase()) {
|
|
30837
30942
|
case "stop":
|
|
30838
30943
|
case "end_turn":
|
|
30839
30944
|
case "stop_sequence":
|
|
30840
30945
|
case "eos":
|
|
30841
|
-
return "stop";
|
|
30946
|
+
return { unified: "stop", raw };
|
|
30842
30947
|
case "length":
|
|
30843
30948
|
case "max_tokens":
|
|
30844
30949
|
case "max_tokens_reached":
|
|
30845
|
-
return "length";
|
|
30950
|
+
return { unified: "length", raw };
|
|
30846
30951
|
case "tool_calls":
|
|
30847
30952
|
case "tool_call":
|
|
30848
30953
|
case "function_call":
|
|
30849
|
-
return "tool-calls";
|
|
30954
|
+
return { unified: "tool-calls", raw };
|
|
30850
30955
|
case "content_filter":
|
|
30851
|
-
return "content-filter";
|
|
30956
|
+
return { unified: "content-filter", raw };
|
|
30852
30957
|
case "error":
|
|
30853
|
-
return "error";
|
|
30958
|
+
return { unified: "error", raw };
|
|
30854
30959
|
default:
|
|
30855
|
-
return "other";
|
|
30960
|
+
return { unified: "other", raw };
|
|
30856
30961
|
}
|
|
30857
30962
|
}
|
|
30858
30963
|
|