ai 6.0.0-beta.48 → 6.0.0-beta.49

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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # ai
2
2
 
3
+ ## 6.0.0-beta.49
4
+
5
+ ### Patch Changes
6
+
7
+ - 703459a: feat: tool execution approval for dynamic tools
8
+ - Updated dependencies [703459a]
9
+ - @ai-sdk/provider-utils@4.0.0-beta.17
10
+ - @ai-sdk/gateway@2.0.0-beta.31
11
+
3
12
  ## 6.0.0-beta.48
4
13
 
5
14
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -291,7 +291,7 @@ onlyBar('bar');
291
291
  */
292
292
  type ValueOf<ObjectType, ValueType extends keyof ObjectType = keyof ObjectType> = ObjectType[ValueType];
293
293
 
294
- type ToolSet = Record<string, (Tool<never, never> | Tool<any, any> | Tool<any, never> | Tool<never, any>) & Pick<Tool<any, any>, 'execute' | 'onInputAvailable' | 'onInputStart' | 'onInputDelta'>>;
294
+ type ToolSet = Record<string, (Tool<never, never> | Tool<any, any> | Tool<any, never> | Tool<never, any>) & Pick<Tool<any, any>, 'execute' | 'onInputAvailable' | 'onInputStart' | 'onInputDelta' | 'needsApproval'>>;
295
295
 
296
296
  type BaseToolCall = {
297
297
  type: 'tool-call';
@@ -1673,12 +1673,36 @@ type DynamicToolUIPart = {
1673
1673
  input: unknown | undefined;
1674
1674
  output?: never;
1675
1675
  errorText?: never;
1676
+ approval?: never;
1676
1677
  } | {
1677
1678
  state: 'input-available';
1678
1679
  input: unknown;
1679
1680
  output?: never;
1680
1681
  errorText?: never;
1681
1682
  callProviderMetadata?: ProviderMetadata;
1683
+ approval?: never;
1684
+ } | {
1685
+ state: 'approval-requested';
1686
+ input: unknown;
1687
+ output?: never;
1688
+ errorText?: never;
1689
+ callProviderMetadata?: ProviderMetadata;
1690
+ approval: {
1691
+ id: string;
1692
+ approved?: never;
1693
+ reason?: never;
1694
+ };
1695
+ } | {
1696
+ state: 'approval-responded';
1697
+ input: unknown;
1698
+ output?: never;
1699
+ errorText?: never;
1700
+ callProviderMetadata?: ProviderMetadata;
1701
+ approval: {
1702
+ id: string;
1703
+ approved: boolean;
1704
+ reason?: string;
1705
+ };
1682
1706
  } | {
1683
1707
  state: 'output-available';
1684
1708
  input: unknown;
@@ -1686,12 +1710,33 @@ type DynamicToolUIPart = {
1686
1710
  errorText?: never;
1687
1711
  callProviderMetadata?: ProviderMetadata;
1688
1712
  preliminary?: boolean;
1713
+ approval?: {
1714
+ id: string;
1715
+ approved: true;
1716
+ reason?: string;
1717
+ };
1689
1718
  } | {
1690
1719
  state: 'output-error';
1691
1720
  input: unknown;
1692
1721
  output?: never;
1693
1722
  errorText: string;
1694
1723
  callProviderMetadata?: ProviderMetadata;
1724
+ approval?: {
1725
+ id: string;
1726
+ approved: true;
1727
+ reason?: string;
1728
+ };
1729
+ } | {
1730
+ state: 'output-denied';
1731
+ input: unknown;
1732
+ output?: never;
1733
+ errorText?: never;
1734
+ callProviderMetadata?: ProviderMetadata;
1735
+ approval: {
1736
+ id: string;
1737
+ approved: false;
1738
+ reason?: string;
1739
+ };
1695
1740
  });
1696
1741
  declare function isToolUIPart<TOOLS extends UITools>(part: UIMessagePart<UIDataTypes, TOOLS>): part is ToolUIPart<TOOLS>;
1697
1742
  declare function isToolOrDynamicToolUIPart<TOOLS extends UITools>(part: UIMessagePart<UIDataTypes, TOOLS>): part is ToolUIPart<TOOLS> | DynamicToolUIPart;
package/dist/index.d.ts CHANGED
@@ -291,7 +291,7 @@ onlyBar('bar');
291
291
  */
292
292
  type ValueOf<ObjectType, ValueType extends keyof ObjectType = keyof ObjectType> = ObjectType[ValueType];
293
293
 
294
- type ToolSet = Record<string, (Tool<never, never> | Tool<any, any> | Tool<any, never> | Tool<never, any>) & Pick<Tool<any, any>, 'execute' | 'onInputAvailable' | 'onInputStart' | 'onInputDelta'>>;
294
+ type ToolSet = Record<string, (Tool<never, never> | Tool<any, any> | Tool<any, never> | Tool<never, any>) & Pick<Tool<any, any>, 'execute' | 'onInputAvailable' | 'onInputStart' | 'onInputDelta' | 'needsApproval'>>;
295
295
 
296
296
  type BaseToolCall = {
297
297
  type: 'tool-call';
@@ -1673,12 +1673,36 @@ type DynamicToolUIPart = {
1673
1673
  input: unknown | undefined;
1674
1674
  output?: never;
1675
1675
  errorText?: never;
1676
+ approval?: never;
1676
1677
  } | {
1677
1678
  state: 'input-available';
1678
1679
  input: unknown;
1679
1680
  output?: never;
1680
1681
  errorText?: never;
1681
1682
  callProviderMetadata?: ProviderMetadata;
1683
+ approval?: never;
1684
+ } | {
1685
+ state: 'approval-requested';
1686
+ input: unknown;
1687
+ output?: never;
1688
+ errorText?: never;
1689
+ callProviderMetadata?: ProviderMetadata;
1690
+ approval: {
1691
+ id: string;
1692
+ approved?: never;
1693
+ reason?: never;
1694
+ };
1695
+ } | {
1696
+ state: 'approval-responded';
1697
+ input: unknown;
1698
+ output?: never;
1699
+ errorText?: never;
1700
+ callProviderMetadata?: ProviderMetadata;
1701
+ approval: {
1702
+ id: string;
1703
+ approved: boolean;
1704
+ reason?: string;
1705
+ };
1682
1706
  } | {
1683
1707
  state: 'output-available';
1684
1708
  input: unknown;
@@ -1686,12 +1710,33 @@ type DynamicToolUIPart = {
1686
1710
  errorText?: never;
1687
1711
  callProviderMetadata?: ProviderMetadata;
1688
1712
  preliminary?: boolean;
1713
+ approval?: {
1714
+ id: string;
1715
+ approved: true;
1716
+ reason?: string;
1717
+ };
1689
1718
  } | {
1690
1719
  state: 'output-error';
1691
1720
  input: unknown;
1692
1721
  output?: never;
1693
1722
  errorText: string;
1694
1723
  callProviderMetadata?: ProviderMetadata;
1724
+ approval?: {
1725
+ id: string;
1726
+ approved: true;
1727
+ reason?: string;
1728
+ };
1729
+ } | {
1730
+ state: 'output-denied';
1731
+ input: unknown;
1732
+ output?: never;
1733
+ errorText?: never;
1734
+ callProviderMetadata?: ProviderMetadata;
1735
+ approval: {
1736
+ id: string;
1737
+ approved: false;
1738
+ reason?: string;
1739
+ };
1695
1740
  });
1696
1741
  declare function isToolUIPart<TOOLS extends UITools>(part: UIMessagePart<UIDataTypes, TOOLS>): part is ToolUIPart<TOOLS>;
1697
1742
  declare function isToolOrDynamicToolUIPart<TOOLS extends UITools>(part: UIMessagePart<UIDataTypes, TOOLS>): part is ToolUIPart<TOOLS> | DynamicToolUIPart;
package/dist/index.js CHANGED
@@ -868,7 +868,7 @@ function detectMediaType({
868
868
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
869
869
 
870
870
  // src/version.ts
871
- var VERSION = true ? "6.0.0-beta.48" : "0.0.0-test";
871
+ var VERSION = true ? "6.0.0-beta.49" : "0.0.0-test";
872
872
 
873
873
  // src/util/download/download.ts
874
874
  var download = async ({ url }) => {
@@ -1486,6 +1486,10 @@ var outputSchema = import_v44.z.discriminatedUnion("type", [
1486
1486
  type: import_v44.z.literal("json"),
1487
1487
  value: jsonValueSchema
1488
1488
  }),
1489
+ import_v44.z.object({
1490
+ type: import_v44.z.literal("execution-denied"),
1491
+ reason: import_v44.z.string().optional()
1492
+ }),
1489
1493
  import_v44.z.object({
1490
1494
  type: import_v44.z.literal("error-text"),
1491
1495
  value: import_v44.z.string()
@@ -3846,27 +3850,15 @@ function processUIMessageStream({
3846
3850
  await runUpdateMessageJob(async ({ state, write }) => {
3847
3851
  var _a17, _b, _c, _d;
3848
3852
  function getToolInvocation(toolCallId) {
3849
- const toolInvocations = state.message.parts.filter(isToolUIPart);
3850
- const toolInvocation = toolInvocations.find(
3851
- (invocation) => invocation.toolCallId === toolCallId
3852
- );
3853
- if (toolInvocation == null) {
3854
- throw new Error(
3855
- "tool-output-error must be preceded by a tool-input-available"
3856
- );
3857
- }
3858
- return toolInvocation;
3859
- }
3860
- function getDynamicToolInvocation(toolCallId) {
3861
3853
  const toolInvocations = state.message.parts.filter(
3862
- (part) => part.type === "dynamic-tool"
3854
+ isToolOrDynamicToolUIPart
3863
3855
  );
3864
3856
  const toolInvocation = toolInvocations.find(
3865
3857
  (invocation) => invocation.toolCallId === toolCallId
3866
3858
  );
3867
3859
  if (toolInvocation == null) {
3868
3860
  throw new Error(
3869
- "tool-output-error must be preceded by a tool-input-available"
3861
+ `no tool invocation found for tool call ${toolCallId}`
3870
3862
  );
3871
3863
  }
3872
3864
  return toolInvocation;
@@ -4141,9 +4133,7 @@ function processUIMessageStream({
4141
4133
  case "tool-approval-request": {
4142
4134
  const toolInvocation = getToolInvocation(chunk.toolCallId);
4143
4135
  toolInvocation.state = "approval-requested";
4144
- toolInvocation.approval = {
4145
- id: chunk.approvalId
4146
- };
4136
+ toolInvocation.approval = { id: chunk.approvalId };
4147
4137
  write();
4148
4138
  break;
4149
4139
  }
@@ -4154,10 +4144,8 @@ function processUIMessageStream({
4154
4144
  break;
4155
4145
  }
4156
4146
  case "tool-output-available": {
4157
- if (chunk.dynamic) {
4158
- const toolInvocation = getDynamicToolInvocation(
4159
- chunk.toolCallId
4160
- );
4147
+ const toolInvocation = getToolInvocation(chunk.toolCallId);
4148
+ if (toolInvocation.type === "dynamic-tool") {
4161
4149
  updateDynamicToolPart({
4162
4150
  toolCallId: chunk.toolCallId,
4163
4151
  toolName: toolInvocation.toolName,
@@ -4167,7 +4155,6 @@ function processUIMessageStream({
4167
4155
  preliminary: chunk.preliminary
4168
4156
  });
4169
4157
  } else {
4170
- const toolInvocation = getToolInvocation(chunk.toolCallId);
4171
4158
  updateToolPart({
4172
4159
  toolCallId: chunk.toolCallId,
4173
4160
  toolName: getToolName(toolInvocation),
@@ -4182,10 +4169,8 @@ function processUIMessageStream({
4182
4169
  break;
4183
4170
  }
4184
4171
  case "tool-output-error": {
4185
- if (chunk.dynamic) {
4186
- const toolInvocation = getDynamicToolInvocation(
4187
- chunk.toolCallId
4188
- );
4172
+ const toolInvocation = getToolInvocation(chunk.toolCallId);
4173
+ if (toolInvocation.type === "dynamic-tool") {
4189
4174
  updateDynamicToolPart({
4190
4175
  toolCallId: chunk.toolCallId,
4191
4176
  toolName: toolInvocation.toolName,
@@ -4194,7 +4179,6 @@ function processUIMessageStream({
4194
4179
  errorText: chunk.errorText
4195
4180
  });
4196
4181
  } else {
4197
- const toolInvocation = getToolInvocation(chunk.toolCallId);
4198
4182
  updateToolPart({
4199
4183
  toolCallId: chunk.toolCallId,
4200
4184
  toolName: getToolName(toolInvocation),
@@ -6315,6 +6299,13 @@ function convertToModelMessages(messages, options) {
6315
6299
  ...part.callProviderMetadata != null ? { providerOptions: part.callProviderMetadata } : {}
6316
6300
  });
6317
6301
  }
6302
+ if (part.approval != null) {
6303
+ content.push({
6304
+ type: "tool-approval-request",
6305
+ approvalId: part.approval.id,
6306
+ toolCallId: part.toolCallId
6307
+ });
6308
+ }
6318
6309
  } else if (isToolUIPart(part)) {
6319
6310
  const toolName = getToolName(part);
6320
6311
  if (part.state !== "input-streaming") {
@@ -6365,7 +6356,7 @@ function convertToModelMessages(messages, options) {
6365
6356
  (toolPart) => {
6366
6357
  var _a18, _b2, _c;
6367
6358
  const outputs = [];
6368
- if (toolPart.type !== "dynamic-tool" && ((_a18 = toolPart.approval) == null ? void 0 : _a18.approved) != null) {
6359
+ if (((_a18 = toolPart.approval) == null ? void 0 : _a18.approved) != null) {
6369
6360
  outputs.push({
6370
6361
  type: "tool-approval-response",
6371
6362
  approvalId: toolPart.approval.id,
@@ -6378,7 +6369,7 @@ function convertToModelMessages(messages, options) {
6378
6369
  outputs.push({
6379
6370
  type: "tool-result",
6380
6371
  toolCallId: toolPart.toolCallId,
6381
- toolName: getToolName(toolPart),
6372
+ toolName: getToolOrDynamicToolName(toolPart),
6382
6373
  output: {
6383
6374
  type: "error-text",
6384
6375
  value: (_b2 = toolPart.approval.reason) != null ? _b2 : "Tool execution denied."
@@ -6388,7 +6379,7 @@ function convertToModelMessages(messages, options) {
6388
6379
  }
6389
6380
  case "output-error":
6390
6381
  case "output-available": {
6391
- const toolName = toolPart.type === "dynamic-tool" ? toolPart.toolName : getToolName(toolPart);
6382
+ const toolName = getToolOrDynamicToolName(toolPart);
6392
6383
  outputs.push({
6393
6384
  type: "tool-result",
6394
6385
  toolCallId: toolPart.toolCallId,
@@ -6412,7 +6403,7 @@ function convertToModelMessages(messages, options) {
6412
6403
  var processBlock = processBlock2;
6413
6404
  let block = [];
6414
6405
  for (const part of message.parts) {
6415
- if (part.type === "text" || part.type === "reasoning" || part.type === "file" || part.type === "dynamic-tool" || isToolUIPart(part)) {
6406
+ if (part.type === "text" || part.type === "reasoning" || part.type === "file" || isToolOrDynamicToolUIPart(part)) {
6416
6407
  block.push(part);
6417
6408
  } else if (part.type === "step-start") {
6418
6409
  processBlock2();
@@ -10284,7 +10275,7 @@ var AbstractChat = class {
10284
10275
  var _a17, _b;
10285
10276
  const messages = this.state.messages;
10286
10277
  const lastMessage = messages[messages.length - 1];
10287
- const updatePart = (part) => isToolUIPart(part) && part.state === "approval-requested" && part.approval.id === id ? {
10278
+ const updatePart = (part) => isToolOrDynamicToolUIPart(part) && part.state === "approval-requested" && part.approval.id === id ? {
10288
10279
  ...part,
10289
10280
  state: "approval-responded",
10290
10281
  approval: { id, approved, reason }
@@ -10652,7 +10643,8 @@ var uiMessagesSchema = (0, import_provider_utils35.lazySchema)(
10652
10643
  state: import_v410.z.literal("input-streaming"),
10653
10644
  input: import_v410.z.unknown().optional(),
10654
10645
  output: import_v410.z.never().optional(),
10655
- errorText: import_v410.z.never().optional()
10646
+ errorText: import_v410.z.never().optional(),
10647
+ approval: import_v410.z.never().optional()
10656
10648
  }),
10657
10649
  import_v410.z.object({
10658
10650
  type: import_v410.z.literal("dynamic-tool"),
@@ -10662,7 +10654,38 @@ var uiMessagesSchema = (0, import_provider_utils35.lazySchema)(
10662
10654
  input: import_v410.z.unknown(),
10663
10655
  output: import_v410.z.never().optional(),
10664
10656
  errorText: import_v410.z.never().optional(),
10665
- callProviderMetadata: providerMetadataSchema.optional()
10657
+ callProviderMetadata: providerMetadataSchema.optional(),
10658
+ approval: import_v410.z.never().optional()
10659
+ }),
10660
+ import_v410.z.object({
10661
+ type: import_v410.z.literal("dynamic-tool"),
10662
+ toolName: import_v410.z.string(),
10663
+ toolCallId: import_v410.z.string(),
10664
+ state: import_v410.z.literal("approval-requested"),
10665
+ input: import_v410.z.unknown(),
10666
+ output: import_v410.z.never().optional(),
10667
+ errorText: import_v410.z.never().optional(),
10668
+ callProviderMetadata: providerMetadataSchema.optional(),
10669
+ approval: import_v410.z.object({
10670
+ id: import_v410.z.string(),
10671
+ approved: import_v410.z.never().optional(),
10672
+ reason: import_v410.z.never().optional()
10673
+ })
10674
+ }),
10675
+ import_v410.z.object({
10676
+ type: import_v410.z.literal("dynamic-tool"),
10677
+ toolName: import_v410.z.string(),
10678
+ toolCallId: import_v410.z.string(),
10679
+ state: import_v410.z.literal("approval-responded"),
10680
+ input: import_v410.z.unknown(),
10681
+ output: import_v410.z.never().optional(),
10682
+ errorText: import_v410.z.never().optional(),
10683
+ callProviderMetadata: providerMetadataSchema.optional(),
10684
+ approval: import_v410.z.object({
10685
+ id: import_v410.z.string(),
10686
+ approved: import_v410.z.boolean(),
10687
+ reason: import_v410.z.string().optional()
10688
+ })
10666
10689
  }),
10667
10690
  import_v410.z.object({
10668
10691
  type: import_v410.z.literal("dynamic-tool"),
@@ -10673,7 +10696,12 @@ var uiMessagesSchema = (0, import_provider_utils35.lazySchema)(
10673
10696
  output: import_v410.z.unknown(),
10674
10697
  errorText: import_v410.z.never().optional(),
10675
10698
  callProviderMetadata: providerMetadataSchema.optional(),
10676
- preliminary: import_v410.z.boolean().optional()
10699
+ preliminary: import_v410.z.boolean().optional(),
10700
+ approval: import_v410.z.object({
10701
+ id: import_v410.z.string(),
10702
+ approved: import_v410.z.literal(true),
10703
+ reason: import_v410.z.string().optional()
10704
+ }).optional()
10677
10705
  }),
10678
10706
  import_v410.z.object({
10679
10707
  type: import_v410.z.literal("dynamic-tool"),
@@ -10683,7 +10711,27 @@ var uiMessagesSchema = (0, import_provider_utils35.lazySchema)(
10683
10711
  input: import_v410.z.unknown(),
10684
10712
  output: import_v410.z.never().optional(),
10685
10713
  errorText: import_v410.z.string(),
10686
- callProviderMetadata: providerMetadataSchema.optional()
10714
+ callProviderMetadata: providerMetadataSchema.optional(),
10715
+ approval: import_v410.z.object({
10716
+ id: import_v410.z.string(),
10717
+ approved: import_v410.z.literal(true),
10718
+ reason: import_v410.z.string().optional()
10719
+ }).optional()
10720
+ }),
10721
+ import_v410.z.object({
10722
+ type: import_v410.z.literal("dynamic-tool"),
10723
+ toolName: import_v410.z.string(),
10724
+ toolCallId: import_v410.z.string(),
10725
+ state: import_v410.z.literal("output-denied"),
10726
+ input: import_v410.z.unknown(),
10727
+ output: import_v410.z.never().optional(),
10728
+ errorText: import_v410.z.never().optional(),
10729
+ callProviderMetadata: providerMetadataSchema.optional(),
10730
+ approval: import_v410.z.object({
10731
+ id: import_v410.z.string(),
10732
+ approved: import_v410.z.literal(false),
10733
+ reason: import_v410.z.string().optional()
10734
+ })
10687
10735
  }),
10688
10736
  import_v410.z.object({
10689
10737
  type: import_v410.z.string().startsWith("tool-"),