@databricks/ai-sdk-provider 0.2.3 → 0.4.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/dist/index.cjs CHANGED
@@ -1,31 +1,7 @@
1
- "use strict";
2
- //#region rolldown:runtime
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
23
-
24
- //#endregion
25
- const __ai_sdk_provider_utils = __toESM(require("@ai-sdk/provider-utils"));
26
- const zod_v4 = __toESM(require("zod/v4"));
27
- const node_crypto = __toESM(require("node:crypto"));
28
- const __ai_sdk_provider = __toESM(require("@ai-sdk/provider"));
1
+ let _ai_sdk_provider_utils = require("@ai-sdk/provider-utils");
2
+ let zod_v4 = require("zod/v4");
3
+ let node_crypto = require("node:crypto");
4
+ let _ai_sdk_provider = require("@ai-sdk/provider");
29
5
 
30
6
  //#region src/chat-agent-language-model/chat-agent-schema.ts
31
7
  const chatAgentToolCallSchema = zod_v4.z.object({
@@ -70,26 +46,6 @@ const chatAgentResponseSchema = zod_v4.z.object({
70
46
  messages: zod_v4.z.array(chatAgentMessageSchema)
71
47
  });
72
48
 
73
- //#endregion
74
- //#region src/tools.ts
75
- const DATABRICKS_TOOL_CALL_ID = "databricks-tool-call";
76
- /**
77
- * The AI-SDK requires that tools used by the model are defined ahead of time.
78
- *
79
- * Since tool calls can be orchestrated by Databricks' agents we don't know the name, input, or output schemas
80
- * of the tools until the model is called.
81
- *
82
- * In the DatabricksProvider we transform all tool calls to fit this definition, and keep the
83
- * original name as part of the metadata. This allows us to parse any tool orchestrated by Databricks' agents,
84
- * 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.
85
- */
86
- const DATABRICKS_TOOL_DEFINITION = {
87
- name: DATABRICKS_TOOL_CALL_ID,
88
- description: "Databricks tool call",
89
- inputSchema: zod_v4.z.any(),
90
- outputSchema: zod_v4.z.any()
91
- };
92
-
93
49
  //#endregion
94
50
  //#region src/chat-agent-language-model/chat-agent-convert-to-message-parts.ts
95
51
  const convertChatAgentChunkToMessagePart = (chunk) => {
@@ -105,14 +61,16 @@ const convertChatAgentChunkToMessagePart = (chunk) => {
105
61
  type: "tool-call",
106
62
  toolCallId: toolCall.id,
107
63
  input: toolCall.function.arguments,
108
- toolName: toolCall.function.name
64
+ toolName: toolCall.function.name,
65
+ dynamic: true,
66
+ providerExecuted: true
109
67
  });
110
68
  });
111
69
  } else if (chunk.delta.role === "tool") parts.push({
112
70
  type: "tool-result",
113
71
  toolCallId: chunk.delta.tool_call_id,
114
72
  result: chunk.delta.content,
115
- toolName: DATABRICKS_TOOL_CALL_ID
73
+ toolName: chunk.delta.name ?? "unknown"
116
74
  });
117
75
  return parts;
118
76
  };
@@ -127,20 +85,22 @@ const convertChatAgentResponseToMessagePart = (response) => {
127
85
  type: "tool-call",
128
86
  toolCallId: part.id,
129
87
  input: part.function.arguments,
130
- toolName: part.function.name
88
+ toolName: part.function.name,
89
+ dynamic: true,
90
+ providerExecuted: true
131
91
  });
132
92
  } else if (message.role === "tool") parts.push({
133
93
  type: "tool-result",
134
94
  toolCallId: message.tool_call_id,
135
95
  result: message.content,
136
- toolName: DATABRICKS_TOOL_CALL_ID
96
+ toolName: message.name ?? "unknown"
137
97
  });
138
98
  return parts;
139
99
  };
140
100
 
141
101
  //#endregion
142
102
  //#region src/chat-agent-language-model/chat-agent-convert-to-input.ts
143
- const convertLanguageModelV2PromptToChatAgentResponse = (prompt) => {
103
+ const convertLanguageModelV3PromptToChatAgentResponse = (prompt) => {
144
104
  const messages = [];
145
105
  let messageIndex = 0;
146
106
  for (const msg of prompt) switch (msg.role) {
@@ -167,10 +127,9 @@ const convertLanguageModelV2PromptToChatAgentResponse = (prompt) => {
167
127
  return messages;
168
128
  };
169
129
  const convertUserMessage$1 = (msg, messageIndex) => {
170
- const text = (msg.content ?? []).filter((part) => part.type === "text").map((part) => part.text).join("\n");
171
130
  return {
172
131
  role: "user",
173
- content: text,
132
+ content: (msg.content ?? []).filter((part) => part.type === "text").map((part) => part.text).join("\n"),
174
133
  id: `user-${messageIndex}`
175
134
  };
176
135
  };
@@ -243,10 +202,7 @@ const convertToolResultOutput = (output) => {
243
202
  function composeDatabricksStreamPartTransformers(...transformers) {
244
203
  return (initialParts, last = null) => {
245
204
  let currentParts = initialParts;
246
- for (const fn of transformers) {
247
- const result = fn(currentParts, last);
248
- currentParts = result.out;
249
- }
205
+ for (const fn of transformers) currentParts = fn(currentParts, last).out;
250
206
  return { out: currentParts };
251
207
  };
252
208
  }
@@ -263,8 +219,7 @@ const applyDeltaBoundaryTransform = (parts, last) => {
263
219
  const incomingDeltaType = maybeGetDeltaType(incoming);
264
220
  const incomingId = getPartId$1(incoming);
265
221
  const lastId = getPartId$1(last);
266
- const incomingMatchesLast = Boolean(isDeltaPart(last) && isDeltaPart(incoming)) && Boolean(lastDeltaType && incomingDeltaType) && Boolean(lastDeltaType === incomingDeltaType) && Boolean(incomingId && lastId && incomingId === lastId);
267
- if (incomingMatchesLast) {
222
+ if (Boolean(isDeltaPart(last) && isDeltaPart(incoming)) && Boolean(lastDeltaType && incomingDeltaType) && Boolean(lastDeltaType === incomingDeltaType) && Boolean(incomingId && lastId && incomingId === lastId)) {
268
223
  out.push(incoming);
269
224
  continue;
270
225
  }
@@ -280,7 +235,6 @@ const applyDeltaBoundaryTransform = (parts, last) => {
280
235
  continue;
281
236
  }
282
237
  out.push(incoming);
283
- continue;
284
238
  }
285
239
  return { out };
286
240
  };
@@ -299,7 +253,6 @@ const getDeltaType = (part) => {
299
253
  const isDeltaPart = (part) => part?.type === "text-delta" || part?.type === "reasoning-delta";
300
254
  const getPartId$1 = (part) => {
301
255
  if (part && "id" in part) return part.id;
302
- return void 0;
303
256
  };
304
257
 
305
258
  //#endregion
@@ -312,7 +265,7 @@ const getPartId$1 = (part) => {
312
265
  */
313
266
  const getDatabricksLanguageModelTransformStream = () => {
314
267
  let lastChunk = null;
315
- const deltaEndByTypeAndId = new Set();
268
+ const deltaEndByTypeAndId = /* @__PURE__ */ new Set();
316
269
  const transformerStreamParts = composeDatabricksStreamPartTransformers(applyDeltaBoundaryTransform);
317
270
  return new TransformStream({
318
271
  transform(chunk, controller) {
@@ -354,14 +307,13 @@ const getDeltaGroup = (type) => {
354
307
  };
355
308
  const getPartId = (part) => {
356
309
  if ("id" in part) return part.id;
357
- return void 0;
358
310
  };
359
311
  const makeEndKey = (id, group) => id && group ? `${group}:${id}` : null;
360
312
 
361
313
  //#endregion
362
314
  //#region src/chat-agent-language-model/chat-agent-language-model.ts
363
315
  var DatabricksChatAgentLanguageModel = class {
364
- specificationVersion = "v2";
316
+ specificationVersion = "v3";
365
317
  modelId;
366
318
  config;
367
319
  constructor(modelId, config) {
@@ -373,16 +325,15 @@ var DatabricksChatAgentLanguageModel = class {
373
325
  }
374
326
  supportedUrls = {};
375
327
  async doGenerate(options) {
376
- const networkArgs = this.getArgs({
377
- config: this.config,
378
- options,
379
- stream: false,
380
- modelId: this.modelId
381
- });
382
- const { value: response } = await (0, __ai_sdk_provider_utils.postJsonToApi)({
383
- ...networkArgs,
384
- successfulResponseHandler: (0, __ai_sdk_provider_utils.createJsonResponseHandler)(chatAgentResponseSchema),
385
- failedResponseHandler: (0, __ai_sdk_provider_utils.createJsonErrorResponseHandler)({
328
+ const { value: response } = await (0, _ai_sdk_provider_utils.postJsonToApi)({
329
+ ...this.getArgs({
330
+ config: this.config,
331
+ options,
332
+ stream: false,
333
+ modelId: this.modelId
334
+ }),
335
+ successfulResponseHandler: (0, _ai_sdk_provider_utils.createJsonResponseHandler)(chatAgentResponseSchema),
336
+ failedResponseHandler: (0, _ai_sdk_provider_utils.createJsonErrorResponseHandler)({
386
337
  errorSchema: zod_v4.z.any(),
387
338
  errorToMessage: (error) => JSON.stringify(error),
388
339
  isRetryable: () => false
@@ -390,11 +341,22 @@ var DatabricksChatAgentLanguageModel = class {
390
341
  });
391
342
  return {
392
343
  content: convertChatAgentResponseToMessagePart(response),
393
- finishReason: "stop",
344
+ finishReason: {
345
+ raw: void 0,
346
+ unified: "stop"
347
+ },
394
348
  usage: {
395
- inputTokens: 0,
396
- outputTokens: 0,
397
- totalTokens: 0
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
+ }
398
360
  },
399
361
  warnings: []
400
362
  };
@@ -406,16 +368,19 @@ var DatabricksChatAgentLanguageModel = class {
406
368
  stream: true,
407
369
  modelId: this.modelId
408
370
  });
409
- const { responseHeaders, value: response } = await (0, __ai_sdk_provider_utils.postJsonToApi)({
371
+ const { responseHeaders, value: response } = await (0, _ai_sdk_provider_utils.postJsonToApi)({
410
372
  ...networkArgs,
411
- failedResponseHandler: (0, __ai_sdk_provider_utils.createJsonErrorResponseHandler)({
373
+ failedResponseHandler: (0, _ai_sdk_provider_utils.createJsonErrorResponseHandler)({
412
374
  errorSchema: zod_v4.z.any(),
413
375
  errorToMessage: (error) => JSON.stringify(error),
414
376
  isRetryable: () => false
415
377
  }),
416
- successfulResponseHandler: (0, __ai_sdk_provider_utils.createEventSourceResponseHandler)(chatAgentChunkSchema)
378
+ successfulResponseHandler: (0, _ai_sdk_provider_utils.createEventSourceResponseHandler)(chatAgentChunkSchema)
417
379
  });
418
- let finishReason = "unknown";
380
+ let finishReason = {
381
+ raw: void 0,
382
+ unified: "other"
383
+ };
419
384
  return {
420
385
  stream: response.pipeThrough(new TransformStream({
421
386
  start(controller) {
@@ -430,7 +395,10 @@ var DatabricksChatAgentLanguageModel = class {
430
395
  rawValue: chunk.rawValue
431
396
  });
432
397
  if (!chunk.success) {
433
- finishReason = "error";
398
+ finishReason = {
399
+ raw: void 0,
400
+ unified: "error"
401
+ };
434
402
  controller.enqueue({
435
403
  type: "error",
436
404
  error: chunk.error
@@ -445,9 +413,17 @@ var DatabricksChatAgentLanguageModel = class {
445
413
  type: "finish",
446
414
  finishReason,
447
415
  usage: {
448
- inputTokens: 0,
449
- outputTokens: 0,
450
- totalTokens: 0
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
+ }
451
427
  }
452
428
  });
453
429
  }
@@ -461,10 +437,10 @@ var DatabricksChatAgentLanguageModel = class {
461
437
  body: {
462
438
  model: modelId,
463
439
  stream,
464
- messages: convertLanguageModelV2PromptToChatAgentResponse(options.prompt)
440
+ messages: convertLanguageModelV3PromptToChatAgentResponse(options.prompt)
465
441
  },
466
442
  url: config.url({ path: "/completions" }),
467
- headers: (0, __ai_sdk_provider_utils.combineHeaders)(config.headers(), options.headers),
443
+ headers: (0, _ai_sdk_provider_utils.combineHeaders)(config.headers(), options.headers),
468
444
  fetch: config.fetch,
469
445
  abortSignal: options.abortSignal
470
446
  };
@@ -639,125 +615,9 @@ const responsesAgentChunkSchema = zod_v4.z.union([
639
615
  */
640
616
  const looseResponseAgentChunkSchema = zod_v4.z.union([responsesAgentChunkSchema, zod_v4.z.object({ type: zod_v4.z.string() }).loose()]);
641
617
 
642
- //#endregion
643
- //#region src/mcp.ts
644
- /**
645
- * MCP Approval Utility Functions
646
- *
647
- * Shared utilities for handling MCP (Model Context Protocol) approval requests
648
- * and responses across client and server code.
649
- */
650
- /** Key used in tool output to indicate approval status */
651
- const MCP_APPROVAL_STATUS_KEY = "__approvalStatus__";
652
- /** Type string for MCP approval requests in provider metadata */
653
- const MCP_APPROVAL_REQUEST_TYPE = "mcp_approval_request";
654
- /** Type string for MCP approval responses in provider metadata */
655
- const MCP_APPROVAL_RESPONSE_TYPE = "mcp_approval_response";
656
- /**
657
- * Check if output contains an approval status marker.
658
- *
659
- * @example
660
- * if (isApprovalStatusOutput(output)) {
661
- * console.log(output.__approvalStatus__); // TypeScript knows this is boolean
662
- * }
663
- */
664
- function isApprovalStatusOutput(output) {
665
- return typeof output === "object" && output !== null && MCP_APPROVAL_STATUS_KEY in output && typeof output[MCP_APPROVAL_STATUS_KEY] === "boolean";
666
- }
667
- /**
668
- * Check if provider metadata indicates an MCP approval request.
669
- *
670
- * @example
671
- * const metadata = extractDatabricksMetadata(part);
672
- * if (isMcpApprovalRequest(metadata)) {
673
- * // Handle MCP approval request
674
- * }
675
- */
676
- function isMcpApprovalRequest(metadata) {
677
- return metadata?.type?.toString() === MCP_APPROVAL_REQUEST_TYPE;
678
- }
679
- /**
680
- * Check if provider metadata indicates an MCP approval response.
681
- */
682
- function isMcpApprovalResponse(metadata) {
683
- return metadata?.type?.toString() === MCP_APPROVAL_RESPONSE_TYPE;
684
- }
685
- /**
686
- * Extract Databricks metadata from a tool call part's callProviderMetadata.
687
- *
688
- * @example
689
- * const metadata = extractDatabricksMetadata(part);
690
- * const toolName = metadata?.toolName;
691
- * const isMcp = isMcpApprovalRequest(metadata);
692
- */
693
- function extractDatabricksMetadata(part) {
694
- if ("callProviderMetadata" in part && part.callProviderMetadata?.databricks) return part.callProviderMetadata.databricks;
695
- return void 0;
696
- }
697
- /**
698
- * Extract the approval status boolean from an output object.
699
- *
700
- * @returns `true` if approved, `false` if denied, `undefined` if not an approval output
701
- *
702
- * @example
703
- * const status = extractApprovalStatus(output);
704
- * if (status !== undefined) {
705
- * console.log(status ? 'Approved' : 'Denied');
706
- * }
707
- */
708
- function extractApprovalStatus(output) {
709
- if (isApprovalStatusOutput(output)) return output[MCP_APPROVAL_STATUS_KEY];
710
- return void 0;
711
- }
712
- /**
713
- * Extract approval status from a tool result's output value.
714
- * Handles the nested structure where output.type === 'json' and value contains the status.
715
- *
716
- * @example
717
- * const status = extractApprovalStatusFromToolResult(toolResult.output);
718
- */
719
- function extractApprovalStatusFromToolResult(output) {
720
- if (output.type === "json" && output.value && typeof output.value === "object" && MCP_APPROVAL_STATUS_KEY in output.value) {
721
- const value = output.value[MCP_APPROVAL_STATUS_KEY];
722
- if (typeof value === "boolean") return value;
723
- }
724
- return void 0;
725
- }
726
- /**
727
- * Create an approval status output object.
728
- *
729
- * @example
730
- * await addToolResult({
731
- * toolCallId,
732
- * output: createApprovalStatusOutput(true), // Approve
733
- * });
734
- */
735
- function createApprovalStatusOutput(approve) {
736
- return { [MCP_APPROVAL_STATUS_KEY]: approve };
737
- }
738
- /**
739
- * Determine the MCP approval state from a tool output.
740
- *
741
- * Logic:
742
- * - No output → 'awaiting-approval' (user hasn't responded yet)
743
- * - Output with __approvalStatus__: true → 'approved'
744
- * - Output with __approvalStatus__: false → 'denied'
745
- * - Output without __approvalStatus__ → 'approved' (tool executed, so it was approved)
746
- *
747
- * @example
748
- * const approvalState = getMcpApprovalState(part.output);
749
- * // 'awaiting-approval' | 'approved' | 'denied'
750
- */
751
- function getMcpApprovalState(output) {
752
- if (!output) return "awaiting-approval";
753
- const status = extractApprovalStatus(output);
754
- if (status === void 0) return "approved";
755
- return status ? "approved" : "denied";
756
- }
757
-
758
618
  //#endregion
759
619
  //#region src/responses-agent-language-model/responses-convert-to-message-parts.ts
760
- const convertResponsesAgentChunkToMessagePart = (chunk) => {
620
+ const convertResponsesAgentChunkToMessagePart = (chunk, options = { useRemoteToolCalling: false }) => {
761
621
  const parts = [];
762
622
  if ("error" in chunk) {
763
623
  parts.push({
@@ -787,12 +647,12 @@ const convertResponsesAgentChunkToMessagePart = (chunk) => {
787
647
  parts.push({
788
648
  type: "tool-result",
789
649
  toolCallId: chunk.call_id,
790
- result: chunk.output,
791
- toolName: DATABRICKS_TOOL_CALL_ID
650
+ result: chunk.output != null ? chunk.output : {},
651
+ toolName: options.toolNamesByCallId?.get(chunk.call_id) ?? "unknown"
792
652
  });
793
653
  break;
794
654
  case "response.output_item.done":
795
- parts.push(...convertOutputItemDone(chunk.item));
655
+ parts.push(...convertOutputItemDone(chunk.item, options));
796
656
  break;
797
657
  case "response.output_text.annotation.added":
798
658
  parts.push({
@@ -813,7 +673,7 @@ const convertResponsesAgentChunkToMessagePart = (chunk) => {
813
673
  }
814
674
  return parts;
815
675
  };
816
- const convertOutputItemDone = (item) => {
676
+ const convertOutputItemDone = (item, options) => {
817
677
  switch (item.type) {
818
678
  case "message": {
819
679
  const firstContent = item.content[0];
@@ -831,18 +691,19 @@ const convertOutputItemDone = (item) => {
831
691
  case "function_call": return [{
832
692
  type: "tool-call",
833
693
  toolCallId: item.call_id,
834
- toolName: DATABRICKS_TOOL_CALL_ID,
694
+ toolName: item.name,
835
695
  input: item.arguments,
836
- providerMetadata: { databricks: {
837
- toolName: item.name,
838
- itemId: item.id
839
- } }
696
+ ...options.useRemoteToolCalling && {
697
+ dynamic: true,
698
+ providerExecuted: true
699
+ },
700
+ providerMetadata: { databricks: { itemId: item.id } }
840
701
  }];
841
702
  case "function_call_output": return [{
842
703
  type: "tool-result",
843
704
  toolCallId: item.call_id,
844
- result: item.output,
845
- toolName: DATABRICKS_TOOL_CALL_ID
705
+ result: item.output != null ? item.output : {},
706
+ toolName: options.toolNamesByCallId?.get(item.call_id) ?? "unknown"
846
707
  }];
847
708
  case "reasoning": {
848
709
  const firstSummary = item.summary[0];
@@ -867,49 +728,54 @@ const convertOutputItemDone = (item) => {
867
728
  case "mcp_approval_request": return [{
868
729
  type: "tool-call",
869
730
  toolCallId: item.id,
870
- toolName: DATABRICKS_TOOL_CALL_ID,
731
+ toolName: item.name,
871
732
  input: item.arguments,
733
+ providerExecuted: true,
734
+ dynamic: true,
872
735
  providerMetadata: { databricks: {
873
- type: MCP_APPROVAL_REQUEST_TYPE,
874
- toolName: item.name,
875
736
  itemId: item.id,
876
- serverLabel: item.server_label
737
+ serverLabel: item.server_label,
738
+ approvalRequestId: item.id
877
739
  } }
740
+ }, {
741
+ type: "tool-approval-request",
742
+ approvalId: item.id,
743
+ toolCallId: item.id
878
744
  }];
879
745
  case "mcp_approval_response": return [{
880
746
  type: "tool-result",
881
747
  toolCallId: item.approval_request_id,
882
- toolName: DATABRICKS_TOOL_CALL_ID,
883
- result: createApprovalStatusOutput(item.approve),
884
- providerMetadata: { databricks: {
885
- type: MCP_APPROVAL_RESPONSE_TYPE,
886
- ...item.id != null && { itemId: item.id }
887
- } }
748
+ toolName: options.toolNamesByCallId?.get(item.approval_request_id) ?? "mcp_approval",
749
+ result: { approved: item.approve },
750
+ providerMetadata: { databricks: { itemId: item.id ?? item.approval_request_id } }
888
751
  }];
889
752
  default: return [];
890
753
  }
891
754
  };
892
- const convertResponsesAgentResponseToMessagePart = (response) => {
755
+ const convertResponsesAgentResponseToMessagePart = (response, options = { useRemoteToolCalling: false }) => {
893
756
  const parts = [];
757
+ const toolNamesByCallId = /* @__PURE__ */ new Map();
758
+ for (const output of response.output) if (output.type === "function_call") toolNamesByCallId.set(output.call_id, output.name);
759
+ else if (output.type === "mcp_approval_request") toolNamesByCallId.set(output.id, output.name);
894
760
  for (const output of response.output) switch (output.type) {
895
- case "message": {
761
+ case "message":
896
762
  for (const content of output.content) if (content.type === "output_text") parts.push({
897
763
  type: "text",
898
764
  text: content.text,
899
765
  providerMetadata: { databricks: { itemId: output.id } }
900
766
  });
901
767
  break;
902
- }
903
768
  case "function_call":
904
769
  parts.push({
905
770
  type: "tool-call",
906
771
  toolCallId: output.call_id,
907
- toolName: DATABRICKS_TOOL_CALL_ID,
772
+ toolName: output.name,
908
773
  input: output.arguments,
909
- providerMetadata: { databricks: {
910
- toolName: output.name,
911
- itemId: output.id
912
- } }
774
+ ...options.useRemoteToolCalling && {
775
+ dynamic: true,
776
+ providerExecuted: true
777
+ },
778
+ providerMetadata: { databricks: { itemId: output.id } }
913
779
  });
914
780
  break;
915
781
  case "reasoning":
@@ -924,33 +790,36 @@ const convertResponsesAgentResponseToMessagePart = (response) => {
924
790
  type: "tool-result",
925
791
  result: output.output,
926
792
  toolCallId: output.call_id,
927
- toolName: DATABRICKS_TOOL_CALL_ID
793
+ toolName: toolNamesByCallId.get(output.call_id) ?? "unknown"
928
794
  });
929
795
  break;
930
796
  case "mcp_approval_request":
931
797
  parts.push({
932
798
  type: "tool-call",
933
799
  toolCallId: output.id,
934
- toolName: DATABRICKS_TOOL_CALL_ID,
800
+ toolName: output.name,
935
801
  input: output.arguments,
802
+ providerExecuted: true,
803
+ dynamic: true,
936
804
  providerMetadata: { databricks: {
937
- type: MCP_APPROVAL_REQUEST_TYPE,
938
- toolName: output.name,
939
805
  itemId: output.id,
940
- serverLabel: output.server_label
806
+ serverLabel: output.server_label,
807
+ approvalRequestId: output.id
941
808
  } }
942
809
  });
810
+ parts.push({
811
+ type: "tool-approval-request",
812
+ approvalId: output.id,
813
+ toolCallId: output.id
814
+ });
943
815
  break;
944
816
  case "mcp_approval_response":
945
817
  parts.push({
946
818
  type: "tool-result",
947
819
  toolCallId: output.approval_request_id,
948
- toolName: DATABRICKS_TOOL_CALL_ID,
949
- result: createApprovalStatusOutput(output.approve),
950
- providerMetadata: { databricks: {
951
- type: MCP_APPROVAL_RESPONSE_TYPE,
952
- ...output.id != null && { itemId: output.id }
953
- } }
820
+ toolName: toolNamesByCallId.get(output.approval_request_id) ?? "mcp_approval",
821
+ result: { approved: output.approve },
822
+ providerMetadata: { databricks: { itemId: output.id ?? output.approval_request_id } }
954
823
  });
955
824
  break;
956
825
  default: break;
@@ -963,12 +832,14 @@ const convertResponsesAgentResponseToMessagePart = (response) => {
963
832
  async function convertToResponsesInput({ prompt, systemMessageMode }) {
964
833
  const input = [];
965
834
  const warnings = [];
835
+ const processedApprovalIds = /* @__PURE__ */ new Set();
836
+ const approvalIdsWithToolResult = /* @__PURE__ */ new Set();
966
837
  const toolCallResultsByToolCallId = prompt.filter((p) => p.role === "tool").flatMap((p) => p.content).reduce((reduction, toolCallResult) => {
967
838
  if (toolCallResult.type === "tool-result") reduction[toolCallResult.toolCallId] = toolCallResult;
968
839
  return reduction;
969
840
  }, {});
970
841
  for (const { role, content } of prompt) switch (role) {
971
- case "system": {
842
+ case "system":
972
843
  switch (systemMessageMode) {
973
844
  case "system":
974
845
  input.push({
@@ -994,7 +865,6 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
994
865
  }
995
866
  }
996
867
  break;
997
- }
998
868
  case "user":
999
869
  input.push({
1000
870
  role: "user",
@@ -1004,21 +874,21 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
1004
874
  type: "input_text",
1005
875
  text: part.text
1006
876
  };
1007
- default: throw new __ai_sdk_provider.UnsupportedFunctionalityError({ functionality: `part ${JSON.stringify(part)}` });
877
+ default: throw new _ai_sdk_provider.UnsupportedFunctionalityError({ functionality: `part ${JSON.stringify(part)}` });
1008
878
  }
1009
879
  })
1010
880
  });
1011
881
  break;
1012
882
  case "assistant":
1013
883
  for (const part of content) {
1014
- const providerOptions = await (0, __ai_sdk_provider_utils.parseProviderOptions)({
884
+ const providerOptions = await (0, _ai_sdk_provider_utils.parseProviderOptions)({
1015
885
  provider: "databricks",
1016
886
  providerOptions: part.providerOptions,
1017
887
  schema: ProviderOptionsSchema$1
1018
888
  });
1019
889
  const itemId = providerOptions?.itemId ?? void 0;
1020
890
  switch (part.type) {
1021
- case "text": {
891
+ case "text":
1022
892
  input.push({
1023
893
  role: "assistant",
1024
894
  content: [{
@@ -1028,40 +898,18 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
1028
898
  id: itemId
1029
899
  });
1030
900
  break;
1031
- }
1032
901
  case "tool-call": {
1033
902
  const toolName = providerOptions?.toolName ?? part.toolName;
1034
- if (providerOptions?.type === MCP_APPROVAL_REQUEST_TYPE) {
903
+ const approvalRequestId = providerOptions?.approvalRequestId;
904
+ if (approvalRequestId) {
1035
905
  const serverLabel = providerOptions?.serverLabel ?? "";
1036
- const argumentsString = JSON.stringify(part.input);
1037
- const id = part.toolCallId;
1038
906
  input.push({
1039
- type: MCP_APPROVAL_REQUEST_TYPE,
1040
- id,
907
+ type: "mcp_approval_request",
908
+ id: approvalRequestId,
1041
909
  name: toolName,
1042
- arguments: argumentsString,
910
+ arguments: JSON.stringify(part.input),
1043
911
  server_label: serverLabel
1044
912
  });
1045
- const toolResult = toolCallResultsByToolCallId[part.toolCallId];
1046
- if (toolResult) {
1047
- /**
1048
- * The tool call result is either the approval status or the actual output from the tool call.
1049
- * If it's the approval status, we need to add an approval response part.
1050
- * If it's the tool call output, we don't include the approval response part but we do include the tool call output part.
1051
- */
1052
- const approvalStatus = extractApprovalStatusFromToolResult(toolResult.output);
1053
- if (approvalStatus !== void 0) input.push({
1054
- type: MCP_APPROVAL_RESPONSE_TYPE,
1055
- id: toolResult.toolCallId,
1056
- approval_request_id: toolResult.toolCallId,
1057
- approve: approvalStatus
1058
- });
1059
- else input.push({
1060
- type: "function_call_output",
1061
- call_id: toolResult.toolCallId,
1062
- output: convertToolResultOutputToString(toolResult.output)
1063
- });
1064
- }
1065
913
  break;
1066
914
  }
1067
915
  input.push({
@@ -1079,28 +927,15 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
1079
927
  });
1080
928
  break;
1081
929
  }
1082
- case "tool-result": {
1083
- if (providerOptions?.type === MCP_APPROVAL_RESPONSE_TYPE) {
1084
- const approvalRequestId = providerOptions?.approvalRequestId ?? part.toolCallId;
1085
- const approve = providerOptions?.approve ?? false;
1086
- const reason = providerOptions?.reason ?? "";
1087
- input.push({
1088
- type: MCP_APPROVAL_RESPONSE_TYPE,
1089
- id: approvalRequestId,
1090
- approval_request_id: approvalRequestId,
1091
- approve,
1092
- reason
1093
- });
1094
- break;
1095
- }
930
+ case "tool-result":
1096
931
  input.push({
1097
932
  type: "function_call_output",
1098
933
  call_id: part.toolCallId,
1099
934
  output: convertToolResultOutputToString(part.output)
1100
935
  });
936
+ approvalIdsWithToolResult.add(part.toolCallId);
1101
937
  break;
1102
- }
1103
- case "reasoning": {
938
+ case "reasoning":
1104
939
  if (!itemId) break;
1105
940
  input.push({
1106
941
  type: "reasoning",
@@ -1111,11 +946,22 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
1111
946
  id: itemId
1112
947
  });
1113
948
  break;
1114
- }
1115
949
  }
1116
950
  }
1117
951
  break;
1118
- case "tool": break;
952
+ case "tool":
953
+ for (const part of content) if (part.type === "tool-approval-response") {
954
+ if (processedApprovalIds.has(part.approvalId)) continue;
955
+ processedApprovalIds.add(part.approvalId);
956
+ if (approvalIdsWithToolResult.has(part.approvalId)) continue;
957
+ input.push({
958
+ type: "mcp_approval_response",
959
+ approval_request_id: part.approvalId,
960
+ approve: part.approved,
961
+ ...part.reason && { reason: part.reason }
962
+ });
963
+ }
964
+ break;
1119
965
  default: {
1120
966
  const _exhaustiveCheck = role;
1121
967
  throw new Error(`Unsupported role: ${String(_exhaustiveCheck)}`);
@@ -1129,17 +975,17 @@ async function convertToResponsesInput({ prompt, systemMessageMode }) {
1129
975
  const ProviderOptionsSchema$1 = zod_v4.z.object({
1130
976
  itemId: zod_v4.z.string().nullish(),
1131
977
  toolName: zod_v4.z.string().nullish(),
1132
- type: zod_v4.z.enum(["mcp_approval_request", "mcp_approval_response"]).nullish(),
1133
978
  serverLabel: zod_v4.z.string().nullish(),
1134
- approvalRequestId: zod_v4.z.string().nullish(),
1135
- approve: zod_v4.z.boolean().nullish(),
1136
- reason: zod_v4.z.string().nullish()
979
+ approvalRequestId: zod_v4.z.string().nullish()
1137
980
  });
1138
981
  const convertToolResultOutputToString = (output) => {
1139
982
  switch (output.type) {
1140
983
  case "text":
1141
984
  case "error-text": return output.value;
1142
- default: return JSON.stringify(output.value);
985
+ case "execution-denied": return output.reason ?? "Execution denied";
986
+ case "json":
987
+ case "error-json":
988
+ case "content": return JSON.stringify(output.value);
1143
989
  }
1144
990
  };
1145
991
 
@@ -1157,7 +1003,7 @@ function prepareResponsesTools({ tools, toolChoice }) {
1157
1003
  };
1158
1004
  const responsesTools = [];
1159
1005
  for (const tool of tools) {
1160
- if (tool.type === "provider-defined" || tool.name === DATABRICKS_TOOL_CALL_ID) continue;
1006
+ if (tool.type === "provider") continue;
1161
1007
  responsesTools.push({
1162
1008
  type: "function",
1163
1009
  name: tool.name,
@@ -1169,14 +1015,13 @@ function prepareResponsesTools({ tools, toolChoice }) {
1169
1015
  tools: void 0,
1170
1016
  toolChoice: void 0
1171
1017
  };
1172
- const convertedToolChoice = convertResponsesToolChoice(toolChoice);
1173
1018
  return {
1174
1019
  tools: responsesTools,
1175
- toolChoice: convertedToolChoice
1020
+ toolChoice: convertResponsesToolChoice(toolChoice)
1176
1021
  };
1177
1022
  }
1178
1023
  function convertResponsesToolChoice(toolChoice) {
1179
- if (!toolChoice) return void 0;
1024
+ if (!toolChoice) return;
1180
1025
  switch (toolChoice.type) {
1181
1026
  case "auto": return "auto";
1182
1027
  case "none": return "none";
@@ -1185,14 +1030,14 @@ function convertResponsesToolChoice(toolChoice) {
1185
1030
  type: "function",
1186
1031
  name: toolChoice.toolName
1187
1032
  };
1188
- default: return void 0;
1033
+ default: return;
1189
1034
  }
1190
1035
  }
1191
1036
 
1192
1037
  //#endregion
1193
1038
  //#region src/responses-agent-language-model/call-options-to-responses-args.ts
1194
1039
  /**
1195
- * Converts AI SDK LanguageModelV2CallOptions to Databricks Responses API body parameters.
1040
+ * Converts AI SDK LanguageModelV3CallOptions to Databricks Responses API body parameters.
1196
1041
  *
1197
1042
  * Inspired by the getArgs method in:
1198
1043
  * https://github.com/vercel/ai/blob/main/packages/openai/src/responses/openai-responses-language-model.ts#L118
@@ -1204,28 +1049,28 @@ function callOptionsToResponsesArgs(options) {
1204
1049
  const warnings = [];
1205
1050
  const databricksOptions = options.providerOptions?.databricks;
1206
1051
  if (options.topK != null) warnings.push({
1207
- type: "unsupported-setting",
1208
- setting: "topK",
1052
+ type: "unsupported",
1053
+ feature: "topK",
1209
1054
  details: "topK is not supported by the Databricks Responses API"
1210
1055
  });
1211
1056
  if (options.presencePenalty != null) warnings.push({
1212
- type: "unsupported-setting",
1213
- setting: "presencePenalty",
1057
+ type: "unsupported",
1058
+ feature: "presencePenalty",
1214
1059
  details: "presencePenalty is not supported by the Databricks Responses API"
1215
1060
  });
1216
1061
  if (options.frequencyPenalty != null) warnings.push({
1217
- type: "unsupported-setting",
1218
- setting: "frequencyPenalty",
1062
+ type: "unsupported",
1063
+ feature: "frequencyPenalty",
1219
1064
  details: "frequencyPenalty is not supported by the Databricks Responses API"
1220
1065
  });
1221
1066
  if (options.seed != null) warnings.push({
1222
- type: "unsupported-setting",
1223
- setting: "seed",
1067
+ type: "unsupported",
1068
+ feature: "seed",
1224
1069
  details: "seed is not supported by the Databricks Responses API"
1225
1070
  });
1226
1071
  if (options.stopSequences != null && options.stopSequences.length > 0) warnings.push({
1227
- type: "unsupported-setting",
1228
- setting: "stopSequences",
1072
+ type: "unsupported",
1073
+ feature: "stopSequences",
1229
1074
  details: "stopSequences is not supported by the Databricks Responses API"
1230
1075
  });
1231
1076
  const args = {};
@@ -1261,16 +1106,27 @@ function callOptionsToResponsesArgs(options) {
1261
1106
  //#endregion
1262
1107
  //#region src/responses-agent-language-model/responses-agent-language-model.ts
1263
1108
  function mapResponsesFinishReason({ finishReason, hasToolCalls }) {
1109
+ let unified;
1264
1110
  switch (finishReason) {
1265
1111
  case void 0:
1266
- case null: return hasToolCalls ? "tool-calls" : "stop";
1267
- case "max_output_tokens": return "length";
1268
- case "content_filter": return "content-filter";
1269
- default: return hasToolCalls ? "tool-calls" : "other";
1112
+ case null:
1113
+ unified = hasToolCalls ? "tool-calls" : "stop";
1114
+ break;
1115
+ case "max_output_tokens":
1116
+ unified = "length";
1117
+ break;
1118
+ case "content_filter":
1119
+ unified = "content-filter";
1120
+ break;
1121
+ default: unified = hasToolCalls ? "tool-calls" : "other";
1270
1122
  }
1123
+ return {
1124
+ raw: finishReason ?? void 0,
1125
+ unified
1126
+ };
1271
1127
  }
1272
1128
  var DatabricksResponsesAgentLanguageModel = class {
1273
- specificationVersion = "v2";
1129
+ specificationVersion = "v3";
1274
1130
  modelId;
1275
1131
  config;
1276
1132
  constructor(modelId, config) {
@@ -1282,16 +1138,16 @@ var DatabricksResponsesAgentLanguageModel = class {
1282
1138
  }
1283
1139
  supportedUrls = {};
1284
1140
  async doGenerate(options) {
1285
- const { warnings,...networkArgs } = await this.getArgs({
1141
+ const { warnings, ...networkArgs } = await this.getArgs({
1286
1142
  config: this.config,
1287
1143
  options,
1288
1144
  stream: false,
1289
1145
  modelId: this.modelId
1290
1146
  });
1291
- const { value: response } = await (0, __ai_sdk_provider_utils.postJsonToApi)({
1147
+ const { value: response } = await (0, _ai_sdk_provider_utils.postJsonToApi)({
1292
1148
  ...networkArgs,
1293
- successfulResponseHandler: (0, __ai_sdk_provider_utils.createJsonResponseHandler)(responsesAgentResponseSchema),
1294
- failedResponseHandler: (0, __ai_sdk_provider_utils.createJsonErrorResponseHandler)({
1149
+ successfulResponseHandler: (0, _ai_sdk_provider_utils.createJsonResponseHandler)(responsesAgentResponseSchema),
1150
+ failedResponseHandler: (0, _ai_sdk_provider_utils.createJsonErrorResponseHandler)({
1295
1151
  errorSchema: zod_v4.z.any(),
1296
1152
  errorToMessage: (error) => JSON.stringify(error),
1297
1153
  isRetryable: () => false
@@ -1306,37 +1162,58 @@ var DatabricksResponsesAgentLanguageModel = class {
1306
1162
  hasToolCalls
1307
1163
  }),
1308
1164
  usage: {
1309
- inputTokens: response.usage?.input_tokens ?? 0,
1310
- outputTokens: response.usage?.output_tokens ?? 0,
1311
- totalTokens: response.usage?.total_tokens ?? 0
1165
+ inputTokens: {
1166
+ total: response.usage?.input_tokens ?? 0,
1167
+ noCache: 0,
1168
+ cacheRead: 0,
1169
+ cacheWrite: 0
1170
+ },
1171
+ outputTokens: {
1172
+ total: response.usage?.output_tokens ?? 0,
1173
+ text: 0,
1174
+ reasoning: 0
1175
+ }
1312
1176
  },
1313
1177
  warnings
1314
1178
  };
1315
1179
  }
1316
1180
  async doStream(options) {
1317
- const { warnings,...networkArgs } = await this.getArgs({
1181
+ const { warnings, ...networkArgs } = await this.getArgs({
1318
1182
  config: this.config,
1319
1183
  options,
1320
1184
  stream: true,
1321
1185
  modelId: this.modelId
1322
1186
  });
1323
- const { responseHeaders, value: response } = await (0, __ai_sdk_provider_utils.postJsonToApi)({
1187
+ const { responseHeaders, value: response } = await (0, _ai_sdk_provider_utils.postJsonToApi)({
1324
1188
  ...networkArgs,
1325
- failedResponseHandler: (0, __ai_sdk_provider_utils.createJsonErrorResponseHandler)({
1189
+ failedResponseHandler: (0, _ai_sdk_provider_utils.createJsonErrorResponseHandler)({
1326
1190
  errorSchema: zod_v4.z.any(),
1327
1191
  errorToMessage: (error) => JSON.stringify(error),
1328
1192
  isRetryable: () => false
1329
1193
  }),
1330
- successfulResponseHandler: (0, __ai_sdk_provider_utils.createEventSourceResponseHandler)(looseResponseAgentChunkSchema),
1194
+ successfulResponseHandler: (0, _ai_sdk_provider_utils.createEventSourceResponseHandler)(looseResponseAgentChunkSchema),
1331
1195
  abortSignal: options.abortSignal
1332
1196
  });
1333
- let finishReason = "unknown";
1197
+ let finishReason = {
1198
+ raw: void 0,
1199
+ unified: "stop"
1200
+ };
1334
1201
  const usage = {
1335
- inputTokens: 0,
1336
- outputTokens: 0,
1337
- totalTokens: 0
1202
+ inputTokens: {
1203
+ total: 0,
1204
+ noCache: 0,
1205
+ cacheRead: 0,
1206
+ cacheWrite: 0
1207
+ },
1208
+ outputTokens: {
1209
+ total: 0,
1210
+ text: 0,
1211
+ reasoning: 0
1212
+ }
1338
1213
  };
1339
1214
  const allParts = [];
1215
+ const useRemoteToolCalling = this.config.useRemoteToolCalling ?? false;
1216
+ const toolNamesByCallId = /* @__PURE__ */ new Map();
1340
1217
  return {
1341
1218
  stream: response.pipeThrough(new TransformStream({
1342
1219
  start(controller) {
@@ -1351,7 +1228,10 @@ var DatabricksResponsesAgentLanguageModel = class {
1351
1228
  rawValue: chunk.rawValue
1352
1229
  });
1353
1230
  if (!chunk.success) {
1354
- finishReason = "error";
1231
+ finishReason = {
1232
+ raw: void 0,
1233
+ unified: "error"
1234
+ };
1355
1235
  controller.enqueue({
1356
1236
  type: "error",
1357
1237
  error: chunk.error
@@ -1364,12 +1244,15 @@ var DatabricksResponsesAgentLanguageModel = class {
1364
1244
  finishReason: chunk.value.response.incomplete_details?.reason,
1365
1245
  hasToolCalls
1366
1246
  });
1367
- usage.inputTokens = chunk.value.response.usage.input_tokens;
1368
- usage.outputTokens = chunk.value.response.usage.output_tokens;
1369
- usage.totalTokens = chunk.value.response.usage.total_tokens;
1247
+ usage.inputTokens.total = chunk.value.response.usage.input_tokens;
1248
+ usage.outputTokens.total = chunk.value.response.usage.output_tokens;
1370
1249
  return;
1371
1250
  }
1372
- const parts = convertResponsesAgentChunkToMessagePart(chunk.value);
1251
+ 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);
1252
+ const parts = convertResponsesAgentChunkToMessagePart(chunk.value, {
1253
+ useRemoteToolCalling,
1254
+ toolNamesByCallId
1255
+ });
1373
1256
  allParts.push(...parts);
1374
1257
  /**
1375
1258
  * Check if the last chunk was a tool result without a tool call
@@ -1384,19 +1267,35 @@ var DatabricksResponsesAgentLanguageModel = class {
1384
1267
  if (!matchingToolCallInParts && !matchingToolCallInStream) {
1385
1268
  const toolCallFromPreviousMessages = options.prompt.flatMap((message) => {
1386
1269
  if (typeof message.content === "string") return [];
1387
- return message.content;
1388
- }).find((p) => p.type === "tool-call" && p.toolCallId === part.toolCallId);
1270
+ return message.content.filter((p) => p.type === "tool-call");
1271
+ }).find((p) => p.toolCallId === part.toolCallId);
1389
1272
  if (!toolCallFromPreviousMessages) throw new Error("No matching tool call found in previous message");
1390
- if (toolCallFromPreviousMessages.type === "tool-call") controller.enqueue({
1391
- ...toolCallFromPreviousMessages,
1392
- input: JSON.stringify(toolCallFromPreviousMessages.input)
1273
+ controller.enqueue({
1274
+ type: "tool-call",
1275
+ toolCallId: toolCallFromPreviousMessages.toolCallId,
1276
+ toolName: toolCallFromPreviousMessages.toolName,
1277
+ input: JSON.stringify(toolCallFromPreviousMessages.input),
1278
+ providerExecuted: true,
1279
+ dynamic: true
1393
1280
  });
1394
1281
  }
1395
1282
  }
1396
1283
  if (shouldDedupeOutputItemDone(parts, allParts.slice(0, -parts.length))) return;
1397
- for (const part$1 of parts) controller.enqueue(part$1);
1284
+ for (const part of parts) controller.enqueue(part);
1398
1285
  },
1399
1286
  flush(controller) {
1287
+ if (!useRemoteToolCalling) {
1288
+ const toolCalls = allParts.filter((p) => p.type === "tool-call");
1289
+ const toolResults = allParts.filter((p) => p.type === "tool-result");
1290
+ for (const toolCall of toolCalls) {
1291
+ if (toolCall.providerMetadata?.databricks?.approvalRequestId != null) continue;
1292
+ if (!toolResults.some((r) => r.toolCallId === toolCall.toolCallId)) controller.enqueue({
1293
+ ...toolCall,
1294
+ providerExecuted: true,
1295
+ dynamic: true
1296
+ });
1297
+ }
1298
+ }
1400
1299
  controller.enqueue({
1401
1300
  type: "finish",
1402
1301
  finishReason,
@@ -1420,7 +1319,7 @@ var DatabricksResponsesAgentLanguageModel = class {
1420
1319
  const { args: callArgs, warnings } = callOptionsToResponsesArgs(options);
1421
1320
  return {
1422
1321
  url: config.url({ path: "/responses" }),
1423
- headers: (0, __ai_sdk_provider_utils.combineHeaders)(config.headers(), options.headers),
1322
+ headers: (0, _ai_sdk_provider_utils.combineHeaders)(config.headers(), options.headers),
1424
1323
  body: {
1425
1324
  model: modelId,
1426
1325
  input,
@@ -1449,8 +1348,7 @@ function shouldDedupeOutputItemDone(incomingParts, previousParts) {
1449
1348
  * corresponds to a specific message and we should only compare against text streamed for that message.
1450
1349
  */
1451
1350
  const lastDoneIndex = previousParts.findLastIndex((part) => part.type === "text-delta" && part.providerMetadata?.databricks?.itemType === "response.output_item.done");
1452
- const partsAfterLastDone = previousParts.slice(lastDoneIndex + 1);
1453
- const { texts: reconstructuredTexts, current } = partsAfterLastDone.reduce((acc, part) => {
1351
+ const { texts: reconstructuredTexts, current } = previousParts.slice(lastDoneIndex + 1).reduce((acc, part) => {
1454
1352
  if (part.type === "text-delta") return {
1455
1353
  ...acc,
1456
1354
  current: acc.current + part.delta
@@ -1464,9 +1362,9 @@ function shouldDedupeOutputItemDone(incomingParts, previousParts) {
1464
1362
  texts: [],
1465
1363
  current: ""
1466
1364
  });
1467
- reconstructuredTexts.push(current);
1365
+ if (current.length > 0) reconstructuredTexts.push(current);
1468
1366
  if (reconstructuredTexts.length === 0) return false;
1469
- const allTextsFoundInOrder = reconstructuredTexts.reduce((acc, text) => {
1367
+ return reconstructuredTexts.reduce((acc, text) => {
1470
1368
  if (!acc.found) return acc;
1471
1369
  const index = doneTextDelta.delta.indexOf(text, acc.lastIndex);
1472
1370
  if (index === -1) return {
@@ -1480,8 +1378,7 @@ function shouldDedupeOutputItemDone(incomingParts, previousParts) {
1480
1378
  }, {
1481
1379
  found: true,
1482
1380
  lastIndex: 0
1483
- });
1484
- return allTextsFoundInOrder.found;
1381
+ }).found;
1485
1382
  }
1486
1383
 
1487
1384
  //#endregion
@@ -1615,12 +1512,12 @@ const convertFmapiChunkToMessagePart = (chunk, toolCallIdsByIndex) => {
1615
1512
  } else if (Array.isArray(choice.delta.content)) parts.push(...mapContentItemsToStreamParts(choice.delta.content, chunk.id));
1616
1513
  return parts;
1617
1514
  };
1618
- const convertFmapiResponseToMessagePart = (response) => {
1515
+ const convertFmapiResponseToMessagePart = (response, options = { useRemoteToolCalling: false }) => {
1619
1516
  const parts = [];
1620
1517
  if (response.choices.length === 0) return parts;
1621
1518
  const choice = response.choices[0];
1622
1519
  if (choice.message.tool_calls && choice.message.tool_calls.length > 0) {
1623
- for (const toolCall of choice.message.tool_calls) parts.push(convertToolCallToContent(toolCall));
1520
+ for (const toolCall of choice.message.tool_calls) parts.push(convertToolCallToContent(toolCall, options));
1624
1521
  if (typeof choice.message.content === "string" && choice.message.content) parts.push({
1625
1522
  type: "text",
1626
1523
  text: choice.message.content
@@ -1634,13 +1531,16 @@ const convertFmapiResponseToMessagePart = (response) => {
1634
1531
  else parts.push(...mapContentItemsToProviderContent(choice.message.content ?? []));
1635
1532
  return parts;
1636
1533
  };
1637
- const convertToolCallToContent = (toolCall) => {
1534
+ const convertToolCallToContent = (toolCall, options) => {
1638
1535
  return {
1639
1536
  type: "tool-call",
1640
1537
  toolCallId: toolCall.id,
1641
- toolName: DATABRICKS_TOOL_CALL_ID,
1538
+ toolName: toolCall.function.name,
1642
1539
  input: toolCall.function.arguments,
1643
- providerMetadata: { databricks: { toolName: toolCall.function.name } }
1540
+ ...options.useRemoteToolCalling && {
1541
+ dynamic: true,
1542
+ providerExecuted: true
1543
+ }
1644
1544
  };
1645
1545
  };
1646
1546
  const mapContentItemsToStreamParts = (items, id) => {
@@ -1654,14 +1554,13 @@ const mapContentItemsToStreamParts = (items, id) => {
1654
1554
  });
1655
1555
  break;
1656
1556
  case "image": break;
1657
- case "reasoning": {
1557
+ case "reasoning":
1658
1558
  for (const summary of item.summary.filter((s) => s.type === "summary_text")) parts.push({
1659
1559
  type: "reasoning-delta",
1660
1560
  id,
1661
1561
  delta: summary.text
1662
1562
  });
1663
1563
  break;
1664
- }
1665
1564
  }
1666
1565
  return parts;
1667
1566
  };
@@ -1675,13 +1574,12 @@ const mapContentItemsToProviderContent = (items) => {
1675
1574
  });
1676
1575
  break;
1677
1576
  case "image": break;
1678
- case "reasoning": {
1577
+ case "reasoning":
1679
1578
  for (const summary of item.summary.filter((s) => s.type === "summary_text")) parts.push({
1680
1579
  type: "reasoning",
1681
1580
  text: summary.text
1682
1581
  });
1683
1582
  break;
1684
- }
1685
1583
  }
1686
1584
  return parts;
1687
1585
  };
@@ -1817,31 +1715,45 @@ const convertToolResultOutputToContentValue = (output) => {
1817
1715
  };
1818
1716
  const ProviderOptionsSchema = zod_v4.z.object({ toolName: zod_v4.z.string().nullish() });
1819
1717
  const getToolNameFromPart = async (part) => {
1820
- const providerOptions = await (0, __ai_sdk_provider_utils.parseProviderOptions)({
1718
+ return (await (0, _ai_sdk_provider_utils.parseProviderOptions)({
1821
1719
  provider: "databricks",
1822
1720
  providerOptions: part.providerOptions,
1823
1721
  schema: ProviderOptionsSchema
1824
- });
1825
- return providerOptions?.toolName ?? part.toolName;
1722
+ }))?.toolName ?? part.toolName;
1826
1723
  };
1827
1724
 
1828
1725
  //#endregion
1829
1726
  //#region src/fmapi-language-model/fmapi-finish-reason.ts
1830
1727
  function mapFmapiFinishReason(finishReason) {
1831
1728
  switch (finishReason) {
1832
- case "stop": return "stop";
1833
- case "length": return "length";
1834
- case "content_filter": return "content-filter";
1729
+ case "stop": return {
1730
+ raw: finishReason,
1731
+ unified: "stop"
1732
+ };
1733
+ case "length": return {
1734
+ raw: finishReason,
1735
+ unified: "length"
1736
+ };
1737
+ case "content_filter": return {
1738
+ raw: finishReason,
1739
+ unified: "content-filter"
1740
+ };
1835
1741
  case "function_call":
1836
- case "tool_calls": return "tool-calls";
1837
- default: return "other";
1742
+ case "tool_calls": return {
1743
+ raw: finishReason,
1744
+ unified: "tool-calls"
1745
+ };
1746
+ default: return {
1747
+ raw: finishReason ?? void 0,
1748
+ unified: "other"
1749
+ };
1838
1750
  }
1839
1751
  }
1840
1752
 
1841
1753
  //#endregion
1842
1754
  //#region src/fmapi-language-model/call-options-to-fmapi-args.ts
1843
1755
  /**
1844
- * Converts AI SDK LanguageModelV2CallOptions to Databricks FMAPI body parameters.
1756
+ * Converts AI SDK LanguageModelV3CallOptions to Databricks FMAPI body parameters.
1845
1757
  *
1846
1758
  * Inspired by the getArgs method in:
1847
1759
  * https://github.com/vercel/ai/blob/main/packages/openai/src/chat/openai-chat-language-model.ts#L71
@@ -1853,18 +1765,18 @@ function callOptionsToFmapiArgs(options) {
1853
1765
  const warnings = [];
1854
1766
  const databricksOptions = options.providerOptions?.databricks;
1855
1767
  if (options.presencePenalty != null) warnings.push({
1856
- type: "unsupported-setting",
1857
- setting: "presencePenalty",
1768
+ type: "unsupported",
1769
+ feature: "presencePenalty",
1858
1770
  details: "presencePenalty is not supported by the Databricks FMAPI"
1859
1771
  });
1860
1772
  if (options.frequencyPenalty != null) warnings.push({
1861
- type: "unsupported-setting",
1862
- setting: "frequencyPenalty",
1773
+ type: "unsupported",
1774
+ feature: "frequencyPenalty",
1863
1775
  details: "frequencyPenalty is not supported by the Databricks FMAPI"
1864
1776
  });
1865
1777
  if (options.seed != null) warnings.push({
1866
- type: "unsupported-setting",
1867
- setting: "seed",
1778
+ type: "unsupported",
1779
+ feature: "seed",
1868
1780
  details: "seed is not supported by the Databricks FMAPI"
1869
1781
  });
1870
1782
  const args = {};
@@ -1904,7 +1816,7 @@ function callOptionsToFmapiArgs(options) {
1904
1816
  //#endregion
1905
1817
  //#region src/fmapi-language-model/fmapi-language-model.ts
1906
1818
  var DatabricksFmapiLanguageModel = class {
1907
- specificationVersion = "v2";
1819
+ specificationVersion = "v3";
1908
1820
  modelId;
1909
1821
  config;
1910
1822
  constructor(modelId, config) {
@@ -1916,16 +1828,16 @@ var DatabricksFmapiLanguageModel = class {
1916
1828
  }
1917
1829
  supportedUrls = {};
1918
1830
  async doGenerate(options) {
1919
- const { warnings,...networkArgs } = await this.getArgs({
1831
+ const { warnings, ...networkArgs } = await this.getArgs({
1920
1832
  config: this.config,
1921
1833
  options,
1922
1834
  stream: false,
1923
1835
  modelId: this.modelId
1924
1836
  });
1925
- const { value: response } = await (0, __ai_sdk_provider_utils.postJsonToApi)({
1837
+ const { value: response } = await (0, _ai_sdk_provider_utils.postJsonToApi)({
1926
1838
  ...networkArgs,
1927
- successfulResponseHandler: (0, __ai_sdk_provider_utils.createJsonResponseHandler)(fmapiResponseSchema),
1928
- failedResponseHandler: (0, __ai_sdk_provider_utils.createJsonErrorResponseHandler)({
1839
+ successfulResponseHandler: (0, _ai_sdk_provider_utils.createJsonResponseHandler)(fmapiResponseSchema),
1840
+ failedResponseHandler: (0, _ai_sdk_provider_utils.createJsonErrorResponseHandler)({
1929
1841
  errorSchema: zod_v4.z.any(),
1930
1842
  errorToMessage: (error) => JSON.stringify(error),
1931
1843
  isRetryable: () => false
@@ -1934,42 +1846,62 @@ var DatabricksFmapiLanguageModel = class {
1934
1846
  const choice = response.choices[0];
1935
1847
  const finishReason = mapFmapiFinishReason(choice?.finish_reason);
1936
1848
  return {
1937
- content: convertFmapiResponseToMessagePart(response),
1849
+ content: convertFmapiResponseToMessagePart(response, { useRemoteToolCalling: this.config.useRemoteToolCalling ?? false }),
1938
1850
  finishReason,
1939
1851
  usage: {
1940
- inputTokens: response.usage?.prompt_tokens ?? 0,
1941
- outputTokens: response.usage?.completion_tokens ?? 0,
1942
- totalTokens: response.usage?.total_tokens ?? 0
1852
+ inputTokens: {
1853
+ total: response.usage?.prompt_tokens ?? 0,
1854
+ noCache: 0,
1855
+ cacheRead: 0,
1856
+ cacheWrite: 0
1857
+ },
1858
+ outputTokens: {
1859
+ total: response.usage?.completion_tokens ?? 0,
1860
+ text: 0,
1861
+ reasoning: 0
1862
+ }
1943
1863
  },
1944
1864
  warnings
1945
1865
  };
1946
1866
  }
1947
1867
  async doStream(options) {
1948
- const { warnings,...networkArgs } = await this.getArgs({
1868
+ const { warnings, ...networkArgs } = await this.getArgs({
1949
1869
  config: this.config,
1950
1870
  options,
1951
1871
  stream: true,
1952
1872
  modelId: this.modelId
1953
1873
  });
1954
- const { responseHeaders, value: response } = await (0, __ai_sdk_provider_utils.postJsonToApi)({
1874
+ const { responseHeaders, value: response } = await (0, _ai_sdk_provider_utils.postJsonToApi)({
1955
1875
  ...networkArgs,
1956
- failedResponseHandler: (0, __ai_sdk_provider_utils.createJsonErrorResponseHandler)({
1876
+ failedResponseHandler: (0, _ai_sdk_provider_utils.createJsonErrorResponseHandler)({
1957
1877
  errorSchema: zod_v4.z.any(),
1958
1878
  errorToMessage: (error) => JSON.stringify(error),
1959
1879
  isRetryable: () => false
1960
1880
  }),
1961
- successfulResponseHandler: (0, __ai_sdk_provider_utils.createEventSourceResponseHandler)(fmapiChunkSchema),
1881
+ successfulResponseHandler: (0, _ai_sdk_provider_utils.createEventSourceResponseHandler)(fmapiChunkSchema),
1962
1882
  abortSignal: options.abortSignal
1963
1883
  });
1964
- let finishReason = "unknown";
1884
+ let finishReason = {
1885
+ raw: void 0,
1886
+ unified: "other"
1887
+ };
1965
1888
  let usage = {
1966
- inputTokens: 0,
1967
- outputTokens: 0,
1968
- totalTokens: 0
1889
+ inputTokens: {
1890
+ total: 0,
1891
+ noCache: 0,
1892
+ cacheRead: 0,
1893
+ cacheWrite: 0
1894
+ },
1895
+ outputTokens: {
1896
+ total: 0,
1897
+ text: 0,
1898
+ reasoning: 0
1899
+ }
1969
1900
  };
1970
- const toolCallIdsByIndex = new Map();
1971
- const toolCallNamesById = new Map();
1972
- const toolCallInputsById = new Map();
1901
+ const toolCallIdsByIndex = /* @__PURE__ */ new Map();
1902
+ const toolCallNamesById = /* @__PURE__ */ new Map();
1903
+ const toolCallInputsById = /* @__PURE__ */ new Map();
1904
+ const useRemoteToolCalling = this.config.useRemoteToolCalling ?? false;
1973
1905
  return {
1974
1906
  stream: response.pipeThrough(new TransformStream({
1975
1907
  start(controller) {
@@ -1984,7 +1916,10 @@ var DatabricksFmapiLanguageModel = class {
1984
1916
  rawValue: chunk.rawValue
1985
1917
  });
1986
1918
  if (!chunk.success) {
1987
- finishReason = "error";
1919
+ finishReason = {
1920
+ raw: void 0,
1921
+ unified: "error"
1922
+ };
1988
1923
  controller.enqueue({
1989
1924
  type: "error",
1990
1925
  error: chunk.error
@@ -1994,9 +1929,17 @@ var DatabricksFmapiLanguageModel = class {
1994
1929
  const choice = chunk.value.choices[0];
1995
1930
  finishReason = mapFmapiFinishReason(choice?.finish_reason);
1996
1931
  if (chunk.value.usage) usage = {
1997
- inputTokens: chunk.value.usage.prompt_tokens ?? 0,
1998
- outputTokens: chunk.value.usage.completion_tokens ?? 0,
1999
- totalTokens: chunk.value.usage.total_tokens ?? 0
1932
+ inputTokens: {
1933
+ total: chunk.value.usage.prompt_tokens ?? 0,
1934
+ noCache: 0,
1935
+ cacheRead: 0,
1936
+ cacheWrite: 0
1937
+ },
1938
+ outputTokens: {
1939
+ total: chunk.value.usage.completion_tokens ?? 0,
1940
+ text: 0,
1941
+ reasoning: 0
1942
+ }
2000
1943
  };
2001
1944
  const parts = convertFmapiChunkToMessagePart(chunk.value, toolCallIdsByIndex);
2002
1945
  for (const part of parts) {
@@ -2021,9 +1964,12 @@ var DatabricksFmapiLanguageModel = class {
2021
1964
  controller.enqueue({
2022
1965
  type: "tool-call",
2023
1966
  toolCallId,
2024
- toolName: DATABRICKS_TOOL_CALL_ID,
1967
+ toolName,
2025
1968
  input: inputText,
2026
- providerMetadata: { databricks: { toolName } }
1969
+ ...useRemoteToolCalling && {
1970
+ dynamic: true,
1971
+ providerExecuted: true
1972
+ }
2027
1973
  });
2028
1974
  }
2029
1975
  }
@@ -2045,7 +1991,7 @@ var DatabricksFmapiLanguageModel = class {
2045
1991
  const { args: callArgs, warnings } = callOptionsToFmapiArgs(options);
2046
1992
  return {
2047
1993
  url: config.url({ path: "/chat/completions" }),
2048
- headers: (0, __ai_sdk_provider_utils.combineHeaders)(config.headers(), options.headers),
1994
+ headers: (0, _ai_sdk_provider_utils.combineHeaders)(config.headers(), options.headers),
2049
1995
  body: {
2050
1996
  messages,
2051
1997
  stream,
@@ -2063,7 +2009,7 @@ var DatabricksFmapiLanguageModel = class {
2063
2009
  * Convert AI SDK tool to OpenAI format
2064
2010
  */
2065
2011
  function convertToolToOpenAIFormat(tool) {
2066
- if (tool.type === "provider-defined" || tool.name === DATABRICKS_TOOL_CALL_ID) return void 0;
2012
+ if (tool.type === "provider") return;
2067
2013
  return {
2068
2014
  type: "function",
2069
2015
  function: {
@@ -2090,8 +2036,8 @@ function convertToolChoiceToOpenAIFormat(toolChoice) {
2090
2036
  //#endregion
2091
2037
  //#region src/databricks-provider.ts
2092
2038
  const createDatabricksProvider = (settings) => {
2093
- const baseUrl = (0, __ai_sdk_provider_utils.withoutTrailingSlash)(settings.baseURL);
2094
- const getHeaders = () => (0, __ai_sdk_provider_utils.combineHeaders)(settings.headers);
2039
+ const baseUrl = (0, _ai_sdk_provider_utils.withoutTrailingSlash)(settings.baseURL);
2040
+ const getHeaders = () => (0, _ai_sdk_provider_utils.combineHeaders)(settings.headers);
2095
2041
  const fetch = settings.fetch;
2096
2042
  const provider = settings.provider ?? "databricks";
2097
2043
  const formatUrl = ({ path }) => settings.formatUrl?.({
@@ -2108,13 +2054,15 @@ const createDatabricksProvider = (settings) => {
2108
2054
  url: formatUrl,
2109
2055
  headers: getHeaders,
2110
2056
  fetch,
2111
- provider
2057
+ provider,
2058
+ useRemoteToolCalling: settings.useRemoteToolCalling
2112
2059
  });
2113
2060
  const createFmapi = (modelId) => new DatabricksFmapiLanguageModel(modelId, {
2114
2061
  url: formatUrl,
2115
2062
  headers: getHeaders,
2116
2063
  fetch,
2117
- provider
2064
+ provider,
2065
+ useRemoteToolCalling: settings.useRemoteToolCalling
2118
2066
  });
2119
2067
  const notImplemented = (name) => {
2120
2068
  return () => {
@@ -2122,28 +2070,17 @@ const createDatabricksProvider = (settings) => {
2122
2070
  };
2123
2071
  };
2124
2072
  return {
2073
+ specificationVersion: "v3",
2125
2074
  responses: createResponsesAgent,
2126
2075
  chatCompletions: createFmapi,
2127
2076
  chatAgent: createChatAgent,
2128
2077
  imageModel: notImplemented("ImageModel"),
2129
2078
  textEmbeddingModel: notImplemented("TextEmbeddingModel"),
2079
+ embeddingModel: notImplemented("EmbeddingModel"),
2130
2080
  languageModel: notImplemented("LanguageModel")
2131
2081
  };
2132
2082
  };
2133
2083
 
2134
2084
  //#endregion
2135
- exports.DATABRICKS_TOOL_CALL_ID = DATABRICKS_TOOL_CALL_ID
2136
- exports.DATABRICKS_TOOL_DEFINITION = DATABRICKS_TOOL_DEFINITION
2137
- exports.MCP_APPROVAL_REQUEST_TYPE = MCP_APPROVAL_REQUEST_TYPE
2138
- exports.MCP_APPROVAL_RESPONSE_TYPE = MCP_APPROVAL_RESPONSE_TYPE
2139
- exports.MCP_APPROVAL_STATUS_KEY = MCP_APPROVAL_STATUS_KEY
2140
- exports.createApprovalStatusOutput = createApprovalStatusOutput
2141
- exports.createDatabricksProvider = createDatabricksProvider
2142
- exports.extractApprovalStatus = extractApprovalStatus
2143
- exports.extractApprovalStatusFromToolResult = extractApprovalStatusFromToolResult
2144
- exports.extractDatabricksMetadata = extractDatabricksMetadata
2145
- exports.getMcpApprovalState = getMcpApprovalState
2146
- exports.isApprovalStatusOutput = isApprovalStatusOutput
2147
- exports.isMcpApprovalRequest = isMcpApprovalRequest
2148
- exports.isMcpApprovalResponse = isMcpApprovalResponse
2085
+ exports.createDatabricksProvider = createDatabricksProvider;
2149
2086
  //# sourceMappingURL=index.cjs.map