@databricks/ai-sdk-provider 0.2.2 → 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.
@@ -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: DATABRICKS_TOOL_CALL_ID
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: DATABRICKS_TOOL_CALL_ID
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 convertLanguageModelV2PromptToChatAgentResponse = (prompt) => {
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
- const incomingMatchesLast = Boolean(isDeltaPart(last) && isDeltaPart(incoming)) && Boolean(lastDeltaType && incomingDeltaType) && Boolean(lastDeltaType === incomingDeltaType) && Boolean(incomingId && lastId && incomingId === lastId);
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 = "v2";
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
- ...networkArgs,
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: "stop",
344
+ finishReason: {
345
+ raw: void 0,
346
+ unified: "stop"
347
+ },
370
348
  usage: {
371
- inputTokens: 0,
372
- outputTokens: 0,
373
- 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
+ }
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 = "unknown";
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 = "error";
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: 0,
425
- outputTokens: 0,
426
- 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
+ }
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: convertLanguageModelV2PromptToChatAgentResponse(options.prompt)
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: DATABRICKS_TOOL_CALL_ID
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: DATABRICKS_TOOL_CALL_ID,
807
+ toolName: item.name,
811
808
  input: item.arguments,
812
- providerMetadata: { databricks: {
813
- toolName: item.name,
814
- itemId: item.id
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: DATABRICKS_TOOL_CALL_ID
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: DATABRICKS_TOOL_CALL_ID,
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: DATABRICKS_TOOL_CALL_ID,
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: DATABRICKS_TOOL_CALL_ID,
886
+ toolName: output.name,
884
887
  input: output.arguments,
885
- providerMetadata: { databricks: {
886
- toolName: output.name,
887
- itemId: output.id
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: DATABRICKS_TOOL_CALL_ID
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: DATABRICKS_TOOL_CALL_ID,
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: DATABRICKS_TOOL_CALL_ID,
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
- default: return JSON.stringify(output.value);
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-defined" || tool.name === DATABRICKS_TOOL_CALL_ID) continue;
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: convertedToolChoice
1152
+ toolChoice: convertResponsesToolChoice(toolChoice)
1152
1153
  };
1153
1154
  }
1154
1155
  function convertResponsesToolChoice(toolChoice) {
1155
- if (!toolChoice) return void 0;
1156
+ if (!toolChoice) return;
1156
1157
  switch (toolChoice.type) {
1157
1158
  case "auto": return "auto";
1158
1159
  case "none": return "none";
@@ -1161,23 +1162,103 @@ function convertResponsesToolChoice(toolChoice) {
1161
1162
  type: "function",
1162
1163
  name: toolChoice.toolName
1163
1164
  };
1164
- default: return void 0;
1165
+ default: return;
1165
1166
  }
1166
1167
  }
1167
1168
 
1169
+ //#endregion
1170
+ //#region src/responses-agent-language-model/call-options-to-responses-args.ts
1171
+ /**
1172
+ * Converts AI SDK LanguageModelV3CallOptions to Databricks Responses API body parameters.
1173
+ *
1174
+ * Inspired by the getArgs method in:
1175
+ * https://github.com/vercel/ai/blob/main/packages/openai/src/responses/openai-responses-language-model.ts#L118
1176
+ *
1177
+ * Complies with the API described in:
1178
+ * https://docs.databricks.com/aws/en/machine-learning/foundation-model-apis/api-reference#responses-api-request
1179
+ */
1180
+ function callOptionsToResponsesArgs(options) {
1181
+ const warnings = [];
1182
+ const databricksOptions = options.providerOptions?.databricks;
1183
+ if (options.topK != null) warnings.push({
1184
+ type: "unsupported",
1185
+ feature: "topK",
1186
+ details: "topK is not supported by the Databricks Responses API"
1187
+ });
1188
+ if (options.presencePenalty != null) warnings.push({
1189
+ type: "unsupported",
1190
+ feature: "presencePenalty",
1191
+ details: "presencePenalty is not supported by the Databricks Responses API"
1192
+ });
1193
+ if (options.frequencyPenalty != null) warnings.push({
1194
+ type: "unsupported",
1195
+ feature: "frequencyPenalty",
1196
+ details: "frequencyPenalty is not supported by the Databricks Responses API"
1197
+ });
1198
+ if (options.seed != null) warnings.push({
1199
+ type: "unsupported",
1200
+ feature: "seed",
1201
+ details: "seed is not supported by the Databricks Responses API"
1202
+ });
1203
+ if (options.stopSequences != null && options.stopSequences.length > 0) warnings.push({
1204
+ type: "unsupported",
1205
+ feature: "stopSequences",
1206
+ details: "stopSequences is not supported by the Databricks Responses API"
1207
+ });
1208
+ const args = {};
1209
+ if (options.maxOutputTokens != null) args.max_output_tokens = options.maxOutputTokens;
1210
+ if (options.temperature != null) args.temperature = options.temperature;
1211
+ if (options.topP != null) args.top_p = options.topP;
1212
+ if (options.responseFormat != null) switch (options.responseFormat.type) {
1213
+ case "text":
1214
+ args.text = { format: { type: "text" } };
1215
+ break;
1216
+ case "json":
1217
+ if (options.responseFormat.schema != null) args.text = { format: {
1218
+ type: "json_schema",
1219
+ json_schema: {
1220
+ name: options.responseFormat.name ?? "response",
1221
+ description: options.responseFormat.description,
1222
+ schema: options.responseFormat.schema,
1223
+ strict: true
1224
+ }
1225
+ } };
1226
+ else args.text = { format: { type: "json_object" } };
1227
+ break;
1228
+ }
1229
+ if (databricksOptions?.parallelToolCalls != null) args.parallel_tool_calls = databricksOptions.parallelToolCalls;
1230
+ if (databricksOptions?.metadata != null) args.metadata = databricksOptions.metadata;
1231
+ if (databricksOptions?.reasoning != null) args.reasoning = databricksOptions.reasoning;
1232
+ return {
1233
+ args,
1234
+ warnings
1235
+ };
1236
+ }
1237
+
1168
1238
  //#endregion
1169
1239
  //#region src/responses-agent-language-model/responses-agent-language-model.ts
1170
1240
  function mapResponsesFinishReason({ finishReason, hasToolCalls }) {
1241
+ let unified;
1171
1242
  switch (finishReason) {
1172
1243
  case void 0:
1173
- case null: return hasToolCalls ? "tool-calls" : "stop";
1174
- case "max_output_tokens": return "length";
1175
- case "content_filter": return "content-filter";
1176
- default: return hasToolCalls ? "tool-calls" : "other";
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";
1177
1254
  }
1255
+ return {
1256
+ raw: finishReason ?? void 0,
1257
+ unified
1258
+ };
1178
1259
  }
1179
1260
  var DatabricksResponsesAgentLanguageModel = class {
1180
- specificationVersion = "v2";
1261
+ specificationVersion = "v3";
1181
1262
  modelId;
1182
1263
  config;
1183
1264
  constructor(modelId, config) {
@@ -1189,7 +1270,7 @@ var DatabricksResponsesAgentLanguageModel = class {
1189
1270
  }
1190
1271
  supportedUrls = {};
1191
1272
  async doGenerate(options) {
1192
- const networkArgs = await this.getArgs({
1273
+ const { warnings, ...networkArgs } = await this.getArgs({
1193
1274
  config: this.config,
1194
1275
  options,
1195
1276
  stream: false,
@@ -1213,15 +1294,23 @@ var DatabricksResponsesAgentLanguageModel = class {
1213
1294
  hasToolCalls
1214
1295
  }),
1215
1296
  usage: {
1216
- inputTokens: response.usage?.input_tokens ?? 0,
1217
- outputTokens: response.usage?.output_tokens ?? 0,
1218
- totalTokens: response.usage?.total_tokens ?? 0
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
+ }
1219
1308
  },
1220
- warnings: []
1309
+ warnings
1221
1310
  };
1222
1311
  }
1223
1312
  async doStream(options) {
1224
- const networkArgs = await this.getArgs({
1313
+ const { warnings, ...networkArgs } = await this.getArgs({
1225
1314
  config: this.config,
1226
1315
  options,
1227
1316
  stream: true,
@@ -1237,19 +1326,32 @@ var DatabricksResponsesAgentLanguageModel = class {
1237
1326
  successfulResponseHandler: createEventSourceResponseHandler(looseResponseAgentChunkSchema),
1238
1327
  abortSignal: options.abortSignal
1239
1328
  });
1240
- let finishReason = "unknown";
1329
+ let finishReason = {
1330
+ raw: void 0,
1331
+ unified: "stop"
1332
+ };
1241
1333
  const usage = {
1242
- inputTokens: 0,
1243
- outputTokens: 0,
1244
- totalTokens: 0
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
+ }
1245
1345
  };
1246
1346
  const allParts = [];
1347
+ const useRemoteToolCalling = this.config.useRemoteToolCalling ?? false;
1348
+ const toolNamesByCallId = /* @__PURE__ */ new Map();
1247
1349
  return {
1248
1350
  stream: response.pipeThrough(new TransformStream({
1249
1351
  start(controller) {
1250
1352
  controller.enqueue({
1251
1353
  type: "stream-start",
1252
- warnings: []
1354
+ warnings
1253
1355
  });
1254
1356
  },
1255
1357
  transform(chunk, controller) {
@@ -1258,7 +1360,10 @@ var DatabricksResponsesAgentLanguageModel = class {
1258
1360
  rawValue: chunk.rawValue
1259
1361
  });
1260
1362
  if (!chunk.success) {
1261
- finishReason = "error";
1363
+ finishReason = {
1364
+ raw: void 0,
1365
+ unified: "error"
1366
+ };
1262
1367
  controller.enqueue({
1263
1368
  type: "error",
1264
1369
  error: chunk.error
@@ -1271,12 +1376,15 @@ var DatabricksResponsesAgentLanguageModel = class {
1271
1376
  finishReason: chunk.value.response.incomplete_details?.reason,
1272
1377
  hasToolCalls
1273
1378
  });
1274
- usage.inputTokens = chunk.value.response.usage.input_tokens;
1275
- usage.outputTokens = chunk.value.response.usage.output_tokens;
1276
- 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;
1277
1381
  return;
1278
1382
  }
1279
- const parts = convertResponsesAgentChunkToMessagePart(chunk.value);
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
+ });
1280
1388
  allParts.push(...parts);
1281
1389
  /**
1282
1390
  * Check if the last chunk was a tool result without a tool call
@@ -1291,19 +1399,33 @@ var DatabricksResponsesAgentLanguageModel = class {
1291
1399
  if (!matchingToolCallInParts && !matchingToolCallInStream) {
1292
1400
  const toolCallFromPreviousMessages = options.prompt.flatMap((message) => {
1293
1401
  if (typeof message.content === "string") return [];
1294
- return message.content;
1295
- }).find((p) => p.type === "tool-call" && p.toolCallId === part.toolCallId);
1402
+ return message.content.filter((p) => p.type === "tool-call");
1403
+ }).find((p) => p.toolCallId === part.toolCallId);
1296
1404
  if (!toolCallFromPreviousMessages) throw new Error("No matching tool call found in previous message");
1297
- if (toolCallFromPreviousMessages.type === "tool-call") controller.enqueue({
1298
- ...toolCallFromPreviousMessages,
1405
+ controller.enqueue({
1406
+ type: "tool-call",
1407
+ toolCallId: toolCallFromPreviousMessages.toolCallId,
1408
+ toolName: toolCallFromPreviousMessages.toolName,
1299
1409
  input: JSON.stringify(toolCallFromPreviousMessages.input)
1300
1410
  });
1301
1411
  }
1302
1412
  }
1303
1413
  if (shouldDedupeOutputItemDone(parts, allParts.slice(0, -parts.length))) return;
1304
- for (const part$1 of parts) controller.enqueue(part$1);
1414
+ for (const part of parts) controller.enqueue(part);
1305
1415
  },
1306
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
+ }
1307
1429
  controller.enqueue({
1308
1430
  type: "finish",
1309
1431
  finishReason,
@@ -1324,6 +1446,7 @@ var DatabricksResponsesAgentLanguageModel = class {
1324
1446
  tools: options.tools,
1325
1447
  toolChoice: options.toolChoice
1326
1448
  });
1449
+ const { args: callArgs, warnings } = callOptionsToResponsesArgs(options);
1327
1450
  return {
1328
1451
  url: config.url({ path: "/responses" }),
1329
1452
  headers: combineHeaders(config.headers(), options.headers),
@@ -1332,8 +1455,10 @@ var DatabricksResponsesAgentLanguageModel = class {
1332
1455
  input,
1333
1456
  stream,
1334
1457
  ...tools ? { tools } : {},
1335
- ...toolChoice && tools ? { tool_choice: toolChoice } : {}
1458
+ ...toolChoice && tools ? { tool_choice: toolChoice } : {},
1459
+ ...callArgs
1336
1460
  },
1461
+ warnings,
1337
1462
  fetch: config.fetch
1338
1463
  };
1339
1464
  }
@@ -1353,8 +1478,7 @@ function shouldDedupeOutputItemDone(incomingParts, previousParts) {
1353
1478
  * corresponds to a specific message and we should only compare against text streamed for that message.
1354
1479
  */
1355
1480
  const lastDoneIndex = previousParts.findLastIndex((part) => part.type === "text-delta" && part.providerMetadata?.databricks?.itemType === "response.output_item.done");
1356
- const partsAfterLastDone = previousParts.slice(lastDoneIndex + 1);
1357
- const { texts: reconstructuredTexts, current } = partsAfterLastDone.reduce((acc, part) => {
1481
+ const { texts: reconstructuredTexts, current } = previousParts.slice(lastDoneIndex + 1).reduce((acc, part) => {
1358
1482
  if (part.type === "text-delta") return {
1359
1483
  ...acc,
1360
1484
  current: acc.current + part.delta
@@ -1368,9 +1492,9 @@ function shouldDedupeOutputItemDone(incomingParts, previousParts) {
1368
1492
  texts: [],
1369
1493
  current: ""
1370
1494
  });
1371
- reconstructuredTexts.push(current);
1495
+ if (current.length > 0) reconstructuredTexts.push(current);
1372
1496
  if (reconstructuredTexts.length === 0) return false;
1373
- const allTextsFoundInOrder = reconstructuredTexts.reduce((acc, text) => {
1497
+ return reconstructuredTexts.reduce((acc, text) => {
1374
1498
  if (!acc.found) return acc;
1375
1499
  const index = doneTextDelta.delta.indexOf(text, acc.lastIndex);
1376
1500
  if (index === -1) return {
@@ -1384,8 +1508,7 @@ function shouldDedupeOutputItemDone(incomingParts, previousParts) {
1384
1508
  }, {
1385
1509
  found: true,
1386
1510
  lastIndex: 0
1387
- });
1388
- return allTextsFoundInOrder.found;
1511
+ }).found;
1389
1512
  }
1390
1513
 
1391
1514
  //#endregion
@@ -1519,12 +1642,12 @@ const convertFmapiChunkToMessagePart = (chunk, toolCallIdsByIndex) => {
1519
1642
  } else if (Array.isArray(choice.delta.content)) parts.push(...mapContentItemsToStreamParts(choice.delta.content, chunk.id));
1520
1643
  return parts;
1521
1644
  };
1522
- const convertFmapiResponseToMessagePart = (response) => {
1645
+ const convertFmapiResponseToMessagePart = (response, options = { useRemoteToolCalling: false }) => {
1523
1646
  const parts = [];
1524
1647
  if (response.choices.length === 0) return parts;
1525
1648
  const choice = response.choices[0];
1526
1649
  if (choice.message.tool_calls && choice.message.tool_calls.length > 0) {
1527
- 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));
1528
1651
  if (typeof choice.message.content === "string" && choice.message.content) parts.push({
1529
1652
  type: "text",
1530
1653
  text: choice.message.content
@@ -1538,13 +1661,16 @@ const convertFmapiResponseToMessagePart = (response) => {
1538
1661
  else parts.push(...mapContentItemsToProviderContent(choice.message.content ?? []));
1539
1662
  return parts;
1540
1663
  };
1541
- const convertToolCallToContent = (toolCall) => {
1664
+ const convertToolCallToContent = (toolCall, options) => {
1542
1665
  return {
1543
1666
  type: "tool-call",
1544
1667
  toolCallId: toolCall.id,
1545
- toolName: DATABRICKS_TOOL_CALL_ID,
1668
+ toolName: toolCall.function.name,
1546
1669
  input: toolCall.function.arguments,
1547
- providerMetadata: { databricks: { toolName: toolCall.function.name } }
1670
+ ...options.useRemoteToolCalling && {
1671
+ dynamic: true,
1672
+ providerExecuted: true
1673
+ }
1548
1674
  };
1549
1675
  };
1550
1676
  const mapContentItemsToStreamParts = (items, id) => {
@@ -1558,14 +1684,13 @@ const mapContentItemsToStreamParts = (items, id) => {
1558
1684
  });
1559
1685
  break;
1560
1686
  case "image": break;
1561
- case "reasoning": {
1687
+ case "reasoning":
1562
1688
  for (const summary of item.summary.filter((s) => s.type === "summary_text")) parts.push({
1563
1689
  type: "reasoning-delta",
1564
1690
  id,
1565
1691
  delta: summary.text
1566
1692
  });
1567
1693
  break;
1568
- }
1569
1694
  }
1570
1695
  return parts;
1571
1696
  };
@@ -1579,13 +1704,12 @@ const mapContentItemsToProviderContent = (items) => {
1579
1704
  });
1580
1705
  break;
1581
1706
  case "image": break;
1582
- case "reasoning": {
1707
+ case "reasoning":
1583
1708
  for (const summary of item.summary.filter((s) => s.type === "summary_text")) parts.push({
1584
1709
  type: "reasoning",
1585
1710
  text: summary.text
1586
1711
  });
1587
1712
  break;
1588
- }
1589
1713
  }
1590
1714
  return parts;
1591
1715
  };
@@ -1721,31 +1845,108 @@ const convertToolResultOutputToContentValue = (output) => {
1721
1845
  };
1722
1846
  const ProviderOptionsSchema = z.object({ toolName: z.string().nullish() });
1723
1847
  const getToolNameFromPart = async (part) => {
1724
- const providerOptions = await parseProviderOptions({
1848
+ return (await parseProviderOptions({
1725
1849
  provider: "databricks",
1726
1850
  providerOptions: part.providerOptions,
1727
1851
  schema: ProviderOptionsSchema
1728
- });
1729
- return providerOptions?.toolName ?? part.toolName;
1852
+ }))?.toolName ?? part.toolName;
1730
1853
  };
1731
1854
 
1732
1855
  //#endregion
1733
1856
  //#region src/fmapi-language-model/fmapi-finish-reason.ts
1734
1857
  function mapFmapiFinishReason(finishReason) {
1735
1858
  switch (finishReason) {
1736
- case "stop": return "stop";
1737
- case "length": return "length";
1738
- case "content_filter": return "content-filter";
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
+ };
1739
1871
  case "function_call":
1740
- case "tool_calls": return "tool-calls";
1741
- default: return "other";
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
+ };
1742
1880
  }
1743
1881
  }
1744
1882
 
1883
+ //#endregion
1884
+ //#region src/fmapi-language-model/call-options-to-fmapi-args.ts
1885
+ /**
1886
+ * Converts AI SDK LanguageModelV3CallOptions to Databricks FMAPI body parameters.
1887
+ *
1888
+ * Inspired by the getArgs method in:
1889
+ * https://github.com/vercel/ai/blob/main/packages/openai/src/chat/openai-chat-language-model.ts#L71
1890
+ *
1891
+ * Complies with the API described in:
1892
+ * https://docs.databricks.com/aws/en/machine-learning/foundation-model-apis/api-reference#chat-request
1893
+ */
1894
+ function callOptionsToFmapiArgs(options) {
1895
+ const warnings = [];
1896
+ const databricksOptions = options.providerOptions?.databricks;
1897
+ if (options.presencePenalty != null) warnings.push({
1898
+ type: "unsupported",
1899
+ feature: "presencePenalty",
1900
+ details: "presencePenalty is not supported by the Databricks FMAPI"
1901
+ });
1902
+ if (options.frequencyPenalty != null) warnings.push({
1903
+ type: "unsupported",
1904
+ feature: "frequencyPenalty",
1905
+ details: "frequencyPenalty is not supported by the Databricks FMAPI"
1906
+ });
1907
+ if (options.seed != null) warnings.push({
1908
+ type: "unsupported",
1909
+ feature: "seed",
1910
+ details: "seed is not supported by the Databricks FMAPI"
1911
+ });
1912
+ const args = {};
1913
+ if (options.maxOutputTokens != null) args.max_tokens = options.maxOutputTokens;
1914
+ if (options.temperature != null) args.temperature = options.temperature;
1915
+ if (options.topP != null) args.top_p = options.topP;
1916
+ if (options.topK != null) args.top_k = options.topK;
1917
+ if (options.stopSequences != null && options.stopSequences.length > 0) args.stop = options.stopSequences;
1918
+ if (options.responseFormat != null) switch (options.responseFormat.type) {
1919
+ case "text":
1920
+ args.response_format = { type: "text" };
1921
+ break;
1922
+ case "json":
1923
+ if (options.responseFormat.schema != null) args.response_format = {
1924
+ type: "json_schema",
1925
+ json_schema: {
1926
+ name: options.responseFormat.name ?? "response",
1927
+ description: options.responseFormat.description,
1928
+ schema: options.responseFormat.schema,
1929
+ strict: true
1930
+ }
1931
+ };
1932
+ else args.response_format = { type: "json_object" };
1933
+ break;
1934
+ }
1935
+ if (databricksOptions?.topK != null) args.top_k = databricksOptions.topK;
1936
+ if (databricksOptions?.n != null) args.n = databricksOptions.n;
1937
+ if (databricksOptions?.logprobs != null) args.logprobs = databricksOptions.logprobs;
1938
+ if (databricksOptions?.topLogprobs != null) args.top_logprobs = databricksOptions.topLogprobs;
1939
+ if (databricksOptions?.reasoningEffort != null) args.reasoning_effort = databricksOptions.reasoningEffort;
1940
+ return {
1941
+ args,
1942
+ warnings
1943
+ };
1944
+ }
1945
+
1745
1946
  //#endregion
1746
1947
  //#region src/fmapi-language-model/fmapi-language-model.ts
1747
1948
  var DatabricksFmapiLanguageModel = class {
1748
- specificationVersion = "v2";
1949
+ specificationVersion = "v3";
1749
1950
  modelId;
1750
1951
  config;
1751
1952
  constructor(modelId, config) {
@@ -1757,7 +1958,7 @@ var DatabricksFmapiLanguageModel = class {
1757
1958
  }
1758
1959
  supportedUrls = {};
1759
1960
  async doGenerate(options) {
1760
- const networkArgs = await this.getArgs({
1961
+ const { warnings, ...networkArgs } = await this.getArgs({
1761
1962
  config: this.config,
1762
1963
  options,
1763
1964
  stream: false,
@@ -1775,18 +1976,26 @@ var DatabricksFmapiLanguageModel = class {
1775
1976
  const choice = response.choices[0];
1776
1977
  const finishReason = mapFmapiFinishReason(choice?.finish_reason);
1777
1978
  return {
1778
- content: convertFmapiResponseToMessagePart(response),
1979
+ content: convertFmapiResponseToMessagePart(response, { useRemoteToolCalling: this.config.useRemoteToolCalling ?? false }),
1779
1980
  finishReason,
1780
1981
  usage: {
1781
- inputTokens: response.usage?.prompt_tokens ?? 0,
1782
- outputTokens: response.usage?.completion_tokens ?? 0,
1783
- totalTokens: response.usage?.total_tokens ?? 0
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
+ }
1784
1993
  },
1785
- warnings: []
1994
+ warnings
1786
1995
  };
1787
1996
  }
1788
1997
  async doStream(options) {
1789
- const networkArgs = await this.getArgs({
1998
+ const { warnings, ...networkArgs } = await this.getArgs({
1790
1999
  config: this.config,
1791
2000
  options,
1792
2001
  stream: true,
@@ -1802,21 +2011,33 @@ var DatabricksFmapiLanguageModel = class {
1802
2011
  successfulResponseHandler: createEventSourceResponseHandler(fmapiChunkSchema),
1803
2012
  abortSignal: options.abortSignal
1804
2013
  });
1805
- let finishReason = "unknown";
2014
+ let finishReason = {
2015
+ raw: void 0,
2016
+ unified: "other"
2017
+ };
1806
2018
  let usage = {
1807
- inputTokens: 0,
1808
- outputTokens: 0,
1809
- totalTokens: 0
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
+ }
1810
2030
  };
1811
- const toolCallIdsByIndex = new Map();
1812
- const toolCallNamesById = new Map();
1813
- 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;
1814
2035
  return {
1815
2036
  stream: response.pipeThrough(new TransformStream({
1816
2037
  start(controller) {
1817
2038
  controller.enqueue({
1818
2039
  type: "stream-start",
1819
- warnings: []
2040
+ warnings
1820
2041
  });
1821
2042
  },
1822
2043
  transform(chunk, controller) {
@@ -1825,7 +2046,10 @@ var DatabricksFmapiLanguageModel = class {
1825
2046
  rawValue: chunk.rawValue
1826
2047
  });
1827
2048
  if (!chunk.success) {
1828
- finishReason = "error";
2049
+ finishReason = {
2050
+ raw: void 0,
2051
+ unified: "error"
2052
+ };
1829
2053
  controller.enqueue({
1830
2054
  type: "error",
1831
2055
  error: chunk.error
@@ -1835,9 +2059,17 @@ var DatabricksFmapiLanguageModel = class {
1835
2059
  const choice = chunk.value.choices[0];
1836
2060
  finishReason = mapFmapiFinishReason(choice?.finish_reason);
1837
2061
  if (chunk.value.usage) usage = {
1838
- inputTokens: chunk.value.usage.prompt_tokens ?? 0,
1839
- outputTokens: chunk.value.usage.completion_tokens ?? 0,
1840
- totalTokens: chunk.value.usage.total_tokens ?? 0
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
+ }
1841
2073
  };
1842
2074
  const parts = convertFmapiChunkToMessagePart(chunk.value, toolCallIdsByIndex);
1843
2075
  for (const part of parts) {
@@ -1862,9 +2094,12 @@ var DatabricksFmapiLanguageModel = class {
1862
2094
  controller.enqueue({
1863
2095
  type: "tool-call",
1864
2096
  toolCallId,
1865
- toolName: DATABRICKS_TOOL_CALL_ID,
2097
+ toolName,
1866
2098
  input: inputText,
1867
- providerMetadata: { databricks: { toolName } }
2099
+ ...useRemoteToolCalling && {
2100
+ dynamic: true,
2101
+ providerExecuted: true
2102
+ }
1868
2103
  });
1869
2104
  }
1870
2105
  }
@@ -1883,6 +2118,7 @@ var DatabricksFmapiLanguageModel = class {
1883
2118
  const tools = options.tools?.map((tool) => convertToolToOpenAIFormat(tool)).filter((tool) => tool !== void 0);
1884
2119
  const toolChoice = options.toolChoice ? convertToolChoiceToOpenAIFormat(options.toolChoice) : void 0;
1885
2120
  const { messages } = await convertPromptToFmapiMessages(options.prompt);
2121
+ const { args: callArgs, warnings } = callOptionsToFmapiArgs(options);
1886
2122
  return {
1887
2123
  url: config.url({ path: "/chat/completions" }),
1888
2124
  headers: combineHeaders(config.headers(), options.headers),
@@ -1892,10 +2128,9 @@ var DatabricksFmapiLanguageModel = class {
1892
2128
  model: modelId,
1893
2129
  ...tools && tools.length > 0 ? { tools } : {},
1894
2130
  ...toolChoice && tools && tools.length > 0 ? { tool_choice: toolChoice } : {},
1895
- ...options.temperature !== void 0 ? { temperature: options.temperature } : {},
1896
- ...options.maxOutputTokens !== void 0 ? { max_tokens: options.maxOutputTokens } : {},
1897
- ...options.stopSequences && options.stopSequences.length > 0 ? { stop: options.stopSequences } : {}
2131
+ ...callArgs
1898
2132
  },
2133
+ warnings,
1899
2134
  fetch: config.fetch
1900
2135
  };
1901
2136
  }
@@ -1904,7 +2139,7 @@ var DatabricksFmapiLanguageModel = class {
1904
2139
  * Convert AI SDK tool to OpenAI format
1905
2140
  */
1906
2141
  function convertToolToOpenAIFormat(tool) {
1907
- if (tool.type === "provider-defined" || tool.name === DATABRICKS_TOOL_CALL_ID) return void 0;
2142
+ if (tool.type === "provider") return;
1908
2143
  return {
1909
2144
  type: "function",
1910
2145
  function: {
@@ -1949,13 +2184,15 @@ const createDatabricksProvider = (settings) => {
1949
2184
  url: formatUrl,
1950
2185
  headers: getHeaders,
1951
2186
  fetch,
1952
- provider
2187
+ provider,
2188
+ useRemoteToolCalling: settings.useRemoteToolCalling
1953
2189
  });
1954
2190
  const createFmapi = (modelId) => new DatabricksFmapiLanguageModel(modelId, {
1955
2191
  url: formatUrl,
1956
2192
  headers: getHeaders,
1957
2193
  fetch,
1958
- provider
2194
+ provider,
2195
+ useRemoteToolCalling: settings.useRemoteToolCalling
1959
2196
  });
1960
2197
  const notImplemented = (name) => {
1961
2198
  return () => {
@@ -1963,15 +2200,17 @@ const createDatabricksProvider = (settings) => {
1963
2200
  };
1964
2201
  };
1965
2202
  return {
2203
+ specificationVersion: "v3",
1966
2204
  responses: createResponsesAgent,
1967
2205
  chatCompletions: createFmapi,
1968
2206
  chatAgent: createChatAgent,
1969
2207
  imageModel: notImplemented("ImageModel"),
1970
2208
  textEmbeddingModel: notImplemented("TextEmbeddingModel"),
2209
+ embeddingModel: notImplemented("EmbeddingModel"),
1971
2210
  languageModel: notImplemented("LanguageModel")
1972
2211
  };
1973
2212
  };
1974
2213
 
1975
2214
  //#endregion
1976
- export { DATABRICKS_TOOL_CALL_ID, DATABRICKS_TOOL_DEFINITION, MCP_APPROVAL_REQUEST_TYPE, MCP_APPROVAL_RESPONSE_TYPE, MCP_APPROVAL_STATUS_KEY, createApprovalStatusOutput, createDatabricksProvider, extractApprovalStatus, extractApprovalStatusFromToolResult, extractDatabricksMetadata, getMcpApprovalState, isApprovalStatusOutput, isMcpApprovalRequest, isMcpApprovalResponse };
1977
- //# sourceMappingURL=index.js.map
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