@databricks/ai-sdk-provider 0.2.3 → 0.3.0
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 +59 -49
- package/dist/index.cjs +332 -254
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -33
- package/dist/index.d.cts.map +1 -1
- package/dist/{index.d.ts → index.d.mts} +23 -34
- package/dist/index.d.mts.map +1 -0
- package/dist/{index.js → index.mjs} +293 -189
- package/dist/index.mjs.map +1 -0
- package/package.json +7 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -46,26 +46,6 @@ const chatAgentResponseSchema = z.object({
|
|
|
46
46
|
messages: z.array(chatAgentMessageSchema)
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
//#endregion
|
|
50
|
-
//#region src/tools.ts
|
|
51
|
-
const DATABRICKS_TOOL_CALL_ID = "databricks-tool-call";
|
|
52
|
-
/**
|
|
53
|
-
* The AI-SDK requires that tools used by the model are defined ahead of time.
|
|
54
|
-
*
|
|
55
|
-
* Since tool calls can be orchestrated by Databricks' agents we don't know the name, input, or output schemas
|
|
56
|
-
* of the tools until the model is called.
|
|
57
|
-
*
|
|
58
|
-
* In the DatabricksProvider we transform all tool calls to fit this definition, and keep the
|
|
59
|
-
* original name as part of the metadata. This allows us to parse any tool orchestrated by Databricks' agents,
|
|
60
|
-
* while still being able to render the tool call and result in the UI, and pass it back to the model with the correct name.
|
|
61
|
-
*/
|
|
62
|
-
const DATABRICKS_TOOL_DEFINITION = {
|
|
63
|
-
name: DATABRICKS_TOOL_CALL_ID,
|
|
64
|
-
description: "Databricks tool call",
|
|
65
|
-
inputSchema: z.any(),
|
|
66
|
-
outputSchema: z.any()
|
|
67
|
-
};
|
|
68
|
-
|
|
69
49
|
//#endregion
|
|
70
50
|
//#region src/chat-agent-language-model/chat-agent-convert-to-message-parts.ts
|
|
71
51
|
const convertChatAgentChunkToMessagePart = (chunk) => {
|
|
@@ -81,14 +61,16 @@ const convertChatAgentChunkToMessagePart = (chunk) => {
|
|
|
81
61
|
type: "tool-call",
|
|
82
62
|
toolCallId: toolCall.id,
|
|
83
63
|
input: toolCall.function.arguments,
|
|
84
|
-
toolName: toolCall.function.name
|
|
64
|
+
toolName: toolCall.function.name,
|
|
65
|
+
dynamic: true,
|
|
66
|
+
providerExecuted: true
|
|
85
67
|
});
|
|
86
68
|
});
|
|
87
69
|
} else if (chunk.delta.role === "tool") parts.push({
|
|
88
70
|
type: "tool-result",
|
|
89
71
|
toolCallId: chunk.delta.tool_call_id,
|
|
90
72
|
result: chunk.delta.content,
|
|
91
|
-
toolName:
|
|
73
|
+
toolName: chunk.delta.name ?? "unknown"
|
|
92
74
|
});
|
|
93
75
|
return parts;
|
|
94
76
|
};
|
|
@@ -103,20 +85,22 @@ const convertChatAgentResponseToMessagePart = (response) => {
|
|
|
103
85
|
type: "tool-call",
|
|
104
86
|
toolCallId: part.id,
|
|
105
87
|
input: part.function.arguments,
|
|
106
|
-
toolName: part.function.name
|
|
88
|
+
toolName: part.function.name,
|
|
89
|
+
dynamic: true,
|
|
90
|
+
providerExecuted: true
|
|
107
91
|
});
|
|
108
92
|
} else if (message.role === "tool") parts.push({
|
|
109
93
|
type: "tool-result",
|
|
110
94
|
toolCallId: message.tool_call_id,
|
|
111
95
|
result: message.content,
|
|
112
|
-
toolName:
|
|
96
|
+
toolName: message.name ?? "unknown"
|
|
113
97
|
});
|
|
114
98
|
return parts;
|
|
115
99
|
};
|
|
116
100
|
|
|
117
101
|
//#endregion
|
|
118
102
|
//#region src/chat-agent-language-model/chat-agent-convert-to-input.ts
|
|
119
|
-
const
|
|
103
|
+
const convertLanguageModelV3PromptToChatAgentResponse = (prompt) => {
|
|
120
104
|
const messages = [];
|
|
121
105
|
let messageIndex = 0;
|
|
122
106
|
for (const msg of prompt) switch (msg.role) {
|
|
@@ -143,10 +127,9 @@ const convertLanguageModelV2PromptToChatAgentResponse = (prompt) => {
|
|
|
143
127
|
return messages;
|
|
144
128
|
};
|
|
145
129
|
const convertUserMessage$1 = (msg, messageIndex) => {
|
|
146
|
-
const text = (msg.content ?? []).filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
|
147
130
|
return {
|
|
148
131
|
role: "user",
|
|
149
|
-
content: text,
|
|
132
|
+
content: (msg.content ?? []).filter((part) => part.type === "text").map((part) => part.text).join("\n"),
|
|
150
133
|
id: `user-${messageIndex}`
|
|
151
134
|
};
|
|
152
135
|
};
|
|
@@ -219,10 +202,7 @@ const convertToolResultOutput = (output) => {
|
|
|
219
202
|
function composeDatabricksStreamPartTransformers(...transformers) {
|
|
220
203
|
return (initialParts, last = null) => {
|
|
221
204
|
let currentParts = initialParts;
|
|
222
|
-
for (const fn of transformers)
|
|
223
|
-
const result = fn(currentParts, last);
|
|
224
|
-
currentParts = result.out;
|
|
225
|
-
}
|
|
205
|
+
for (const fn of transformers) currentParts = fn(currentParts, last).out;
|
|
226
206
|
return { out: currentParts };
|
|
227
207
|
};
|
|
228
208
|
}
|
|
@@ -239,8 +219,7 @@ const applyDeltaBoundaryTransform = (parts, last) => {
|
|
|
239
219
|
const incomingDeltaType = maybeGetDeltaType(incoming);
|
|
240
220
|
const incomingId = getPartId$1(incoming);
|
|
241
221
|
const lastId = getPartId$1(last);
|
|
242
|
-
|
|
243
|
-
if (incomingMatchesLast) {
|
|
222
|
+
if (Boolean(isDeltaPart(last) && isDeltaPart(incoming)) && Boolean(lastDeltaType && incomingDeltaType) && Boolean(lastDeltaType === incomingDeltaType) && Boolean(incomingId && lastId && incomingId === lastId)) {
|
|
244
223
|
out.push(incoming);
|
|
245
224
|
continue;
|
|
246
225
|
}
|
|
@@ -256,7 +235,6 @@ const applyDeltaBoundaryTransform = (parts, last) => {
|
|
|
256
235
|
continue;
|
|
257
236
|
}
|
|
258
237
|
out.push(incoming);
|
|
259
|
-
continue;
|
|
260
238
|
}
|
|
261
239
|
return { out };
|
|
262
240
|
};
|
|
@@ -275,7 +253,6 @@ const getDeltaType = (part) => {
|
|
|
275
253
|
const isDeltaPart = (part) => part?.type === "text-delta" || part?.type === "reasoning-delta";
|
|
276
254
|
const getPartId$1 = (part) => {
|
|
277
255
|
if (part && "id" in part) return part.id;
|
|
278
|
-
return void 0;
|
|
279
256
|
};
|
|
280
257
|
|
|
281
258
|
//#endregion
|
|
@@ -288,7 +265,7 @@ const getPartId$1 = (part) => {
|
|
|
288
265
|
*/
|
|
289
266
|
const getDatabricksLanguageModelTransformStream = () => {
|
|
290
267
|
let lastChunk = null;
|
|
291
|
-
const deltaEndByTypeAndId = new Set();
|
|
268
|
+
const deltaEndByTypeAndId = /* @__PURE__ */ new Set();
|
|
292
269
|
const transformerStreamParts = composeDatabricksStreamPartTransformers(applyDeltaBoundaryTransform);
|
|
293
270
|
return new TransformStream({
|
|
294
271
|
transform(chunk, controller) {
|
|
@@ -330,14 +307,13 @@ const getDeltaGroup = (type) => {
|
|
|
330
307
|
};
|
|
331
308
|
const getPartId = (part) => {
|
|
332
309
|
if ("id" in part) return part.id;
|
|
333
|
-
return void 0;
|
|
334
310
|
};
|
|
335
311
|
const makeEndKey = (id, group) => id && group ? `${group}:${id}` : null;
|
|
336
312
|
|
|
337
313
|
//#endregion
|
|
338
314
|
//#region src/chat-agent-language-model/chat-agent-language-model.ts
|
|
339
315
|
var DatabricksChatAgentLanguageModel = class {
|
|
340
|
-
specificationVersion = "
|
|
316
|
+
specificationVersion = "v3";
|
|
341
317
|
modelId;
|
|
342
318
|
config;
|
|
343
319
|
constructor(modelId, config) {
|
|
@@ -349,14 +325,13 @@ var DatabricksChatAgentLanguageModel = class {
|
|
|
349
325
|
}
|
|
350
326
|
supportedUrls = {};
|
|
351
327
|
async doGenerate(options) {
|
|
352
|
-
const networkArgs = this.getArgs({
|
|
353
|
-
config: this.config,
|
|
354
|
-
options,
|
|
355
|
-
stream: false,
|
|
356
|
-
modelId: this.modelId
|
|
357
|
-
});
|
|
358
328
|
const { value: response } = await postJsonToApi({
|
|
359
|
-
...
|
|
329
|
+
...this.getArgs({
|
|
330
|
+
config: this.config,
|
|
331
|
+
options,
|
|
332
|
+
stream: false,
|
|
333
|
+
modelId: this.modelId
|
|
334
|
+
}),
|
|
360
335
|
successfulResponseHandler: createJsonResponseHandler(chatAgentResponseSchema),
|
|
361
336
|
failedResponseHandler: createJsonErrorResponseHandler({
|
|
362
337
|
errorSchema: z.any(),
|
|
@@ -366,11 +341,22 @@ var DatabricksChatAgentLanguageModel = class {
|
|
|
366
341
|
});
|
|
367
342
|
return {
|
|
368
343
|
content: convertChatAgentResponseToMessagePart(response),
|
|
369
|
-
finishReason:
|
|
344
|
+
finishReason: {
|
|
345
|
+
raw: void 0,
|
|
346
|
+
unified: "stop"
|
|
347
|
+
},
|
|
370
348
|
usage: {
|
|
371
|
-
inputTokens:
|
|
372
|
-
|
|
373
|
-
|
|
349
|
+
inputTokens: {
|
|
350
|
+
total: 0,
|
|
351
|
+
noCache: 0,
|
|
352
|
+
cacheRead: 0,
|
|
353
|
+
cacheWrite: 0
|
|
354
|
+
},
|
|
355
|
+
outputTokens: {
|
|
356
|
+
total: 0,
|
|
357
|
+
text: 0,
|
|
358
|
+
reasoning: 0
|
|
359
|
+
}
|
|
374
360
|
},
|
|
375
361
|
warnings: []
|
|
376
362
|
};
|
|
@@ -391,7 +377,10 @@ var DatabricksChatAgentLanguageModel = class {
|
|
|
391
377
|
}),
|
|
392
378
|
successfulResponseHandler: createEventSourceResponseHandler(chatAgentChunkSchema)
|
|
393
379
|
});
|
|
394
|
-
let finishReason =
|
|
380
|
+
let finishReason = {
|
|
381
|
+
raw: void 0,
|
|
382
|
+
unified: "other"
|
|
383
|
+
};
|
|
395
384
|
return {
|
|
396
385
|
stream: response.pipeThrough(new TransformStream({
|
|
397
386
|
start(controller) {
|
|
@@ -406,7 +395,10 @@ var DatabricksChatAgentLanguageModel = class {
|
|
|
406
395
|
rawValue: chunk.rawValue
|
|
407
396
|
});
|
|
408
397
|
if (!chunk.success) {
|
|
409
|
-
finishReason =
|
|
398
|
+
finishReason = {
|
|
399
|
+
raw: void 0,
|
|
400
|
+
unified: "error"
|
|
401
|
+
};
|
|
410
402
|
controller.enqueue({
|
|
411
403
|
type: "error",
|
|
412
404
|
error: chunk.error
|
|
@@ -421,9 +413,17 @@ var DatabricksChatAgentLanguageModel = class {
|
|
|
421
413
|
type: "finish",
|
|
422
414
|
finishReason,
|
|
423
415
|
usage: {
|
|
424
|
-
inputTokens:
|
|
425
|
-
|
|
426
|
-
|
|
416
|
+
inputTokens: {
|
|
417
|
+
total: 0,
|
|
418
|
+
noCache: 0,
|
|
419
|
+
cacheRead: 0,
|
|
420
|
+
cacheWrite: 0
|
|
421
|
+
},
|
|
422
|
+
outputTokens: {
|
|
423
|
+
total: 0,
|
|
424
|
+
text: 0,
|
|
425
|
+
reasoning: 0
|
|
426
|
+
}
|
|
427
427
|
}
|
|
428
428
|
});
|
|
429
429
|
}
|
|
@@ -437,7 +437,7 @@ var DatabricksChatAgentLanguageModel = class {
|
|
|
437
437
|
body: {
|
|
438
438
|
model: modelId,
|
|
439
439
|
stream,
|
|
440
|
-
messages:
|
|
440
|
+
messages: convertLanguageModelV3PromptToChatAgentResponse(options.prompt)
|
|
441
441
|
},
|
|
442
442
|
url: config.url({ path: "/completions" }),
|
|
443
443
|
headers: combineHeaders(config.headers(), options.headers),
|
|
@@ -668,7 +668,6 @@ function isMcpApprovalResponse(metadata) {
|
|
|
668
668
|
*/
|
|
669
669
|
function extractDatabricksMetadata(part) {
|
|
670
670
|
if ("callProviderMetadata" in part && part.callProviderMetadata?.databricks) return part.callProviderMetadata.databricks;
|
|
671
|
-
return void 0;
|
|
672
671
|
}
|
|
673
672
|
/**
|
|
674
673
|
* Extract the approval status boolean from an output object.
|
|
@@ -683,7 +682,6 @@ function extractDatabricksMetadata(part) {
|
|
|
683
682
|
*/
|
|
684
683
|
function extractApprovalStatus(output) {
|
|
685
684
|
if (isApprovalStatusOutput(output)) return output[MCP_APPROVAL_STATUS_KEY];
|
|
686
|
-
return void 0;
|
|
687
685
|
}
|
|
688
686
|
/**
|
|
689
687
|
* Extract approval status from a tool result's output value.
|
|
@@ -697,7 +695,6 @@ function extractApprovalStatusFromToolResult(output) {
|
|
|
697
695
|
const value = output.value[MCP_APPROVAL_STATUS_KEY];
|
|
698
696
|
if (typeof value === "boolean") return value;
|
|
699
697
|
}
|
|
700
|
-
return void 0;
|
|
701
698
|
}
|
|
702
699
|
/**
|
|
703
700
|
* Create an approval status output object.
|
|
@@ -733,7 +730,7 @@ function getMcpApprovalState(output) {
|
|
|
733
730
|
|
|
734
731
|
//#endregion
|
|
735
732
|
//#region src/responses-agent-language-model/responses-convert-to-message-parts.ts
|
|
736
|
-
const convertResponsesAgentChunkToMessagePart = (chunk) => {
|
|
733
|
+
const convertResponsesAgentChunkToMessagePart = (chunk, options = { useRemoteToolCalling: false }) => {
|
|
737
734
|
const parts = [];
|
|
738
735
|
if ("error" in chunk) {
|
|
739
736
|
parts.push({
|
|
@@ -763,12 +760,12 @@ const convertResponsesAgentChunkToMessagePart = (chunk) => {
|
|
|
763
760
|
parts.push({
|
|
764
761
|
type: "tool-result",
|
|
765
762
|
toolCallId: chunk.call_id,
|
|
766
|
-
result: chunk.output,
|
|
767
|
-
toolName:
|
|
763
|
+
result: chunk.output != null ? chunk.output : {},
|
|
764
|
+
toolName: options.toolNamesByCallId?.get(chunk.call_id) ?? "unknown"
|
|
768
765
|
});
|
|
769
766
|
break;
|
|
770
767
|
case "response.output_item.done":
|
|
771
|
-
parts.push(...convertOutputItemDone(chunk.item));
|
|
768
|
+
parts.push(...convertOutputItemDone(chunk.item, options));
|
|
772
769
|
break;
|
|
773
770
|
case "response.output_text.annotation.added":
|
|
774
771
|
parts.push({
|
|
@@ -789,7 +786,7 @@ const convertResponsesAgentChunkToMessagePart = (chunk) => {
|
|
|
789
786
|
}
|
|
790
787
|
return parts;
|
|
791
788
|
};
|
|
792
|
-
const convertOutputItemDone = (item) => {
|
|
789
|
+
const convertOutputItemDone = (item, options) => {
|
|
793
790
|
switch (item.type) {
|
|
794
791
|
case "message": {
|
|
795
792
|
const firstContent = item.content[0];
|
|
@@ -807,18 +804,19 @@ const convertOutputItemDone = (item) => {
|
|
|
807
804
|
case "function_call": return [{
|
|
808
805
|
type: "tool-call",
|
|
809
806
|
toolCallId: item.call_id,
|
|
810
|
-
toolName:
|
|
807
|
+
toolName: item.name,
|
|
811
808
|
input: item.arguments,
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
}
|
|
809
|
+
...options.useRemoteToolCalling && {
|
|
810
|
+
dynamic: true,
|
|
811
|
+
providerExecuted: true
|
|
812
|
+
},
|
|
813
|
+
providerMetadata: { databricks: { itemId: item.id } }
|
|
816
814
|
}];
|
|
817
815
|
case "function_call_output": return [{
|
|
818
816
|
type: "tool-result",
|
|
819
817
|
toolCallId: item.call_id,
|
|
820
|
-
result: item.output,
|
|
821
|
-
toolName:
|
|
818
|
+
result: item.output != null ? item.output : {},
|
|
819
|
+
toolName: options.toolNamesByCallId?.get(item.call_id) ?? "unknown"
|
|
822
820
|
}];
|
|
823
821
|
case "reasoning": {
|
|
824
822
|
const firstSummary = item.summary[0];
|
|
@@ -843,11 +841,14 @@ const convertOutputItemDone = (item) => {
|
|
|
843
841
|
case "mcp_approval_request": return [{
|
|
844
842
|
type: "tool-call",
|
|
845
843
|
toolCallId: item.id,
|
|
846
|
-
toolName:
|
|
844
|
+
toolName: item.name,
|
|
847
845
|
input: item.arguments,
|
|
846
|
+
...options.useRemoteToolCalling && {
|
|
847
|
+
dynamic: true,
|
|
848
|
+
providerExecuted: true
|
|
849
|
+
},
|
|
848
850
|
providerMetadata: { databricks: {
|
|
849
851
|
type: MCP_APPROVAL_REQUEST_TYPE,
|
|
850
|
-
toolName: item.name,
|
|
851
852
|
itemId: item.id,
|
|
852
853
|
serverLabel: item.server_label
|
|
853
854
|
} }
|
|
@@ -855,7 +856,7 @@ const convertOutputItemDone = (item) => {
|
|
|
855
856
|
case "mcp_approval_response": return [{
|
|
856
857
|
type: "tool-result",
|
|
857
858
|
toolCallId: item.approval_request_id,
|
|
858
|
-
toolName:
|
|
859
|
+
toolName: options.toolNamesByCallId?.get(item.approval_request_id) ?? "mcp_approval",
|
|
859
860
|
result: createApprovalStatusOutput(item.approve),
|
|
860
861
|
providerMetadata: { databricks: {
|
|
861
862
|
type: MCP_APPROVAL_RESPONSE_TYPE,
|
|
@@ -865,27 +866,30 @@ const convertOutputItemDone = (item) => {
|
|
|
865
866
|
default: return [];
|
|
866
867
|
}
|
|
867
868
|
};
|
|
868
|
-
const convertResponsesAgentResponseToMessagePart = (response) => {
|
|
869
|
+
const convertResponsesAgentResponseToMessagePart = (response, options = { useRemoteToolCalling: false }) => {
|
|
869
870
|
const parts = [];
|
|
871
|
+
const toolNamesByCallId = /* @__PURE__ */ new Map();
|
|
872
|
+
for (const output of response.output) if (output.type === "function_call") toolNamesByCallId.set(output.call_id, output.name);
|
|
873
|
+
else if (output.type === "mcp_approval_request") toolNamesByCallId.set(output.id, output.name);
|
|
870
874
|
for (const output of response.output) switch (output.type) {
|
|
871
|
-
case "message":
|
|
875
|
+
case "message":
|
|
872
876
|
for (const content of output.content) if (content.type === "output_text") parts.push({
|
|
873
877
|
type: "text",
|
|
874
878
|
text: content.text,
|
|
875
879
|
providerMetadata: { databricks: { itemId: output.id } }
|
|
876
880
|
});
|
|
877
881
|
break;
|
|
878
|
-
}
|
|
879
882
|
case "function_call":
|
|
880
883
|
parts.push({
|
|
881
884
|
type: "tool-call",
|
|
882
885
|
toolCallId: output.call_id,
|
|
883
|
-
toolName:
|
|
886
|
+
toolName: output.name,
|
|
884
887
|
input: output.arguments,
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
}
|
|
888
|
+
...options.useRemoteToolCalling && {
|
|
889
|
+
dynamic: true,
|
|
890
|
+
providerExecuted: true
|
|
891
|
+
},
|
|
892
|
+
providerMetadata: { databricks: { itemId: output.id } }
|
|
889
893
|
});
|
|
890
894
|
break;
|
|
891
895
|
case "reasoning":
|
|
@@ -900,18 +904,17 @@ const convertResponsesAgentResponseToMessagePart = (response) => {
|
|
|
900
904
|
type: "tool-result",
|
|
901
905
|
result: output.output,
|
|
902
906
|
toolCallId: output.call_id,
|
|
903
|
-
toolName:
|
|
907
|
+
toolName: toolNamesByCallId.get(output.call_id) ?? "unknown"
|
|
904
908
|
});
|
|
905
909
|
break;
|
|
906
910
|
case "mcp_approval_request":
|
|
907
911
|
parts.push({
|
|
908
912
|
type: "tool-call",
|
|
909
913
|
toolCallId: output.id,
|
|
910
|
-
toolName:
|
|
914
|
+
toolName: output.name,
|
|
911
915
|
input: output.arguments,
|
|
912
916
|
providerMetadata: { databricks: {
|
|
913
917
|
type: MCP_APPROVAL_REQUEST_TYPE,
|
|
914
|
-
toolName: output.name,
|
|
915
918
|
itemId: output.id,
|
|
916
919
|
serverLabel: output.server_label
|
|
917
920
|
} }
|
|
@@ -921,7 +924,7 @@ const convertResponsesAgentResponseToMessagePart = (response) => {
|
|
|
921
924
|
parts.push({
|
|
922
925
|
type: "tool-result",
|
|
923
926
|
toolCallId: output.approval_request_id,
|
|
924
|
-
toolName:
|
|
927
|
+
toolName: toolNamesByCallId.get(output.approval_request_id) ?? "mcp_approval",
|
|
925
928
|
result: createApprovalStatusOutput(output.approve),
|
|
926
929
|
providerMetadata: { databricks: {
|
|
927
930
|
type: MCP_APPROVAL_RESPONSE_TYPE,
|
|
@@ -944,7 +947,7 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
|
|
|
944
947
|
return reduction;
|
|
945
948
|
}, {});
|
|
946
949
|
for (const { role, content } of prompt) switch (role) {
|
|
947
|
-
case "system":
|
|
950
|
+
case "system":
|
|
948
951
|
switch (systemMessageMode) {
|
|
949
952
|
case "system":
|
|
950
953
|
input.push({
|
|
@@ -970,7 +973,6 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
|
|
|
970
973
|
}
|
|
971
974
|
}
|
|
972
975
|
break;
|
|
973
|
-
}
|
|
974
976
|
case "user":
|
|
975
977
|
input.push({
|
|
976
978
|
role: "user",
|
|
@@ -994,7 +996,7 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
|
|
|
994
996
|
});
|
|
995
997
|
const itemId = providerOptions?.itemId ?? void 0;
|
|
996
998
|
switch (part.type) {
|
|
997
|
-
case "text":
|
|
999
|
+
case "text":
|
|
998
1000
|
input.push({
|
|
999
1001
|
role: "assistant",
|
|
1000
1002
|
content: [{
|
|
@@ -1004,7 +1006,6 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
|
|
|
1004
1006
|
id: itemId
|
|
1005
1007
|
});
|
|
1006
1008
|
break;
|
|
1007
|
-
}
|
|
1008
1009
|
case "tool-call": {
|
|
1009
1010
|
const toolName = providerOptions?.toolName ?? part.toolName;
|
|
1010
1011
|
if (providerOptions?.type === MCP_APPROVAL_REQUEST_TYPE) {
|
|
@@ -1055,7 +1056,7 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
|
|
|
1055
1056
|
});
|
|
1056
1057
|
break;
|
|
1057
1058
|
}
|
|
1058
|
-
case "tool-result":
|
|
1059
|
+
case "tool-result":
|
|
1059
1060
|
if (providerOptions?.type === MCP_APPROVAL_RESPONSE_TYPE) {
|
|
1060
1061
|
const approvalRequestId = providerOptions?.approvalRequestId ?? part.toolCallId;
|
|
1061
1062
|
const approve = providerOptions?.approve ?? false;
|
|
@@ -1075,8 +1076,7 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
|
|
|
1075
1076
|
output: convertToolResultOutputToString(part.output)
|
|
1076
1077
|
});
|
|
1077
1078
|
break;
|
|
1078
|
-
|
|
1079
|
-
case "reasoning": {
|
|
1079
|
+
case "reasoning":
|
|
1080
1080
|
if (!itemId) break;
|
|
1081
1081
|
input.push({
|
|
1082
1082
|
type: "reasoning",
|
|
@@ -1087,7 +1087,6 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
|
|
|
1087
1087
|
id: itemId
|
|
1088
1088
|
});
|
|
1089
1089
|
break;
|
|
1090
|
-
}
|
|
1091
1090
|
}
|
|
1092
1091
|
}
|
|
1093
1092
|
break;
|
|
@@ -1115,7 +1114,10 @@ const convertToolResultOutputToString = (output) => {
|
|
|
1115
1114
|
switch (output.type) {
|
|
1116
1115
|
case "text":
|
|
1117
1116
|
case "error-text": return output.value;
|
|
1118
|
-
|
|
1117
|
+
case "execution-denied": return output.reason ?? "Execution denied";
|
|
1118
|
+
case "json":
|
|
1119
|
+
case "error-json":
|
|
1120
|
+
case "content": return JSON.stringify(output.value);
|
|
1119
1121
|
}
|
|
1120
1122
|
};
|
|
1121
1123
|
|
|
@@ -1133,7 +1135,7 @@ function prepareResponsesTools({ tools, toolChoice }) {
|
|
|
1133
1135
|
};
|
|
1134
1136
|
const responsesTools = [];
|
|
1135
1137
|
for (const tool of tools) {
|
|
1136
|
-
if (tool.type === "provider
|
|
1138
|
+
if (tool.type === "provider") continue;
|
|
1137
1139
|
responsesTools.push({
|
|
1138
1140
|
type: "function",
|
|
1139
1141
|
name: tool.name,
|
|
@@ -1145,14 +1147,13 @@ function prepareResponsesTools({ tools, toolChoice }) {
|
|
|
1145
1147
|
tools: void 0,
|
|
1146
1148
|
toolChoice: void 0
|
|
1147
1149
|
};
|
|
1148
|
-
const convertedToolChoice = convertResponsesToolChoice(toolChoice);
|
|
1149
1150
|
return {
|
|
1150
1151
|
tools: responsesTools,
|
|
1151
|
-
toolChoice:
|
|
1152
|
+
toolChoice: convertResponsesToolChoice(toolChoice)
|
|
1152
1153
|
};
|
|
1153
1154
|
}
|
|
1154
1155
|
function convertResponsesToolChoice(toolChoice) {
|
|
1155
|
-
if (!toolChoice) return
|
|
1156
|
+
if (!toolChoice) return;
|
|
1156
1157
|
switch (toolChoice.type) {
|
|
1157
1158
|
case "auto": return "auto";
|
|
1158
1159
|
case "none": return "none";
|
|
@@ -1161,14 +1162,14 @@ function convertResponsesToolChoice(toolChoice) {
|
|
|
1161
1162
|
type: "function",
|
|
1162
1163
|
name: toolChoice.toolName
|
|
1163
1164
|
};
|
|
1164
|
-
default: return
|
|
1165
|
+
default: return;
|
|
1165
1166
|
}
|
|
1166
1167
|
}
|
|
1167
1168
|
|
|
1168
1169
|
//#endregion
|
|
1169
1170
|
//#region src/responses-agent-language-model/call-options-to-responses-args.ts
|
|
1170
1171
|
/**
|
|
1171
|
-
* Converts AI SDK
|
|
1172
|
+
* Converts AI SDK LanguageModelV3CallOptions to Databricks Responses API body parameters.
|
|
1172
1173
|
*
|
|
1173
1174
|
* Inspired by the getArgs method in:
|
|
1174
1175
|
* https://github.com/vercel/ai/blob/main/packages/openai/src/responses/openai-responses-language-model.ts#L118
|
|
@@ -1180,28 +1181,28 @@ function callOptionsToResponsesArgs(options) {
|
|
|
1180
1181
|
const warnings = [];
|
|
1181
1182
|
const databricksOptions = options.providerOptions?.databricks;
|
|
1182
1183
|
if (options.topK != null) warnings.push({
|
|
1183
|
-
type: "unsupported
|
|
1184
|
-
|
|
1184
|
+
type: "unsupported",
|
|
1185
|
+
feature: "topK",
|
|
1185
1186
|
details: "topK is not supported by the Databricks Responses API"
|
|
1186
1187
|
});
|
|
1187
1188
|
if (options.presencePenalty != null) warnings.push({
|
|
1188
|
-
type: "unsupported
|
|
1189
|
-
|
|
1189
|
+
type: "unsupported",
|
|
1190
|
+
feature: "presencePenalty",
|
|
1190
1191
|
details: "presencePenalty is not supported by the Databricks Responses API"
|
|
1191
1192
|
});
|
|
1192
1193
|
if (options.frequencyPenalty != null) warnings.push({
|
|
1193
|
-
type: "unsupported
|
|
1194
|
-
|
|
1194
|
+
type: "unsupported",
|
|
1195
|
+
feature: "frequencyPenalty",
|
|
1195
1196
|
details: "frequencyPenalty is not supported by the Databricks Responses API"
|
|
1196
1197
|
});
|
|
1197
1198
|
if (options.seed != null) warnings.push({
|
|
1198
|
-
type: "unsupported
|
|
1199
|
-
|
|
1199
|
+
type: "unsupported",
|
|
1200
|
+
feature: "seed",
|
|
1200
1201
|
details: "seed is not supported by the Databricks Responses API"
|
|
1201
1202
|
});
|
|
1202
1203
|
if (options.stopSequences != null && options.stopSequences.length > 0) warnings.push({
|
|
1203
|
-
type: "unsupported
|
|
1204
|
-
|
|
1204
|
+
type: "unsupported",
|
|
1205
|
+
feature: "stopSequences",
|
|
1205
1206
|
details: "stopSequences is not supported by the Databricks Responses API"
|
|
1206
1207
|
});
|
|
1207
1208
|
const args = {};
|
|
@@ -1237,16 +1238,27 @@ function callOptionsToResponsesArgs(options) {
|
|
|
1237
1238
|
//#endregion
|
|
1238
1239
|
//#region src/responses-agent-language-model/responses-agent-language-model.ts
|
|
1239
1240
|
function mapResponsesFinishReason({ finishReason, hasToolCalls }) {
|
|
1241
|
+
let unified;
|
|
1240
1242
|
switch (finishReason) {
|
|
1241
1243
|
case void 0:
|
|
1242
|
-
case null:
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1244
|
+
case null:
|
|
1245
|
+
unified = hasToolCalls ? "tool-calls" : "stop";
|
|
1246
|
+
break;
|
|
1247
|
+
case "max_output_tokens":
|
|
1248
|
+
unified = "length";
|
|
1249
|
+
break;
|
|
1250
|
+
case "content_filter":
|
|
1251
|
+
unified = "content-filter";
|
|
1252
|
+
break;
|
|
1253
|
+
default: unified = hasToolCalls ? "tool-calls" : "other";
|
|
1246
1254
|
}
|
|
1255
|
+
return {
|
|
1256
|
+
raw: finishReason ?? void 0,
|
|
1257
|
+
unified
|
|
1258
|
+
};
|
|
1247
1259
|
}
|
|
1248
1260
|
var DatabricksResponsesAgentLanguageModel = class {
|
|
1249
|
-
specificationVersion = "
|
|
1261
|
+
specificationVersion = "v3";
|
|
1250
1262
|
modelId;
|
|
1251
1263
|
config;
|
|
1252
1264
|
constructor(modelId, config) {
|
|
@@ -1258,7 +1270,7 @@ var DatabricksResponsesAgentLanguageModel = class {
|
|
|
1258
1270
|
}
|
|
1259
1271
|
supportedUrls = {};
|
|
1260
1272
|
async doGenerate(options) {
|
|
1261
|
-
const { warnings
|
|
1273
|
+
const { warnings, ...networkArgs } = await this.getArgs({
|
|
1262
1274
|
config: this.config,
|
|
1263
1275
|
options,
|
|
1264
1276
|
stream: false,
|
|
@@ -1282,15 +1294,23 @@ var DatabricksResponsesAgentLanguageModel = class {
|
|
|
1282
1294
|
hasToolCalls
|
|
1283
1295
|
}),
|
|
1284
1296
|
usage: {
|
|
1285
|
-
inputTokens:
|
|
1286
|
-
|
|
1287
|
-
|
|
1297
|
+
inputTokens: {
|
|
1298
|
+
total: response.usage?.input_tokens ?? 0,
|
|
1299
|
+
noCache: 0,
|
|
1300
|
+
cacheRead: 0,
|
|
1301
|
+
cacheWrite: 0
|
|
1302
|
+
},
|
|
1303
|
+
outputTokens: {
|
|
1304
|
+
total: response.usage?.output_tokens ?? 0,
|
|
1305
|
+
text: 0,
|
|
1306
|
+
reasoning: 0
|
|
1307
|
+
}
|
|
1288
1308
|
},
|
|
1289
1309
|
warnings
|
|
1290
1310
|
};
|
|
1291
1311
|
}
|
|
1292
1312
|
async doStream(options) {
|
|
1293
|
-
const { warnings
|
|
1313
|
+
const { warnings, ...networkArgs } = await this.getArgs({
|
|
1294
1314
|
config: this.config,
|
|
1295
1315
|
options,
|
|
1296
1316
|
stream: true,
|
|
@@ -1306,13 +1326,26 @@ var DatabricksResponsesAgentLanguageModel = class {
|
|
|
1306
1326
|
successfulResponseHandler: createEventSourceResponseHandler(looseResponseAgentChunkSchema),
|
|
1307
1327
|
abortSignal: options.abortSignal
|
|
1308
1328
|
});
|
|
1309
|
-
let finishReason =
|
|
1329
|
+
let finishReason = {
|
|
1330
|
+
raw: void 0,
|
|
1331
|
+
unified: "stop"
|
|
1332
|
+
};
|
|
1310
1333
|
const usage = {
|
|
1311
|
-
inputTokens:
|
|
1312
|
-
|
|
1313
|
-
|
|
1334
|
+
inputTokens: {
|
|
1335
|
+
total: 0,
|
|
1336
|
+
noCache: 0,
|
|
1337
|
+
cacheRead: 0,
|
|
1338
|
+
cacheWrite: 0
|
|
1339
|
+
},
|
|
1340
|
+
outputTokens: {
|
|
1341
|
+
total: 0,
|
|
1342
|
+
text: 0,
|
|
1343
|
+
reasoning: 0
|
|
1344
|
+
}
|
|
1314
1345
|
};
|
|
1315
1346
|
const allParts = [];
|
|
1347
|
+
const useRemoteToolCalling = this.config.useRemoteToolCalling ?? false;
|
|
1348
|
+
const toolNamesByCallId = /* @__PURE__ */ new Map();
|
|
1316
1349
|
return {
|
|
1317
1350
|
stream: response.pipeThrough(new TransformStream({
|
|
1318
1351
|
start(controller) {
|
|
@@ -1327,7 +1360,10 @@ var DatabricksResponsesAgentLanguageModel = class {
|
|
|
1327
1360
|
rawValue: chunk.rawValue
|
|
1328
1361
|
});
|
|
1329
1362
|
if (!chunk.success) {
|
|
1330
|
-
finishReason =
|
|
1363
|
+
finishReason = {
|
|
1364
|
+
raw: void 0,
|
|
1365
|
+
unified: "error"
|
|
1366
|
+
};
|
|
1331
1367
|
controller.enqueue({
|
|
1332
1368
|
type: "error",
|
|
1333
1369
|
error: chunk.error
|
|
@@ -1340,12 +1376,15 @@ var DatabricksResponsesAgentLanguageModel = class {
|
|
|
1340
1376
|
finishReason: chunk.value.response.incomplete_details?.reason,
|
|
1341
1377
|
hasToolCalls
|
|
1342
1378
|
});
|
|
1343
|
-
usage.inputTokens = chunk.value.response.usage.input_tokens;
|
|
1344
|
-
usage.outputTokens = chunk.value.response.usage.output_tokens;
|
|
1345
|
-
usage.totalTokens = chunk.value.response.usage.total_tokens;
|
|
1379
|
+
usage.inputTokens.total = chunk.value.response.usage.input_tokens;
|
|
1380
|
+
usage.outputTokens.total = chunk.value.response.usage.output_tokens;
|
|
1346
1381
|
return;
|
|
1347
1382
|
}
|
|
1348
|
-
|
|
1383
|
+
if (chunk.value.type === "response.output_item.done" && chunk.value.item.type === "function_call") toolNamesByCallId.set(chunk.value.item.call_id, chunk.value.item.name);
|
|
1384
|
+
const parts = convertResponsesAgentChunkToMessagePart(chunk.value, {
|
|
1385
|
+
useRemoteToolCalling,
|
|
1386
|
+
toolNamesByCallId
|
|
1387
|
+
});
|
|
1349
1388
|
allParts.push(...parts);
|
|
1350
1389
|
/**
|
|
1351
1390
|
* Check if the last chunk was a tool result without a tool call
|
|
@@ -1360,19 +1399,33 @@ var DatabricksResponsesAgentLanguageModel = class {
|
|
|
1360
1399
|
if (!matchingToolCallInParts && !matchingToolCallInStream) {
|
|
1361
1400
|
const toolCallFromPreviousMessages = options.prompt.flatMap((message) => {
|
|
1362
1401
|
if (typeof message.content === "string") return [];
|
|
1363
|
-
return message.content;
|
|
1364
|
-
}).find((p) => p.
|
|
1402
|
+
return message.content.filter((p) => p.type === "tool-call");
|
|
1403
|
+
}).find((p) => p.toolCallId === part.toolCallId);
|
|
1365
1404
|
if (!toolCallFromPreviousMessages) throw new Error("No matching tool call found in previous message");
|
|
1366
|
-
|
|
1367
|
-
|
|
1405
|
+
controller.enqueue({
|
|
1406
|
+
type: "tool-call",
|
|
1407
|
+
toolCallId: toolCallFromPreviousMessages.toolCallId,
|
|
1408
|
+
toolName: toolCallFromPreviousMessages.toolName,
|
|
1368
1409
|
input: JSON.stringify(toolCallFromPreviousMessages.input)
|
|
1369
1410
|
});
|
|
1370
1411
|
}
|
|
1371
1412
|
}
|
|
1372
1413
|
if (shouldDedupeOutputItemDone(parts, allParts.slice(0, -parts.length))) return;
|
|
1373
|
-
for (const part
|
|
1414
|
+
for (const part of parts) controller.enqueue(part);
|
|
1374
1415
|
},
|
|
1375
1416
|
flush(controller) {
|
|
1417
|
+
if (!useRemoteToolCalling) {
|
|
1418
|
+
const toolCalls = allParts.filter((p) => p.type === "tool-call");
|
|
1419
|
+
const toolResults = allParts.filter((p) => p.type === "tool-result");
|
|
1420
|
+
for (const toolCall of toolCalls) {
|
|
1421
|
+
if (toolCall.providerMetadata?.databricks?.type === MCP_APPROVAL_REQUEST_TYPE) continue;
|
|
1422
|
+
if (!toolResults.some((r) => r.toolCallId === toolCall.toolCallId)) controller.enqueue({
|
|
1423
|
+
...toolCall,
|
|
1424
|
+
providerExecuted: true,
|
|
1425
|
+
dynamic: true
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1376
1429
|
controller.enqueue({
|
|
1377
1430
|
type: "finish",
|
|
1378
1431
|
finishReason,
|
|
@@ -1425,8 +1478,7 @@ function shouldDedupeOutputItemDone(incomingParts, previousParts) {
|
|
|
1425
1478
|
* corresponds to a specific message and we should only compare against text streamed for that message.
|
|
1426
1479
|
*/
|
|
1427
1480
|
const lastDoneIndex = previousParts.findLastIndex((part) => part.type === "text-delta" && part.providerMetadata?.databricks?.itemType === "response.output_item.done");
|
|
1428
|
-
const
|
|
1429
|
-
const { texts: reconstructuredTexts, current } = partsAfterLastDone.reduce((acc, part) => {
|
|
1481
|
+
const { texts: reconstructuredTexts, current } = previousParts.slice(lastDoneIndex + 1).reduce((acc, part) => {
|
|
1430
1482
|
if (part.type === "text-delta") return {
|
|
1431
1483
|
...acc,
|
|
1432
1484
|
current: acc.current + part.delta
|
|
@@ -1440,9 +1492,9 @@ function shouldDedupeOutputItemDone(incomingParts, previousParts) {
|
|
|
1440
1492
|
texts: [],
|
|
1441
1493
|
current: ""
|
|
1442
1494
|
});
|
|
1443
|
-
reconstructuredTexts.push(current);
|
|
1495
|
+
if (current.length > 0) reconstructuredTexts.push(current);
|
|
1444
1496
|
if (reconstructuredTexts.length === 0) return false;
|
|
1445
|
-
|
|
1497
|
+
return reconstructuredTexts.reduce((acc, text) => {
|
|
1446
1498
|
if (!acc.found) return acc;
|
|
1447
1499
|
const index = doneTextDelta.delta.indexOf(text, acc.lastIndex);
|
|
1448
1500
|
if (index === -1) return {
|
|
@@ -1456,8 +1508,7 @@ function shouldDedupeOutputItemDone(incomingParts, previousParts) {
|
|
|
1456
1508
|
}, {
|
|
1457
1509
|
found: true,
|
|
1458
1510
|
lastIndex: 0
|
|
1459
|
-
});
|
|
1460
|
-
return allTextsFoundInOrder.found;
|
|
1511
|
+
}).found;
|
|
1461
1512
|
}
|
|
1462
1513
|
|
|
1463
1514
|
//#endregion
|
|
@@ -1591,12 +1642,12 @@ const convertFmapiChunkToMessagePart = (chunk, toolCallIdsByIndex) => {
|
|
|
1591
1642
|
} else if (Array.isArray(choice.delta.content)) parts.push(...mapContentItemsToStreamParts(choice.delta.content, chunk.id));
|
|
1592
1643
|
return parts;
|
|
1593
1644
|
};
|
|
1594
|
-
const convertFmapiResponseToMessagePart = (response) => {
|
|
1645
|
+
const convertFmapiResponseToMessagePart = (response, options = { useRemoteToolCalling: false }) => {
|
|
1595
1646
|
const parts = [];
|
|
1596
1647
|
if (response.choices.length === 0) return parts;
|
|
1597
1648
|
const choice = response.choices[0];
|
|
1598
1649
|
if (choice.message.tool_calls && choice.message.tool_calls.length > 0) {
|
|
1599
|
-
for (const toolCall of choice.message.tool_calls) parts.push(convertToolCallToContent(toolCall));
|
|
1650
|
+
for (const toolCall of choice.message.tool_calls) parts.push(convertToolCallToContent(toolCall, options));
|
|
1600
1651
|
if (typeof choice.message.content === "string" && choice.message.content) parts.push({
|
|
1601
1652
|
type: "text",
|
|
1602
1653
|
text: choice.message.content
|
|
@@ -1610,13 +1661,16 @@ const convertFmapiResponseToMessagePart = (response) => {
|
|
|
1610
1661
|
else parts.push(...mapContentItemsToProviderContent(choice.message.content ?? []));
|
|
1611
1662
|
return parts;
|
|
1612
1663
|
};
|
|
1613
|
-
const convertToolCallToContent = (toolCall) => {
|
|
1664
|
+
const convertToolCallToContent = (toolCall, options) => {
|
|
1614
1665
|
return {
|
|
1615
1666
|
type: "tool-call",
|
|
1616
1667
|
toolCallId: toolCall.id,
|
|
1617
|
-
toolName:
|
|
1668
|
+
toolName: toolCall.function.name,
|
|
1618
1669
|
input: toolCall.function.arguments,
|
|
1619
|
-
|
|
1670
|
+
...options.useRemoteToolCalling && {
|
|
1671
|
+
dynamic: true,
|
|
1672
|
+
providerExecuted: true
|
|
1673
|
+
}
|
|
1620
1674
|
};
|
|
1621
1675
|
};
|
|
1622
1676
|
const mapContentItemsToStreamParts = (items, id) => {
|
|
@@ -1630,14 +1684,13 @@ const mapContentItemsToStreamParts = (items, id) => {
|
|
|
1630
1684
|
});
|
|
1631
1685
|
break;
|
|
1632
1686
|
case "image": break;
|
|
1633
|
-
case "reasoning":
|
|
1687
|
+
case "reasoning":
|
|
1634
1688
|
for (const summary of item.summary.filter((s) => s.type === "summary_text")) parts.push({
|
|
1635
1689
|
type: "reasoning-delta",
|
|
1636
1690
|
id,
|
|
1637
1691
|
delta: summary.text
|
|
1638
1692
|
});
|
|
1639
1693
|
break;
|
|
1640
|
-
}
|
|
1641
1694
|
}
|
|
1642
1695
|
return parts;
|
|
1643
1696
|
};
|
|
@@ -1651,13 +1704,12 @@ const mapContentItemsToProviderContent = (items) => {
|
|
|
1651
1704
|
});
|
|
1652
1705
|
break;
|
|
1653
1706
|
case "image": break;
|
|
1654
|
-
case "reasoning":
|
|
1707
|
+
case "reasoning":
|
|
1655
1708
|
for (const summary of item.summary.filter((s) => s.type === "summary_text")) parts.push({
|
|
1656
1709
|
type: "reasoning",
|
|
1657
1710
|
text: summary.text
|
|
1658
1711
|
});
|
|
1659
1712
|
break;
|
|
1660
|
-
}
|
|
1661
1713
|
}
|
|
1662
1714
|
return parts;
|
|
1663
1715
|
};
|
|
@@ -1793,31 +1845,45 @@ const convertToolResultOutputToContentValue = (output) => {
|
|
|
1793
1845
|
};
|
|
1794
1846
|
const ProviderOptionsSchema = z.object({ toolName: z.string().nullish() });
|
|
1795
1847
|
const getToolNameFromPart = async (part) => {
|
|
1796
|
-
|
|
1848
|
+
return (await parseProviderOptions({
|
|
1797
1849
|
provider: "databricks",
|
|
1798
1850
|
providerOptions: part.providerOptions,
|
|
1799
1851
|
schema: ProviderOptionsSchema
|
|
1800
|
-
});
|
|
1801
|
-
return providerOptions?.toolName ?? part.toolName;
|
|
1852
|
+
}))?.toolName ?? part.toolName;
|
|
1802
1853
|
};
|
|
1803
1854
|
|
|
1804
1855
|
//#endregion
|
|
1805
1856
|
//#region src/fmapi-language-model/fmapi-finish-reason.ts
|
|
1806
1857
|
function mapFmapiFinishReason(finishReason) {
|
|
1807
1858
|
switch (finishReason) {
|
|
1808
|
-
case "stop": return
|
|
1809
|
-
|
|
1810
|
-
|
|
1859
|
+
case "stop": return {
|
|
1860
|
+
raw: finishReason,
|
|
1861
|
+
unified: "stop"
|
|
1862
|
+
};
|
|
1863
|
+
case "length": return {
|
|
1864
|
+
raw: finishReason,
|
|
1865
|
+
unified: "length"
|
|
1866
|
+
};
|
|
1867
|
+
case "content_filter": return {
|
|
1868
|
+
raw: finishReason,
|
|
1869
|
+
unified: "content-filter"
|
|
1870
|
+
};
|
|
1811
1871
|
case "function_call":
|
|
1812
|
-
case "tool_calls": return
|
|
1813
|
-
|
|
1872
|
+
case "tool_calls": return {
|
|
1873
|
+
raw: finishReason,
|
|
1874
|
+
unified: "tool-calls"
|
|
1875
|
+
};
|
|
1876
|
+
default: return {
|
|
1877
|
+
raw: finishReason ?? void 0,
|
|
1878
|
+
unified: "other"
|
|
1879
|
+
};
|
|
1814
1880
|
}
|
|
1815
1881
|
}
|
|
1816
1882
|
|
|
1817
1883
|
//#endregion
|
|
1818
1884
|
//#region src/fmapi-language-model/call-options-to-fmapi-args.ts
|
|
1819
1885
|
/**
|
|
1820
|
-
* Converts AI SDK
|
|
1886
|
+
* Converts AI SDK LanguageModelV3CallOptions to Databricks FMAPI body parameters.
|
|
1821
1887
|
*
|
|
1822
1888
|
* Inspired by the getArgs method in:
|
|
1823
1889
|
* https://github.com/vercel/ai/blob/main/packages/openai/src/chat/openai-chat-language-model.ts#L71
|
|
@@ -1829,18 +1895,18 @@ function callOptionsToFmapiArgs(options) {
|
|
|
1829
1895
|
const warnings = [];
|
|
1830
1896
|
const databricksOptions = options.providerOptions?.databricks;
|
|
1831
1897
|
if (options.presencePenalty != null) warnings.push({
|
|
1832
|
-
type: "unsupported
|
|
1833
|
-
|
|
1898
|
+
type: "unsupported",
|
|
1899
|
+
feature: "presencePenalty",
|
|
1834
1900
|
details: "presencePenalty is not supported by the Databricks FMAPI"
|
|
1835
1901
|
});
|
|
1836
1902
|
if (options.frequencyPenalty != null) warnings.push({
|
|
1837
|
-
type: "unsupported
|
|
1838
|
-
|
|
1903
|
+
type: "unsupported",
|
|
1904
|
+
feature: "frequencyPenalty",
|
|
1839
1905
|
details: "frequencyPenalty is not supported by the Databricks FMAPI"
|
|
1840
1906
|
});
|
|
1841
1907
|
if (options.seed != null) warnings.push({
|
|
1842
|
-
type: "unsupported
|
|
1843
|
-
|
|
1908
|
+
type: "unsupported",
|
|
1909
|
+
feature: "seed",
|
|
1844
1910
|
details: "seed is not supported by the Databricks FMAPI"
|
|
1845
1911
|
});
|
|
1846
1912
|
const args = {};
|
|
@@ -1880,7 +1946,7 @@ function callOptionsToFmapiArgs(options) {
|
|
|
1880
1946
|
//#endregion
|
|
1881
1947
|
//#region src/fmapi-language-model/fmapi-language-model.ts
|
|
1882
1948
|
var DatabricksFmapiLanguageModel = class {
|
|
1883
|
-
specificationVersion = "
|
|
1949
|
+
specificationVersion = "v3";
|
|
1884
1950
|
modelId;
|
|
1885
1951
|
config;
|
|
1886
1952
|
constructor(modelId, config) {
|
|
@@ -1892,7 +1958,7 @@ var DatabricksFmapiLanguageModel = class {
|
|
|
1892
1958
|
}
|
|
1893
1959
|
supportedUrls = {};
|
|
1894
1960
|
async doGenerate(options) {
|
|
1895
|
-
const { warnings
|
|
1961
|
+
const { warnings, ...networkArgs } = await this.getArgs({
|
|
1896
1962
|
config: this.config,
|
|
1897
1963
|
options,
|
|
1898
1964
|
stream: false,
|
|
@@ -1910,18 +1976,26 @@ var DatabricksFmapiLanguageModel = class {
|
|
|
1910
1976
|
const choice = response.choices[0];
|
|
1911
1977
|
const finishReason = mapFmapiFinishReason(choice?.finish_reason);
|
|
1912
1978
|
return {
|
|
1913
|
-
content: convertFmapiResponseToMessagePart(response),
|
|
1979
|
+
content: convertFmapiResponseToMessagePart(response, { useRemoteToolCalling: this.config.useRemoteToolCalling ?? false }),
|
|
1914
1980
|
finishReason,
|
|
1915
1981
|
usage: {
|
|
1916
|
-
inputTokens:
|
|
1917
|
-
|
|
1918
|
-
|
|
1982
|
+
inputTokens: {
|
|
1983
|
+
total: response.usage?.prompt_tokens ?? 0,
|
|
1984
|
+
noCache: 0,
|
|
1985
|
+
cacheRead: 0,
|
|
1986
|
+
cacheWrite: 0
|
|
1987
|
+
},
|
|
1988
|
+
outputTokens: {
|
|
1989
|
+
total: response.usage?.completion_tokens ?? 0,
|
|
1990
|
+
text: 0,
|
|
1991
|
+
reasoning: 0
|
|
1992
|
+
}
|
|
1919
1993
|
},
|
|
1920
1994
|
warnings
|
|
1921
1995
|
};
|
|
1922
1996
|
}
|
|
1923
1997
|
async doStream(options) {
|
|
1924
|
-
const { warnings
|
|
1998
|
+
const { warnings, ...networkArgs } = await this.getArgs({
|
|
1925
1999
|
config: this.config,
|
|
1926
2000
|
options,
|
|
1927
2001
|
stream: true,
|
|
@@ -1937,15 +2011,27 @@ var DatabricksFmapiLanguageModel = class {
|
|
|
1937
2011
|
successfulResponseHandler: createEventSourceResponseHandler(fmapiChunkSchema),
|
|
1938
2012
|
abortSignal: options.abortSignal
|
|
1939
2013
|
});
|
|
1940
|
-
let finishReason =
|
|
2014
|
+
let finishReason = {
|
|
2015
|
+
raw: void 0,
|
|
2016
|
+
unified: "other"
|
|
2017
|
+
};
|
|
1941
2018
|
let usage = {
|
|
1942
|
-
inputTokens:
|
|
1943
|
-
|
|
1944
|
-
|
|
2019
|
+
inputTokens: {
|
|
2020
|
+
total: 0,
|
|
2021
|
+
noCache: 0,
|
|
2022
|
+
cacheRead: 0,
|
|
2023
|
+
cacheWrite: 0
|
|
2024
|
+
},
|
|
2025
|
+
outputTokens: {
|
|
2026
|
+
total: 0,
|
|
2027
|
+
text: 0,
|
|
2028
|
+
reasoning: 0
|
|
2029
|
+
}
|
|
1945
2030
|
};
|
|
1946
|
-
const toolCallIdsByIndex = new Map();
|
|
1947
|
-
const toolCallNamesById = new Map();
|
|
1948
|
-
const toolCallInputsById = new Map();
|
|
2031
|
+
const toolCallIdsByIndex = /* @__PURE__ */ new Map();
|
|
2032
|
+
const toolCallNamesById = /* @__PURE__ */ new Map();
|
|
2033
|
+
const toolCallInputsById = /* @__PURE__ */ new Map();
|
|
2034
|
+
const useRemoteToolCalling = this.config.useRemoteToolCalling ?? false;
|
|
1949
2035
|
return {
|
|
1950
2036
|
stream: response.pipeThrough(new TransformStream({
|
|
1951
2037
|
start(controller) {
|
|
@@ -1960,7 +2046,10 @@ var DatabricksFmapiLanguageModel = class {
|
|
|
1960
2046
|
rawValue: chunk.rawValue
|
|
1961
2047
|
});
|
|
1962
2048
|
if (!chunk.success) {
|
|
1963
|
-
finishReason =
|
|
2049
|
+
finishReason = {
|
|
2050
|
+
raw: void 0,
|
|
2051
|
+
unified: "error"
|
|
2052
|
+
};
|
|
1964
2053
|
controller.enqueue({
|
|
1965
2054
|
type: "error",
|
|
1966
2055
|
error: chunk.error
|
|
@@ -1970,9 +2059,17 @@ var DatabricksFmapiLanguageModel = class {
|
|
|
1970
2059
|
const choice = chunk.value.choices[0];
|
|
1971
2060
|
finishReason = mapFmapiFinishReason(choice?.finish_reason);
|
|
1972
2061
|
if (chunk.value.usage) usage = {
|
|
1973
|
-
inputTokens:
|
|
1974
|
-
|
|
1975
|
-
|
|
2062
|
+
inputTokens: {
|
|
2063
|
+
total: chunk.value.usage.prompt_tokens ?? 0,
|
|
2064
|
+
noCache: 0,
|
|
2065
|
+
cacheRead: 0,
|
|
2066
|
+
cacheWrite: 0
|
|
2067
|
+
},
|
|
2068
|
+
outputTokens: {
|
|
2069
|
+
total: chunk.value.usage.completion_tokens ?? 0,
|
|
2070
|
+
text: 0,
|
|
2071
|
+
reasoning: 0
|
|
2072
|
+
}
|
|
1976
2073
|
};
|
|
1977
2074
|
const parts = convertFmapiChunkToMessagePart(chunk.value, toolCallIdsByIndex);
|
|
1978
2075
|
for (const part of parts) {
|
|
@@ -1997,9 +2094,12 @@ var DatabricksFmapiLanguageModel = class {
|
|
|
1997
2094
|
controller.enqueue({
|
|
1998
2095
|
type: "tool-call",
|
|
1999
2096
|
toolCallId,
|
|
2000
|
-
toolName
|
|
2097
|
+
toolName,
|
|
2001
2098
|
input: inputText,
|
|
2002
|
-
|
|
2099
|
+
...useRemoteToolCalling && {
|
|
2100
|
+
dynamic: true,
|
|
2101
|
+
providerExecuted: true
|
|
2102
|
+
}
|
|
2003
2103
|
});
|
|
2004
2104
|
}
|
|
2005
2105
|
}
|
|
@@ -2039,7 +2139,7 @@ var DatabricksFmapiLanguageModel = class {
|
|
|
2039
2139
|
* Convert AI SDK tool to OpenAI format
|
|
2040
2140
|
*/
|
|
2041
2141
|
function convertToolToOpenAIFormat(tool) {
|
|
2042
|
-
if (tool.type === "provider
|
|
2142
|
+
if (tool.type === "provider") return;
|
|
2043
2143
|
return {
|
|
2044
2144
|
type: "function",
|
|
2045
2145
|
function: {
|
|
@@ -2084,13 +2184,15 @@ const createDatabricksProvider = (settings) => {
|
|
|
2084
2184
|
url: formatUrl,
|
|
2085
2185
|
headers: getHeaders,
|
|
2086
2186
|
fetch,
|
|
2087
|
-
provider
|
|
2187
|
+
provider,
|
|
2188
|
+
useRemoteToolCalling: settings.useRemoteToolCalling
|
|
2088
2189
|
});
|
|
2089
2190
|
const createFmapi = (modelId) => new DatabricksFmapiLanguageModel(modelId, {
|
|
2090
2191
|
url: formatUrl,
|
|
2091
2192
|
headers: getHeaders,
|
|
2092
2193
|
fetch,
|
|
2093
|
-
provider
|
|
2194
|
+
provider,
|
|
2195
|
+
useRemoteToolCalling: settings.useRemoteToolCalling
|
|
2094
2196
|
});
|
|
2095
2197
|
const notImplemented = (name) => {
|
|
2096
2198
|
return () => {
|
|
@@ -2098,15 +2200,17 @@ const createDatabricksProvider = (settings) => {
|
|
|
2098
2200
|
};
|
|
2099
2201
|
};
|
|
2100
2202
|
return {
|
|
2203
|
+
specificationVersion: "v3",
|
|
2101
2204
|
responses: createResponsesAgent,
|
|
2102
2205
|
chatCompletions: createFmapi,
|
|
2103
2206
|
chatAgent: createChatAgent,
|
|
2104
2207
|
imageModel: notImplemented("ImageModel"),
|
|
2105
2208
|
textEmbeddingModel: notImplemented("TextEmbeddingModel"),
|
|
2209
|
+
embeddingModel: notImplemented("EmbeddingModel"),
|
|
2106
2210
|
languageModel: notImplemented("LanguageModel")
|
|
2107
2211
|
};
|
|
2108
2212
|
};
|
|
2109
2213
|
|
|
2110
2214
|
//#endregion
|
|
2111
|
-
export {
|
|
2112
|
-
//# sourceMappingURL=index.
|
|
2215
|
+
export { MCP_APPROVAL_REQUEST_TYPE, MCP_APPROVAL_RESPONSE_TYPE, MCP_APPROVAL_STATUS_KEY, createApprovalStatusOutput, createDatabricksProvider, extractApprovalStatus, extractApprovalStatusFromToolResult, extractDatabricksMetadata, getMcpApprovalState, isApprovalStatusOutput, isMcpApprovalRequest, isMcpApprovalResponse };
|
|
2216
|
+
//# sourceMappingURL=index.mjs.map
|