ai-tool-set 0.1.0-alpha.0 → 0.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +216 -127
- package/dist/index.d.mts +93 -35
- package/dist/index.mjs +113 -61
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
|
-
This library provides
|
|
12
|
+
This library provides a type-safe API to manage [`activeTools`](https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-text#active-tools) for [`generateText()`](https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-text) and [`streamText()`](https://ai-sdk.dev/docs/reference/ai-sdk-core/stream-text) in the AI SDK.
|
|
13
13
|
|
|
14
14
|
### Why?
|
|
15
15
|
|
|
16
16
|
The AI SDK provides an `activeTools` parameter to control which tools the model can use at any given time. However, managing tool activation becomes complex when you need to:
|
|
17
17
|
|
|
18
|
-
- **
|
|
18
|
+
- **Statically activate/deactivate tools**: Some tools should be inactive by default and only available after being explicitly activated
|
|
19
19
|
- **Dynamically infer tool activation**: Some tools should be activated based on runtime context like the conversation history
|
|
20
20
|
|
|
21
|
-
This library wraps standard AI SDK `tool()` definitions with activation
|
|
21
|
+
This library wraps standard AI SDK `tool()` definitions with chainable activation methods and resolves `tools` and `activeTools` for any AI SDK function.
|
|
22
22
|
|
|
23
23
|
### Installation
|
|
24
24
|
|
|
@@ -30,53 +30,35 @@ npm install ai-tool-set
|
|
|
30
30
|
|
|
31
31
|
### Creating a Tool Set
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Pass a plain record of AI SDK `tool()` definitions to `createToolSet()`. All tools are active by default.
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
36
|
import { tool } from 'ai';
|
|
37
37
|
import { z } from 'zod';
|
|
38
38
|
import { createToolSet } from 'ai-tool-set';
|
|
39
39
|
|
|
40
|
-
const
|
|
41
|
-
// Plain tool — always active
|
|
40
|
+
const tools = {
|
|
42
41
|
search: tool({
|
|
43
42
|
description: 'Search for products',
|
|
44
43
|
inputSchema: z.object({ query: z.string() }),
|
|
45
44
|
execute: async ({ query }) => searchProducts(query),
|
|
46
45
|
}),
|
|
46
|
+
list_orders: tool({
|
|
47
|
+
description: 'List orders for a customer',
|
|
48
|
+
inputSchema: z.object({ customerId: z.string() }),
|
|
49
|
+
execute: async ({ customerId }) => listOrders(customerId),
|
|
50
|
+
}),
|
|
51
|
+
cancel_order: tool({
|
|
52
|
+
description: 'Cancel an order',
|
|
53
|
+
inputSchema: z.object({ orderId: z.string() }),
|
|
54
|
+
execute: async ({ orderId }) => cancelOrder(orderId),
|
|
55
|
+
}),
|
|
56
|
+
};
|
|
47
57
|
|
|
48
|
-
|
|
49
|
-
list_orders: {
|
|
50
|
-
tool: tool({
|
|
51
|
-
description: 'List orders for a customer',
|
|
52
|
-
inputSchema: z.object({ customerId: z.string() }),
|
|
53
|
-
execute: async ({ customerId }) => listOrders(customerId),
|
|
54
|
-
}),
|
|
55
|
-
active: false,
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
// Callback-based — activated dynamically based on messages
|
|
59
|
-
// Only available when list_orders was called and returned unfulfilled orders
|
|
60
|
-
cancel_order: {
|
|
61
|
-
tool: tool({
|
|
62
|
-
description: 'Cancel an order',
|
|
63
|
-
inputSchema: z.object({ orderId: z.string() }),
|
|
64
|
-
execute: async ({ orderId }) => cancelOrder(orderId),
|
|
65
|
-
}),
|
|
66
|
-
active: ({ messages }) =>
|
|
67
|
-
messages.some((m) =>
|
|
68
|
-
m.parts.some(
|
|
69
|
-
(p) =>
|
|
70
|
-
p.type === 'tool-list_orders' &&
|
|
71
|
-
p.state === 'output-available' &&
|
|
72
|
-
p.output.orders?.some((order) => order.status !== 'fulfilled'),
|
|
73
|
-
),
|
|
74
|
-
),
|
|
75
|
-
},
|
|
76
|
-
});
|
|
58
|
+
const toolSet = createToolSet({ tools });
|
|
77
59
|
```
|
|
78
60
|
|
|
79
|
-
### Use with `generateText` / `streamText`
|
|
61
|
+
### Use with `generateText` / `streamText`
|
|
80
62
|
|
|
81
63
|
The tool set exposes `tools` and `activeTools` as properties that can be used directly:
|
|
82
64
|
|
|
@@ -97,13 +79,10 @@ const result = await generateText({
|
|
|
97
79
|
|
|
98
80
|
### Activate and Deactivate Tools
|
|
99
81
|
|
|
100
|
-
Use
|
|
82
|
+
Use `.activate()` and `.deactivate()` to statically control which tools are available:
|
|
101
83
|
|
|
102
84
|
```typescript
|
|
103
|
-
|
|
104
|
-
const { tools, activeTools } = toolSet
|
|
105
|
-
.activateTools(['list_orders'])
|
|
106
|
-
.deactivateTools(['search']);
|
|
85
|
+
const { tools, activeTools } = toolSet.deactivate(['cancel_order']).activate(['list_orders']);
|
|
107
86
|
|
|
108
87
|
const result = await generateText({
|
|
109
88
|
model,
|
|
@@ -113,9 +92,24 @@ const result = await generateText({
|
|
|
113
92
|
});
|
|
114
93
|
```
|
|
115
94
|
|
|
116
|
-
###
|
|
95
|
+
### Conditional Activation
|
|
96
|
+
|
|
97
|
+
Use `.activateWhen()` and `.deactivateWhen()` to conditionally control tools based on messages and context. The predicate receives an `ActivationInput` with `messages` and `context`.
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const toolSet = createToolSet({ tools }).activateWhen('cancel_order', ({ messages }) =>
|
|
101
|
+
messages.some((m) =>
|
|
102
|
+
m.parts.some(
|
|
103
|
+
(p) =>
|
|
104
|
+
p.type === 'tool-list_orders' &&
|
|
105
|
+
p.state === 'output-available' &&
|
|
106
|
+
p.output.orders?.some((order) => order.status !== 'fulfilled'),
|
|
107
|
+
),
|
|
108
|
+
),
|
|
109
|
+
);
|
|
110
|
+
```
|
|
117
111
|
|
|
118
|
-
Use
|
|
112
|
+
Use `.inferTools()` to evaluate predicates with the current messages and context. It returns `{ tools, activeTools }` that can be spread directly into `generateText()`:
|
|
119
113
|
|
|
120
114
|
```typescript
|
|
121
115
|
const messages = [
|
|
@@ -133,8 +127,8 @@ const messages = [
|
|
|
133
127
|
input: { customerId: 'cust-123' },
|
|
134
128
|
output: {
|
|
135
129
|
orders: [
|
|
136
|
-
{ orderId: '
|
|
137
|
-
{ orderId: '
|
|
130
|
+
{ orderId: '1000', status: 'fulfilled' },
|
|
131
|
+
{ orderId: '1001', status: 'pending' },
|
|
138
132
|
],
|
|
139
133
|
},
|
|
140
134
|
},
|
|
@@ -142,87 +136,168 @@ const messages = [
|
|
|
142
136
|
},
|
|
143
137
|
];
|
|
144
138
|
|
|
145
|
-
//
|
|
146
|
-
const { tools, activeTools } = toolSet.inferTools({ messages });
|
|
139
|
+
// cancel_order is now active because list_orders returned unfulfilled orders
|
|
140
|
+
const { tools, activeTools } = toolSet.inferTools({ messages, context: {} });
|
|
147
141
|
|
|
148
|
-
const result = await generateText({
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
142
|
+
const result = await generateText({ model, tools, activeTools, messages });
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
You can also activate multiple tools at once:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const toolSet = createToolSet({ tools }).activateWhen({
|
|
149
|
+
list_orders: ({ context }) => context.isAuthenticated,
|
|
150
|
+
cancel_order: ({ messages }) => hasUnfulfilledOrders(messages),
|
|
153
151
|
});
|
|
154
152
|
```
|
|
155
153
|
|
|
156
|
-
###
|
|
154
|
+
### Last-Call Wins
|
|
157
155
|
|
|
158
|
-
|
|
156
|
+
Each method appends to an internal list. For each tool, the **last entry** determines its state. This makes ordering explicit and predictable:
|
|
159
157
|
|
|
160
158
|
```typescript
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
159
|
+
const toolSet = createToolSet({ tools })
|
|
160
|
+
.activate(['cancel_order']) // cancel_order: activated
|
|
161
|
+
.deactivate(['cancel_order']) // cancel_order: deactivated
|
|
162
|
+
.activateWhen(
|
|
163
|
+
'cancel_order',
|
|
164
|
+
(
|
|
165
|
+
{ messages }, // cancel_order: conditional activation
|
|
166
|
+
) => hasUnfulfilledOrders(messages),
|
|
167
|
+
);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Immutable vs Mutable
|
|
171
|
+
|
|
172
|
+
By default, `createToolSet()` returns an **immutable** tool set, that means every method returns a new instance and the original is never modified. This is ideal when the tool set is created once in the global scope and shared across requests:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
// Global scope: created once, shared across requests
|
|
176
|
+
const toolSet = createToolSet({ tools }).deactivate(['list_order', 'cancel_order']);
|
|
177
|
+
|
|
178
|
+
export async function POST(req: Request) {
|
|
179
|
+
const { messages } = await req.json();
|
|
180
|
+
|
|
181
|
+
// Activate list_orders only for this request
|
|
182
|
+
// myToolSet !== toolSet, original toolSet is unchanged for next request
|
|
183
|
+
const myToolSet = toolSet.activate(['list_orders']);
|
|
184
|
+
|
|
185
|
+
const { tools, activeTools } = myToolSet;
|
|
186
|
+
|
|
187
|
+
const result = await generateText({
|
|
188
|
+
model,
|
|
189
|
+
tools,
|
|
190
|
+
activeTools,
|
|
191
|
+
messages,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
```
|
|
164
195
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
196
|
+
Pass `mutable: true` to get a **mutable** tool set where each method mutates in-place and returns `this` for chaining. This is useful when the tool set is created per-request in a local scope:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
export async function POST(req: Request) {
|
|
200
|
+
const { messages } = await req.json();
|
|
201
|
+
|
|
202
|
+
// Local scope: created and mutated per request
|
|
203
|
+
const toolSet = createToolSet({ tools, mutable: true }).deactivate(['list_order', 'cancel_order']);
|
|
204
|
+
|
|
205
|
+
// Activate list_orders only for this request
|
|
206
|
+
// myToolSet === toolSet, original toolSet is mutated for this request
|
|
207
|
+
const myToolSet = toolSet.activate(['list_orders']);
|
|
208
|
+
|
|
209
|
+
const { tools, activeTools } = myToolSet;
|
|
210
|
+
|
|
211
|
+
const result = await generateText({
|
|
212
|
+
model,
|
|
213
|
+
tools,
|
|
214
|
+
activeTools,
|
|
215
|
+
messages,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
168
218
|
```
|
|
169
219
|
|
|
170
|
-
### Typed UI
|
|
220
|
+
### Typed UI Tool Set
|
|
171
221
|
|
|
172
222
|
Use `InferUIToolSet` to get fully typed UI messages from your tool set:
|
|
173
223
|
|
|
174
224
|
```typescript
|
|
175
225
|
import type { UIMessage } from 'ai';
|
|
176
|
-
import type { InferUIToolSet
|
|
226
|
+
import type { InferUIToolSet } from 'ai-tool-set';
|
|
177
227
|
|
|
178
|
-
const tools = {
|
|
179
|
-
|
|
180
|
-
list_orders: {
|
|
181
|
-
tool: tool({ ... }),
|
|
182
|
-
active: false,
|
|
183
|
-
},
|
|
184
|
-
cancel_order: {
|
|
185
|
-
tool: tool({ ... }),
|
|
186
|
-
active: ({ messages }) => /* callback logic */,
|
|
187
|
-
},
|
|
188
|
-
} satisfies ToolSetConfig;
|
|
228
|
+
const tools = { search, list_orders, cancel_order };
|
|
229
|
+
const toolSet = createToolSet({ tools });
|
|
189
230
|
|
|
190
|
-
|
|
231
|
+
// From the tools record
|
|
232
|
+
type MyToolSet = InferUIToolSet<typeof tools>;
|
|
191
233
|
|
|
192
|
-
//
|
|
193
|
-
type
|
|
234
|
+
// Or from the ToolSet instance
|
|
235
|
+
type MyToolSet = InferUIToolSet<typeof toolSet>;
|
|
194
236
|
|
|
195
|
-
//
|
|
196
|
-
type MyUIMessage = UIMessage<unknown, any,
|
|
237
|
+
// Use MyToolSet in your UIMessage type for type-safe access to tool invocation parts:
|
|
238
|
+
type MyUIMessage = UIMessage<unknown, any, MyToolSet>;
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Custom UIMessage
|
|
242
|
+
|
|
243
|
+
If you already have a custom `UIMessage` type, you can pass it as `MESSAGE` generic to `createToolSet()` and it will be used in predicates and `inferTools`:
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { myTools } from './my-tools.js';
|
|
247
|
+
import { MyUIMessage } from './my-ui-message.js';
|
|
248
|
+
|
|
249
|
+
const toolSet = createToolSet<typeof myTools, MyUIMessage>({ tools: myTools }).activateWhen(
|
|
250
|
+
'cancel_order',
|
|
251
|
+
({ messages }) => hasUnfulfilledOrders(messages),
|
|
252
|
+
);
|
|
253
|
+
// ~~~~~~~~
|
|
254
|
+
// Messages are now typed as MyUIMessage, so you get type safety and autocompletion in predicates!
|
|
255
|
+
|
|
256
|
+
const { tools, activeTools } = toolSet.inferTools({ messages, context: {} });
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Custom Context
|
|
260
|
+
|
|
261
|
+
Pass a `CONTEXT` generic to `createToolSet()` to type the `context` field in predicates and `inferTools`:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { myTools } from './my-tools.js';
|
|
265
|
+
import { MyUIMessage } from './my-ui-message.js';
|
|
266
|
+
|
|
267
|
+
type MyContext = { userId: string; isAdmin: boolean };
|
|
268
|
+
|
|
269
|
+
const toolSet = createToolSet<typeof myTools, MyUIMessage, MyContext>({ tools: myTools }).activateWhen(
|
|
270
|
+
'cancel_order',
|
|
271
|
+
({ context }) => context.isAdmin,
|
|
272
|
+
);
|
|
273
|
+
// ~~~~~~~~
|
|
274
|
+
// Context is now typed as MyContext, so you get type safety and autocompletion
|
|
275
|
+
|
|
276
|
+
const { tools, activeTools } = toolSet.inferTools({
|
|
277
|
+
messages,
|
|
278
|
+
context: { isAdmin: true },
|
|
279
|
+
});
|
|
197
280
|
```
|
|
198
281
|
|
|
199
282
|
## API
|
|
200
283
|
|
|
201
|
-
## `createToolSet(
|
|
284
|
+
## `createToolSet(options)`
|
|
202
285
|
|
|
203
|
-
- `
|
|
204
|
-
|
|
205
|
-
- a `{ tool, active }` object with activation control (`active` can be `boolean` or `(context) => boolean`)
|
|
286
|
+
- `options.tools`, a plain `Record<string, Tool>` of AI SDK tools
|
|
287
|
+
- `options.mutable` (optional), set to `true` for a mutable tool set (default: `false`)
|
|
206
288
|
|
|
207
|
-
Returns a `ToolSet` instance.
|
|
289
|
+
Returns a `ToolSet` instance. All tools are active by default.
|
|
208
290
|
|
|
209
291
|
```ts
|
|
210
|
-
const toolSet = createToolSet({
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
active: false,
|
|
215
|
-
},
|
|
216
|
-
cancel_order: {
|
|
217
|
-
tool: tool({ ... }),
|
|
218
|
-
active: ({ messages }) => /* callback logic */,
|
|
219
|
-
},
|
|
220
|
-
});
|
|
292
|
+
const toolSet = createToolSet({ tools: { search, list_orders, cancel_order } });
|
|
293
|
+
|
|
294
|
+
// Mutable mode — methods mutate in-place and return `this`
|
|
295
|
+
const toolSet = createToolSet({ tools: { search, list_orders, cancel_order }, mutable: true });
|
|
221
296
|
```
|
|
222
297
|
|
|
223
298
|
#### `.tools`
|
|
224
299
|
|
|
225
|
-
All tools as a standard AI SDK tool record
|
|
300
|
+
All tools as a standard AI SDK tool record, regardless of activation state.
|
|
226
301
|
|
|
227
302
|
```ts
|
|
228
303
|
const { tools } = toolSet;
|
|
@@ -230,81 +305,95 @@ const { tools } = toolSet;
|
|
|
230
305
|
|
|
231
306
|
#### `.activeTools`
|
|
232
307
|
|
|
233
|
-
Resolved array of active tool names based on the current state.
|
|
308
|
+
Resolved array of active tool names based on the current state.
|
|
234
309
|
|
|
235
310
|
```ts
|
|
236
311
|
const { activeTools } = toolSet;
|
|
237
312
|
```
|
|
238
313
|
|
|
239
|
-
#### `.
|
|
314
|
+
#### `.activate(names)`
|
|
240
315
|
|
|
241
|
-
|
|
316
|
+
Statically activate tools by name. Returns a new instance (immutable) or `this` (mutable).
|
|
242
317
|
|
|
243
318
|
```ts
|
|
244
|
-
|
|
319
|
+
toolSet.activate(['cancel_order']);
|
|
245
320
|
```
|
|
246
321
|
|
|
247
|
-
#### `.
|
|
322
|
+
#### `.deactivate(names)`
|
|
248
323
|
|
|
249
|
-
|
|
324
|
+
Statically deactivate tools by name. Returns a new instance (immutable) or `this` (mutable).
|
|
250
325
|
|
|
251
326
|
```ts
|
|
252
|
-
|
|
327
|
+
toolSet.deactivate(['search']);
|
|
253
328
|
```
|
|
254
329
|
|
|
255
|
-
#### `.
|
|
330
|
+
#### `.activateWhen(name, predicate)` / `.activateWhen(predicates)`
|
|
331
|
+
|
|
332
|
+
Conditionally activate tools. The predicate receives `{ messages, context }` and returns `true` to activate.
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
toolSet.activateWhen('cancel_order', ({ messages }) => hasOrders(messages));
|
|
336
|
+
|
|
337
|
+
toolSet.activateWhen({
|
|
338
|
+
cancel_order: ({ messages }) => hasOrders(messages),
|
|
339
|
+
list_orders: ({ context }) => context.isAuthenticated,
|
|
340
|
+
});
|
|
341
|
+
```
|
|
256
342
|
|
|
257
|
-
|
|
343
|
+
#### `.deactivateWhen(name, predicate)` / `.deactivateWhen(predicates)`
|
|
258
344
|
|
|
259
|
-
|
|
260
|
-
- `messages`, `Array<UIMessage>`, the current conversation messages used by activation callbacks to determine tool availability
|
|
345
|
+
Conditionally deactivate tools. The predicate receives `{ messages, context }` and returns `true` to deactivate.
|
|
261
346
|
|
|
262
347
|
```ts
|
|
263
|
-
|
|
348
|
+
toolSet.deactivateWhen('search', ({ messages }) => messages.length > 10);
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### `.inferTools(input)`
|
|
352
|
+
|
|
353
|
+
Evaluate all predicates with the provided messages and context. Returns `{ tools, activeTools }` — directly spreadable into `generateText()` or `streamText()`. This is a terminal operation: messages and context are consumed but not stored.
|
|
354
|
+
|
|
355
|
+
- `input`:
|
|
356
|
+
- `messages`, the current conversation messages
|
|
357
|
+
- `context`, arbitrary values passed to predicates
|
|
358
|
+
|
|
359
|
+
```ts
|
|
360
|
+
const { tools, activeTools } = toolSet.inferTools({ messages, context: {} });
|
|
361
|
+
|
|
362
|
+
const result = await generateText({ model, tools, activeTools, messages });
|
|
264
363
|
```
|
|
265
364
|
|
|
266
365
|
## Types
|
|
267
366
|
|
|
268
|
-
### `
|
|
367
|
+
### `ActivationInput`
|
|
269
368
|
|
|
270
|
-
|
|
369
|
+
Input passed to activation predicates. Generic over `MESSAGE` and `CONTEXT`:
|
|
271
370
|
|
|
272
371
|
```ts
|
|
273
|
-
import {
|
|
372
|
+
import type { ActivationInput } from 'ai-tool-set';
|
|
274
373
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
list_orders: { tool: tool({ ... }), active: false },
|
|
278
|
-
cancel_order: { tool: tool({ ... }), active: ({ messages }) => /* ... */ },
|
|
279
|
-
} satisfies ToolSetConfig;
|
|
374
|
+
type MyInput = ActivationInput<MyUIMessage, { isAdmin: boolean }>;
|
|
375
|
+
// { messages: Array<MyUIMessage>; context: { isAdmin: boolean } }
|
|
280
376
|
```
|
|
281
377
|
|
|
282
378
|
### `InferToolSet`
|
|
283
379
|
|
|
284
|
-
Extract
|
|
380
|
+
Extract the raw tool record from a tool record or `ToolSet` instance:
|
|
285
381
|
|
|
286
382
|
```ts
|
|
287
|
-
import {
|
|
383
|
+
import type { InferToolSet } from 'ai-tool-set';
|
|
288
384
|
|
|
289
|
-
type Tools = InferToolSet<typeof tools>;
|
|
290
|
-
// { search: Tool<...>, list_orders: Tool<...>, cancel_order: Tool<...> }
|
|
291
|
-
|
|
292
|
-
// Also works with a ToolSet instance
|
|
293
|
-
const toolSet = createToolSet(tools);
|
|
294
385
|
type Tools = InferToolSet<typeof toolSet>;
|
|
386
|
+
// { search: Tool<...>, list_orders: Tool<...>, cancel_order: Tool<...> }
|
|
295
387
|
```
|
|
296
388
|
|
|
297
389
|
### `InferUIToolSet`
|
|
298
390
|
|
|
299
|
-
Derive typed UI tool parts from a
|
|
391
|
+
Derive typed UI tool parts from a tool record or `ToolSet` instance. Use with `UIMessage` for type-safe access to tool invocation parts:
|
|
300
392
|
|
|
301
393
|
```ts
|
|
302
394
|
import type { UIMessage } from 'ai';
|
|
303
|
-
import {
|
|
304
|
-
|
|
305
|
-
type MyUIMessage = UIMessage<unknown, any, InferUIToolSet<typeof tools>>;
|
|
395
|
+
import type { InferUIToolSet } from 'ai-tool-set';
|
|
306
396
|
|
|
307
|
-
// Also works with a ToolSet instance
|
|
308
397
|
type MyUIMessage = UIMessage<unknown, any, InferUIToolSet<typeof toolSet>>;
|
|
309
398
|
|
|
310
399
|
// Parts are now typed per tool:
|
package/dist/index.d.mts
CHANGED
|
@@ -8,9 +8,19 @@ type MessageType = UIMessage | ModelMessage;
|
|
|
8
8
|
/** The fully-typed UIMessage for a given tool record. */
|
|
9
9
|
type InferUIMessage<TOOLS extends ToolRecord> = UIMessage<unknown, any, InferUIToolSet<TOOLS>>;
|
|
10
10
|
/** Infer the raw tool record from a ToolRecord or ToolSet instance. */
|
|
11
|
-
type InferToolSet<T extends ToolRecord |
|
|
11
|
+
type InferToolSet<T extends ToolRecord | AnyToolSet> = T extends ImmutableToolSet<infer TOOLS, any, any> ? TOOLS : T extends MutableToolSet<infer TOOLS, any, any> ? TOOLS : T;
|
|
12
12
|
/** Infer the UI tool types from a tool record or ToolSet instance. */
|
|
13
|
-
type InferUIToolSet<T extends ToolRecord |
|
|
13
|
+
type InferUIToolSet<T extends ToolRecord | AnyToolSet> = { [K in keyof InferToolSet<T> & string]: InferUITool<InferToolSet<T>[K]> };
|
|
14
|
+
/**
|
|
15
|
+
* Extract tool names tracked as active from an ImmutableToolSet instance.
|
|
16
|
+
* Returns `never` for MutableToolSet (cannot be determined at compile time).
|
|
17
|
+
*/
|
|
18
|
+
type ActiveTools<T extends AnyToolSet> = T extends ImmutableToolSet<any, any, any, infer A, any> ? A : never;
|
|
19
|
+
/**
|
|
20
|
+
* Extract tool names tracked as inactive from an ImmutableToolSet instance.
|
|
21
|
+
* Returns `never` for MutableToolSet (cannot be determined at compile time).
|
|
22
|
+
*/
|
|
23
|
+
type InactiveTools<T extends AnyToolSet> = T extends ImmutableToolSet<any, any, any, any, infer D> ? D : never;
|
|
14
24
|
/**
|
|
15
25
|
* Input passed to activation predicates.
|
|
16
26
|
* Use `ActivationInput<MyMsg>` to get per-tool narrowing in callbacks.
|
|
@@ -25,28 +35,42 @@ type ActivationEntry = {
|
|
|
25
35
|
toolName: string;
|
|
26
36
|
resolve: (input: ActivationInput<any, any>) => boolean;
|
|
27
37
|
};
|
|
28
|
-
|
|
38
|
+
/** Resolved tools and active tool names returned by `inferTools()`. */
|
|
39
|
+
type ResolvedToolSet<TOOLS extends ToolRecord> = {
|
|
29
40
|
tools: TOOLS;
|
|
30
|
-
|
|
31
|
-
input: ActivationInput<MESSAGE, CONTEXT>;
|
|
41
|
+
activeTools: Array<keyof TOOLS & string>;
|
|
32
42
|
};
|
|
43
|
+
/** Union of both toolset classes for type utility constraints. */
|
|
44
|
+
type AnyToolSet = ImmutableToolSet<any> | MutableToolSet<any>;
|
|
45
|
+
/**
|
|
46
|
+
* Immutable state container for tool activation.
|
|
47
|
+
*
|
|
48
|
+
* All mutation methods return a new ToolSetState instance.
|
|
49
|
+
* Resolution follows "last-call wins": each method appends entries,
|
|
50
|
+
* and the last entry for each tool determines its state.
|
|
51
|
+
*/
|
|
52
|
+
declare class ToolSetState<TOOLS extends ToolRecord, MESSAGE extends MessageType = UIMessage, CONTEXT extends Record<string, unknown> = Record<string, unknown>> {
|
|
53
|
+
#private;
|
|
54
|
+
constructor(tools: TOOLS, entries: Array<ActivationEntry>);
|
|
55
|
+
/** All tools as a standard AI SDK tool record. */
|
|
56
|
+
get tools(): TOOLS;
|
|
57
|
+
/** Resolved list of active tool names based on current entries (no predicates, default input). */
|
|
58
|
+
get activeTools(): Array<keyof TOOLS & string>;
|
|
59
|
+
activate(names: Array<string>): ToolSetState<TOOLS, MESSAGE, CONTEXT>;
|
|
60
|
+
deactivate(names: Array<string>): ToolSetState<TOOLS, MESSAGE, CONTEXT>;
|
|
61
|
+
activateWhen(nameOrPredicates: string | Partial<Record<string, ActivationPredicate<MESSAGE, CONTEXT>>>, predicate?: ActivationPredicate<MESSAGE, CONTEXT>): ToolSetState<TOOLS, MESSAGE, CONTEXT>;
|
|
62
|
+
deactivateWhen(nameOrPredicates: string | Partial<Record<string, ActivationPredicate<MESSAGE, CONTEXT>>>, predicate?: ActivationPredicate<MESSAGE, CONTEXT>): ToolSetState<TOOLS, MESSAGE, CONTEXT>;
|
|
63
|
+
/** Evaluate all predicates with the provided input and return resolved tools + activeTools. */
|
|
64
|
+
inferTools(input: ActivationInput<MESSAGE, CONTEXT>): ResolvedToolSet<TOOLS>;
|
|
65
|
+
}
|
|
33
66
|
/**
|
|
34
67
|
* An immutable tool set with chainable activation methods.
|
|
35
68
|
*
|
|
36
69
|
* Resolution follows "last-call wins": each method appends an entry,
|
|
37
70
|
* and the last entry for each tool determines its state.
|
|
38
71
|
* Default (no entry) is active.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```typescript
|
|
42
|
-
* const toolSet = createToolSet({ search, list_orders, cancel_order })
|
|
43
|
-
* .deactivate(['cancel_order'])
|
|
44
|
-
* .activateWhen('cancel_order', ({ messages }) => hasUnfulfilledOrders(messages));
|
|
45
|
-
*
|
|
46
|
-
* const { tools, activeTools } = toolSet.inferTools({ messages, context: {} });
|
|
47
|
-
* ```
|
|
48
72
|
*/
|
|
49
|
-
declare class
|
|
73
|
+
declare class ImmutableToolSet<TOOLS extends ToolRecord, MESSAGE extends MessageType = UIMessage, CONTEXT extends Record<string, unknown> = Record<string, unknown>, ACTIVATED extends string = never, DEACTIVATED extends string = never> {
|
|
50
74
|
#private;
|
|
51
75
|
/** All tools as a standard AI SDK tool record. */
|
|
52
76
|
readonly tools: TOOLS;
|
|
@@ -54,36 +78,70 @@ declare class ToolSet<TOOLS extends ToolRecord, MESSAGE extends MessageType = UI
|
|
|
54
78
|
readonly activeTools: Array<keyof TOOLS & string>;
|
|
55
79
|
constructor(state: ToolSetState<TOOLS, MESSAGE, CONTEXT>);
|
|
56
80
|
/** Statically activate tools by name. */
|
|
57
|
-
activate<NAMES extends
|
|
81
|
+
activate<NAMES extends keyof TOOLS & string>(names: Array<NAMES>): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, ACTIVATED | NAMES, Exclude<DEACTIVATED, NAMES>>;
|
|
82
|
+
/** Statically deactivate tools by name. */
|
|
83
|
+
deactivate<NAMES extends keyof TOOLS & string>(names: Array<NAMES>): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, Exclude<ACTIVATED, NAMES>, DEACTIVATED | NAMES>;
|
|
84
|
+
/**
|
|
85
|
+
* Conditionally activate a tool — inactive by default, becomes active when predicate returns true.
|
|
86
|
+
* Tracks names in DEACTIVATED since the tool starts inactive.
|
|
87
|
+
*/
|
|
88
|
+
activateWhen<NAME extends keyof TOOLS & string>(name: NAME, predicate: ActivationPredicate<MESSAGE, CONTEXT>): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, Exclude<ACTIVATED, NAME>, DEACTIVATED | NAME>;
|
|
89
|
+
activateWhen<NAMES extends keyof TOOLS & string>(predicates: Partial<Record<NAMES, ActivationPredicate<MESSAGE, CONTEXT>>>): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, Exclude<ACTIVATED, NAMES>, DEACTIVATED | NAMES>;
|
|
90
|
+
/**
|
|
91
|
+
* Conditionally deactivate a tool — active by default, becomes inactive when predicate returns true.
|
|
92
|
+
* Tracks names in ACTIVATED since the tool starts active.
|
|
93
|
+
*/
|
|
94
|
+
deactivateWhen<NAME extends keyof TOOLS & string>(name: NAME, predicate: ActivationPredicate<MESSAGE, CONTEXT>): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, ACTIVATED | NAME, Exclude<DEACTIVATED, NAME>>;
|
|
95
|
+
deactivateWhen<NAMES extends keyof TOOLS & string>(predicates: Partial<Record<NAMES, ActivationPredicate<MESSAGE, CONTEXT>>>): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, ACTIVATED | NAMES, Exclude<DEACTIVATED, NAMES>>;
|
|
96
|
+
/** Evaluate all predicates with the provided input. Returns resolved `{ tools, activeTools }`. */
|
|
97
|
+
inferTools(input: ActivationInput<MESSAGE, CONTEXT>): ResolvedToolSet<TOOLS>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A mutable tool set with chainable activation methods.
|
|
101
|
+
*
|
|
102
|
+
* Same resolution semantics as ImmutableToolSet, but methods mutate
|
|
103
|
+
* in-place and return `this` instead of creating new instances.
|
|
104
|
+
*/
|
|
105
|
+
declare class MutableToolSet<TOOLS extends ToolRecord, MESSAGE extends MessageType = UIMessage, CONTEXT extends Record<string, unknown> = Record<string, unknown>> {
|
|
106
|
+
#private;
|
|
107
|
+
/** All tools as a standard AI SDK tool record. */
|
|
108
|
+
readonly tools: TOOLS;
|
|
109
|
+
/** Resolved list of active tool names based on current state. */
|
|
110
|
+
activeTools: Array<keyof TOOLS & string>;
|
|
111
|
+
constructor(state: ToolSetState<TOOLS, MESSAGE, CONTEXT>);
|
|
112
|
+
/** Statically activate tools by name. */
|
|
113
|
+
activate(names: Array<keyof TOOLS & string>): this;
|
|
58
114
|
/** Statically deactivate tools by name. */
|
|
59
|
-
deactivate<
|
|
115
|
+
deactivate(names: Array<keyof TOOLS & string>): this;
|
|
60
116
|
/**
|
|
61
|
-
* Conditionally activate a tool — becomes active when predicate returns true.
|
|
62
|
-
*
|
|
63
|
-
* - `.activateWhen('tool_name', (input) => ...)`
|
|
64
|
-
* - `.activateWhen({ tool_name: (input) => ... })`
|
|
117
|
+
* Conditionally activate a tool — inactive by default, becomes active when predicate returns true.
|
|
65
118
|
*/
|
|
66
|
-
activateWhen
|
|
67
|
-
activateWhen(predicates: Partial<Record<keyof TOOLS & string, ActivationPredicate<MESSAGE, CONTEXT>>>):
|
|
119
|
+
activateWhen(name: keyof TOOLS & string, predicate: ActivationPredicate<MESSAGE, CONTEXT>): this;
|
|
120
|
+
activateWhen(predicates: Partial<Record<keyof TOOLS & string, ActivationPredicate<MESSAGE, CONTEXT>>>): this;
|
|
68
121
|
/**
|
|
69
|
-
* Conditionally deactivate a tool — becomes inactive when predicate returns true.
|
|
70
|
-
* Internally wraps with negation so resolve returns true (active) when pred is false.
|
|
71
|
-
*
|
|
72
|
-
* - `.deactivateWhen('tool_name', (input) => ...)`
|
|
73
|
-
* - `.deactivateWhen({ tool_name: (input) => ... })`
|
|
122
|
+
* Conditionally deactivate a tool — active by default, becomes inactive when predicate returns true.
|
|
74
123
|
*/
|
|
75
|
-
deactivateWhen
|
|
76
|
-
deactivateWhen(predicates: Partial<Record<keyof TOOLS & string, ActivationPredicate<MESSAGE, CONTEXT>>>):
|
|
77
|
-
/**
|
|
78
|
-
inferTools(input: ActivationInput<MESSAGE, CONTEXT>):
|
|
124
|
+
deactivateWhen(name: keyof TOOLS & string, predicate: ActivationPredicate<MESSAGE, CONTEXT>): this;
|
|
125
|
+
deactivateWhen(predicates: Partial<Record<keyof TOOLS & string, ActivationPredicate<MESSAGE, CONTEXT>>>): this;
|
|
126
|
+
/** Evaluate all predicates with the provided input. Returns resolved `{ tools, activeTools }`. */
|
|
127
|
+
inferTools(input: ActivationInput<MESSAGE, CONTEXT>): ResolvedToolSet<TOOLS>;
|
|
79
128
|
}
|
|
129
|
+
type CreateToolSetOptions<TOOLS extends ToolRecord> = {
|
|
130
|
+
tools: TOOLS;
|
|
131
|
+
mutable?: boolean;
|
|
132
|
+
};
|
|
80
133
|
/**
|
|
81
|
-
* Create a chainable
|
|
134
|
+
* Create a chainable tool set.
|
|
82
135
|
*
|
|
83
136
|
* @typeParam TOOLS — inferred from the argument
|
|
84
137
|
* @typeParam MESSAGE — defaults to the fully-typed UIMessage derived from TOOLS
|
|
85
138
|
* @typeParam CONTEXT — defaults to Record<string, unknown>
|
|
86
139
|
*/
|
|
87
|
-
declare
|
|
140
|
+
declare function createToolSet<const TOOLS extends ToolRecord, MESSAGE extends MessageType = InferUIMessage<TOOLS>, CONTEXT extends Record<string, unknown> = Record<string, unknown>>(options: CreateToolSetOptions<TOOLS> & {
|
|
141
|
+
mutable: true;
|
|
142
|
+
}): MutableToolSet<TOOLS, MESSAGE, CONTEXT>;
|
|
143
|
+
declare function createToolSet<const TOOLS extends ToolRecord, MESSAGE extends MessageType = InferUIMessage<TOOLS>, CONTEXT extends Record<string, unknown> = Record<string, unknown>>(options: CreateToolSetOptions<TOOLS> & {
|
|
144
|
+
mutable?: false;
|
|
145
|
+
}): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, keyof TOOLS & string>;
|
|
88
146
|
//#endregion
|
|
89
|
-
export { type ActivationInput, type InferToolSet, type InferUIToolSet, createToolSet };
|
|
147
|
+
export { type ActivationInput, type ActiveTools, type InactiveTools, type InferToolSet, type InferUIToolSet, createToolSet };
|
package/dist/index.mjs
CHANGED
|
@@ -10,99 +10,151 @@ const toEntries = (nameOrPredicates, predicate) => {
|
|
|
10
10
|
}));
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Immutable state container for tool activation.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* All mutation methods return a new ToolSetState instance.
|
|
16
|
+
* Resolution follows "last-call wins": each method appends entries,
|
|
16
17
|
* and the last entry for each tool determines its state.
|
|
17
|
-
* Default (no entry) is active.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* const toolSet = createToolSet({ search, list_orders, cancel_order })
|
|
22
|
-
* .deactivate(['cancel_order'])
|
|
23
|
-
* .activateWhen('cancel_order', ({ messages }) => hasUnfulfilledOrders(messages));
|
|
24
|
-
*
|
|
25
|
-
* const { tools, activeTools } = toolSet.inferTools({ messages, context: {} });
|
|
26
|
-
* ```
|
|
27
18
|
*/
|
|
28
|
-
var
|
|
29
|
-
#
|
|
19
|
+
var ToolSetState = class ToolSetState {
|
|
20
|
+
#tools;
|
|
21
|
+
#entries;
|
|
22
|
+
constructor(tools, entries) {
|
|
23
|
+
this.#tools = tools;
|
|
24
|
+
this.#entries = entries;
|
|
25
|
+
}
|
|
30
26
|
/** All tools as a standard AI SDK tool record. */
|
|
31
|
-
tools
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return lastEntry.resolve(state.input);
|
|
41
|
-
});
|
|
27
|
+
get tools() {
|
|
28
|
+
return this.#tools;
|
|
29
|
+
}
|
|
30
|
+
/** Resolved list of active tool names based on current entries (no predicates, default input). */
|
|
31
|
+
get activeTools() {
|
|
32
|
+
return this.inferTools({
|
|
33
|
+
messages: [],
|
|
34
|
+
context: {}
|
|
35
|
+
}).activeTools;
|
|
42
36
|
}
|
|
43
|
-
/** Statically activate tools by name. */
|
|
44
37
|
activate(names) {
|
|
45
38
|
const newEntries = names.map((name) => ({
|
|
46
39
|
toolName: name,
|
|
47
40
|
resolve: () => true
|
|
48
41
|
}));
|
|
49
|
-
return new
|
|
50
|
-
...this.#state,
|
|
51
|
-
entries: [...this.#state.entries, ...newEntries]
|
|
52
|
-
});
|
|
42
|
+
return new ToolSetState(this.#tools, [...this.#entries, ...newEntries]);
|
|
53
43
|
}
|
|
54
|
-
/** Statically deactivate tools by name. */
|
|
55
44
|
deactivate(names) {
|
|
56
45
|
const newEntries = names.map((name) => ({
|
|
57
46
|
toolName: name,
|
|
58
47
|
resolve: () => false
|
|
59
48
|
}));
|
|
60
|
-
return new
|
|
61
|
-
...this.#state,
|
|
62
|
-
entries: [...this.#state.entries, ...newEntries]
|
|
63
|
-
});
|
|
49
|
+
return new ToolSetState(this.#tools, [...this.#entries, ...newEntries]);
|
|
64
50
|
}
|
|
65
51
|
activateWhen(nameOrPredicates, predicate) {
|
|
66
|
-
|
|
67
|
-
return new ToolSet({
|
|
68
|
-
...this.#state,
|
|
69
|
-
entries: [...this.#state.entries, ...newEntries]
|
|
70
|
-
});
|
|
52
|
+
return new ToolSetState(this.#tools, [...this.#entries, ...toEntries(nameOrPredicates, predicate)]);
|
|
71
53
|
}
|
|
72
54
|
deactivateWhen(nameOrPredicates, predicate) {
|
|
73
55
|
const newEntries = toEntries(nameOrPredicates, predicate).map((e) => ({
|
|
74
56
|
...e,
|
|
75
57
|
resolve: (input) => !e.resolve(input)
|
|
76
58
|
}));
|
|
77
|
-
return new
|
|
78
|
-
...this.#state,
|
|
79
|
-
entries: [...this.#state.entries, ...newEntries]
|
|
80
|
-
});
|
|
59
|
+
return new ToolSetState(this.#tools, [...this.#entries, ...newEntries]);
|
|
81
60
|
}
|
|
82
|
-
/**
|
|
61
|
+
/** Evaluate all predicates with the provided input and return resolved tools + activeTools. */
|
|
83
62
|
inferTools(input) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
63
|
+
const activeTools = Object.keys(this.#tools).filter((name) => {
|
|
64
|
+
const lastEntry = this.#entries.findLast((e) => e.toolName === name);
|
|
65
|
+
if (!lastEntry) return true;
|
|
66
|
+
return lastEntry.resolve(input);
|
|
87
67
|
});
|
|
68
|
+
return {
|
|
69
|
+
tools: this.#tools,
|
|
70
|
+
activeTools
|
|
71
|
+
};
|
|
88
72
|
}
|
|
89
73
|
};
|
|
90
74
|
/**
|
|
91
|
-
*
|
|
75
|
+
* An immutable tool set with chainable activation methods.
|
|
92
76
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
77
|
+
* Resolution follows "last-call wins": each method appends an entry,
|
|
78
|
+
* and the last entry for each tool determines its state.
|
|
79
|
+
* Default (no entry) is active.
|
|
96
80
|
*/
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
81
|
+
var ImmutableToolSet = class ImmutableToolSet {
|
|
82
|
+
#state;
|
|
83
|
+
/** All tools as a standard AI SDK tool record. */
|
|
84
|
+
tools;
|
|
85
|
+
/** Resolved list of active tool names based on current state. */
|
|
86
|
+
activeTools;
|
|
87
|
+
constructor(state) {
|
|
88
|
+
this.#state = state;
|
|
89
|
+
this.tools = state.tools;
|
|
90
|
+
this.activeTools = state.activeTools;
|
|
91
|
+
}
|
|
92
|
+
/** Statically activate tools by name. */
|
|
93
|
+
activate(names) {
|
|
94
|
+
return new ImmutableToolSet(this.#state.activate(names));
|
|
95
|
+
}
|
|
96
|
+
/** Statically deactivate tools by name. */
|
|
97
|
+
deactivate(names) {
|
|
98
|
+
return new ImmutableToolSet(this.#state.deactivate(names));
|
|
99
|
+
}
|
|
100
|
+
activateWhen(nameOrPredicates, predicate) {
|
|
101
|
+
return new ImmutableToolSet(this.#state.activateWhen(nameOrPredicates, predicate));
|
|
102
|
+
}
|
|
103
|
+
deactivateWhen(nameOrPredicates, predicate) {
|
|
104
|
+
return new ImmutableToolSet(this.#state.deactivateWhen(nameOrPredicates, predicate));
|
|
105
|
+
}
|
|
106
|
+
/** Evaluate all predicates with the provided input. Returns resolved `{ tools, activeTools }`. */
|
|
107
|
+
inferTools(input) {
|
|
108
|
+
return this.#state.inferTools(input);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* A mutable tool set with chainable activation methods.
|
|
113
|
+
*
|
|
114
|
+
* Same resolution semantics as ImmutableToolSet, but methods mutate
|
|
115
|
+
* in-place and return `this` instead of creating new instances.
|
|
116
|
+
*/
|
|
117
|
+
var MutableToolSet = class {
|
|
118
|
+
#state;
|
|
119
|
+
/** All tools as a standard AI SDK tool record. */
|
|
120
|
+
tools;
|
|
121
|
+
/** Resolved list of active tool names based on current state. */
|
|
122
|
+
activeTools;
|
|
123
|
+
constructor(state) {
|
|
124
|
+
this.#state = state;
|
|
125
|
+
this.tools = state.tools;
|
|
126
|
+
this.activeTools = state.activeTools;
|
|
127
|
+
}
|
|
128
|
+
#apply(state) {
|
|
129
|
+
this.#state = state;
|
|
130
|
+
this.activeTools = state.activeTools;
|
|
131
|
+
}
|
|
132
|
+
/** Statically activate tools by name. */
|
|
133
|
+
activate(names) {
|
|
134
|
+
this.#apply(this.#state.activate(names));
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
/** Statically deactivate tools by name. */
|
|
138
|
+
deactivate(names) {
|
|
139
|
+
this.#apply(this.#state.deactivate(names));
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
activateWhen(nameOrPredicates, predicate) {
|
|
143
|
+
this.#apply(this.#state.activateWhen(nameOrPredicates, predicate));
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
deactivateWhen(nameOrPredicates, predicate) {
|
|
147
|
+
this.#apply(this.#state.deactivateWhen(nameOrPredicates, predicate));
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
/** Evaluate all predicates with the provided input. Returns resolved `{ tools, activeTools }`. */
|
|
151
|
+
inferTools(input) {
|
|
152
|
+
return this.#state.inferTools(input);
|
|
153
|
+
}
|
|
106
154
|
};
|
|
155
|
+
function createToolSet(options) {
|
|
156
|
+
const state = new ToolSetState(options.tools, []);
|
|
157
|
+
return options.mutable ? new MutableToolSet(state) : new ImmutableToolSet(state);
|
|
158
|
+
}
|
|
107
159
|
//#endregion
|
|
108
160
|
export { createToolSet };
|