ai-tool-set 0.1.0-alpha.2 → 0.1.0-alpha.4
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 +190 -92
- package/dist/index.d.mts +22 -14
- package/dist/index.mjs +12 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,58 +58,53 @@ const tools = {
|
|
|
58
58
|
const toolSet = createToolSet({ tools });
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
###
|
|
61
|
+
### Activate and Deactivate Tools
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
Use `.activate()` and `.deactivate()` to statically control which tools are available. Call `.inferTools()` to resolve `activeTools` and pass into `generateText()` or `streamText()`:
|
|
64
64
|
|
|
65
65
|
```typescript
|
|
66
66
|
import { generateText } from 'ai';
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
tools,
|
|
73
|
-
activeTools,
|
|
74
|
-
// Or spread tool set directly:
|
|
75
|
-
// ...toolSet,
|
|
76
|
-
prompt: 'Hello',
|
|
77
|
-
});
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Activate and Deactivate Tools
|
|
81
|
-
|
|
82
|
-
Use `.activate()` and `.deactivate()` to statically control which tools are available:
|
|
68
|
+
// Activate and deactivate tools
|
|
69
|
+
const toolSet = createToolSet({ tools })
|
|
70
|
+
.deactivate(['cancel_order'])
|
|
71
|
+
.activate(['list_orders']);
|
|
83
72
|
|
|
84
|
-
|
|
85
|
-
const { tools, activeTools } = toolSet.
|
|
73
|
+
// Infer active tools
|
|
74
|
+
const { tools, activeTools } = toolSet.inferTools();
|
|
86
75
|
|
|
87
76
|
const result = await generateText({
|
|
88
77
|
model,
|
|
78
|
+
// Pass tools and activeTools:
|
|
89
79
|
tools,
|
|
90
80
|
activeTools,
|
|
81
|
+
// Or spread directly:
|
|
82
|
+
// ...toolSet.deactivate(['cancel_order']).activate(['list_orders']).inferTools(),
|
|
91
83
|
prompt: 'Show me my orders',
|
|
92
84
|
});
|
|
93
85
|
```
|
|
94
86
|
|
|
95
87
|
### Conditional Activation
|
|
96
88
|
|
|
97
|
-
Use `.activateWhen()` and `.deactivateWhen()` to conditionally control tools based on messages and context. The predicate receives an
|
|
89
|
+
Use `.activateWhen()` and `.deactivateWhen()` to conditionally control tools based on messages and context. The predicate receives an input with `messages` and `context` (both can be `undefined` if not provided to `inferTools`) and should return a boolean (or undefined) to determine whether the tool should be activated/deactivated.
|
|
98
90
|
|
|
99
91
|
```typescript
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
p
|
|
92
|
+
// Conditional activation with a predicate that checks for unfulfilled orders in the messages
|
|
93
|
+
const toolSet = createToolSet({ tools })
|
|
94
|
+
.activateWhen('list_orders', ({ context }) => context?.isAuthenticated)
|
|
95
|
+
.activateWhen('cancel_order', ({ messages }) =>
|
|
96
|
+
messages?.some((m) =>
|
|
97
|
+
m.parts.some(
|
|
98
|
+
(p) =>
|
|
99
|
+
p.type === 'tool-list_orders' &&
|
|
100
|
+
p.state === 'output-available' &&
|
|
101
|
+
p.output.orders?.some((order) => order.status !== 'fulfilled'),
|
|
102
|
+
),
|
|
107
103
|
),
|
|
108
|
-
)
|
|
109
|
-
);
|
|
104
|
+
);
|
|
110
105
|
```
|
|
111
106
|
|
|
112
|
-
|
|
107
|
+
Call `.inferTools()` with messages and/or context to evaluate activation predicates and resolve `activeTools`:
|
|
113
108
|
|
|
114
109
|
```typescript
|
|
115
110
|
const messages = [
|
|
@@ -136,8 +131,10 @@ const messages = [
|
|
|
136
131
|
},
|
|
137
132
|
];
|
|
138
133
|
|
|
134
|
+
const context = { isAuthenticated: true };
|
|
135
|
+
|
|
139
136
|
// cancel_order is now active because list_orders returned unfulfilled orders
|
|
140
|
-
const { tools, activeTools } = toolSet.inferTools({ messages, context
|
|
137
|
+
const { tools, activeTools } = toolSet.inferTools({ messages, context });
|
|
141
138
|
|
|
142
139
|
const result = await generateText({ model, tools, activeTools, messages });
|
|
143
140
|
```
|
|
@@ -145,26 +142,53 @@ const result = await generateText({ model, tools, activeTools, messages });
|
|
|
145
142
|
You can also activate multiple tools at once:
|
|
146
143
|
|
|
147
144
|
```typescript
|
|
148
|
-
const toolSet = createToolSet({ tools })
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
})
|
|
145
|
+
const toolSet = createToolSet({ tools })
|
|
146
|
+
.activateWhen({
|
|
147
|
+
list_orders: ({ context }) => context?.isAuthenticated,
|
|
148
|
+
cancel_order: ({ messages }) => hasUnfulfilledOrders(messages),
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Activation Defaults
|
|
153
|
+
|
|
154
|
+
`.activateWhen()` marks a tool as **inactive by default**. It only becomes active when the predicate returns `true`. If the predicate returns `undefined` or `false`, the tool stays inactive:
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
const toolSet = createToolSet({ tools })
|
|
158
|
+
// undefined when messages is not provided → tool stays inactive
|
|
159
|
+
// false when no orders found → tool stays inactive
|
|
160
|
+
// true when orders found → tool becomes active
|
|
161
|
+
.activateWhen('cancel_order', ({ messages }) => messages?.some((m) => hasOrders(m)));
|
|
162
|
+
|
|
163
|
+
toolSet.inferTools().activeTools; // cancel_order is inactive (predicate received undefined)
|
|
164
|
+
toolSet.inferTools({ messages: [] }).activeTools; // cancel_order is inactive (no orders)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`.deactivateWhen()` marks a tool as **active by default**. It only becomes inactive when the predicate returns `true`. If the predicate returns `undefined` or `false`, the tool stays active:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
const toolSet = createToolSet({ tools })
|
|
171
|
+
// undefined when messages is not provided → tool stays active
|
|
172
|
+
// false when few messages → tool stays active
|
|
173
|
+
// true when too many messages → tool becomes inactive
|
|
174
|
+
.deactivateWhen('search', ({ messages }) => messages && messages.length > 10);
|
|
175
|
+
|
|
176
|
+
toolSet.inferTools().activeTools; // search is active (predicate received undefined)
|
|
177
|
+
toolSet.inferTools({ messages: [] }).activeTools; // search is active (few messages)
|
|
152
178
|
```
|
|
153
179
|
|
|
154
180
|
### Last-Call Wins
|
|
155
181
|
|
|
156
|
-
Each method appends to an internal list. For each tool, the **last entry** determines its state. This makes ordering explicit and predictable:
|
|
182
|
+
Each activation method appends to an internal list. For each tool, the **last entry** determines its state. This makes ordering explicit and predictable:
|
|
157
183
|
|
|
158
184
|
```typescript
|
|
159
185
|
const toolSet = createToolSet({ tools })
|
|
160
|
-
|
|
161
|
-
.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
) => hasUnfulfilledOrders(messages),
|
|
167
|
-
);
|
|
186
|
+
// cancel_order: activated
|
|
187
|
+
.activate(['cancel_order'])
|
|
188
|
+
// cancel_order: deactivated
|
|
189
|
+
.deactivate(['cancel_order'])
|
|
190
|
+
// cancel_order: deactivated with conditional activation
|
|
191
|
+
.activateWhen('cancel_order', ({ messages }) => hasUnfulfilledOrders(messages));
|
|
168
192
|
```
|
|
169
193
|
|
|
170
194
|
### Immutable vs Mutable
|
|
@@ -182,36 +206,63 @@ export async function POST(req: Request) {
|
|
|
182
206
|
// myToolSet !== toolSet, original toolSet is unchanged for next request
|
|
183
207
|
const myToolSet = toolSet.activate(['list_orders']);
|
|
184
208
|
|
|
185
|
-
const { tools, activeTools } = myToolSet;
|
|
186
|
-
|
|
187
209
|
const result = await generateText({
|
|
188
210
|
model,
|
|
189
|
-
|
|
190
|
-
activeTools,
|
|
211
|
+
...myToolSet.inferTools({ messages }),
|
|
191
212
|
messages,
|
|
192
213
|
});
|
|
193
214
|
}
|
|
194
215
|
```
|
|
195
216
|
|
|
196
|
-
|
|
217
|
+
Use `createToolSet({ 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
218
|
|
|
198
219
|
```typescript
|
|
199
220
|
export async function POST(req: Request) {
|
|
200
221
|
const { messages } = await req.json();
|
|
201
222
|
|
|
202
223
|
// Local scope: created and mutated per request
|
|
203
|
-
const toolSet = createToolSet({ tools, mutable: true })
|
|
224
|
+
const toolSet = createToolSet({ tools, mutable: true })
|
|
225
|
+
.deactivate(['list_order', 'cancel_order'])
|
|
226
|
+
.activate(['list_orders']);
|
|
204
227
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
228
|
+
const result = await generateText({
|
|
229
|
+
model,
|
|
230
|
+
...toolSet.inferTools({ messages }),
|
|
231
|
+
messages,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Cloning
|
|
208
237
|
|
|
209
|
-
|
|
238
|
+
Use `.clone({ mutable?: boolean })` to convert between immutable and mutable, preserving all activation entries:
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
// Convert an immutable toolset to mutable
|
|
242
|
+
const mutableToolSet = toolSet.clone({ mutable: true });
|
|
243
|
+
|
|
244
|
+
// Convert a mutable toolset back to immutable
|
|
245
|
+
const immutableToolSet = mutableToolSet.clone();
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
This is useful when you want to create a base tool set in the global scope and clone it per request to add request-specific activation:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
// Global scope: base tool set
|
|
252
|
+
const baseToolSet = createToolSet({ tools }).deactivate(['list_order', 'cancel_order']);
|
|
253
|
+
|
|
254
|
+
export async function POST(req: Request) {
|
|
255
|
+
const { messages } = await req.json();
|
|
256
|
+
|
|
257
|
+
// Clone the base tool set into a mutable instance for this request
|
|
258
|
+
const toolSet = baseToolSet.clone({ mutable: true });
|
|
259
|
+
|
|
260
|
+
// Activate list_orders only for this request
|
|
261
|
+
toolSet.activate(['list_orders']);
|
|
210
262
|
|
|
211
263
|
const result = await generateText({
|
|
212
264
|
model,
|
|
213
|
-
|
|
214
|
-
activeTools,
|
|
265
|
+
...toolSet.inferTools({ messages }),
|
|
215
266
|
messages,
|
|
216
267
|
});
|
|
217
268
|
}
|
|
@@ -246,14 +297,16 @@ If you already have a custom `UIMessage` type, you can pass it as `MESSAGE` gene
|
|
|
246
297
|
import { myTools } from './my-tools.js';
|
|
247
298
|
import { MyUIMessage } from './my-ui-message.js';
|
|
248
299
|
|
|
249
|
-
const toolSet = createToolSet<typeof myTools, MyUIMessage>({ tools: myTools })
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
)
|
|
253
|
-
//
|
|
254
|
-
// Messages are now typed as MyUIMessage
|
|
300
|
+
const toolSet = createToolSet<typeof myTools, MyUIMessage>({ tools: myTools })
|
|
301
|
+
.activateWhen(
|
|
302
|
+
'cancel_order',
|
|
303
|
+
({ messages }) => hasUnfulfilledOrders(messages),
|
|
304
|
+
// ~~~~~~~~
|
|
305
|
+
// Messages are now typed as Array<MyUIMessage> | undefined
|
|
306
|
+
);
|
|
307
|
+
|
|
255
308
|
|
|
256
|
-
const { tools, activeTools } = toolSet.inferTools({ messages
|
|
309
|
+
const { tools, activeTools } = toolSet.inferTools({ messages });
|
|
257
310
|
```
|
|
258
311
|
|
|
259
312
|
### Custom Context
|
|
@@ -266,16 +319,18 @@ import { MyUIMessage } from './my-ui-message.js';
|
|
|
266
319
|
|
|
267
320
|
type MyContext = { userId: string; isAdmin: boolean };
|
|
268
321
|
|
|
269
|
-
const toolSet = createToolSet<typeof myTools, MyUIMessage, MyContext>({ tools: myTools })
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
)
|
|
273
|
-
//
|
|
274
|
-
// Context is
|
|
322
|
+
const toolSet = createToolSet<typeof myTools, MyUIMessage, MyContext>({ tools: myTools })
|
|
323
|
+
.activateWhen(
|
|
324
|
+
'cancel_order',
|
|
325
|
+
({ context }) => context?.isAdmin,
|
|
326
|
+
// ~~~~~~~
|
|
327
|
+
// Context is typed as MyContext | undefined
|
|
328
|
+
);
|
|
329
|
+
|
|
275
330
|
|
|
276
331
|
const { tools, activeTools } = toolSet.inferTools({
|
|
277
332
|
messages,
|
|
278
|
-
context: { isAdmin: true },
|
|
333
|
+
context: { userId: '1', isAdmin: true },
|
|
279
334
|
});
|
|
280
335
|
```
|
|
281
336
|
|
|
@@ -303,14 +358,6 @@ All tools as a standard AI SDK tool record, regardless of activation state.
|
|
|
303
358
|
const { tools } = toolSet;
|
|
304
359
|
```
|
|
305
360
|
|
|
306
|
-
#### `.activeTools`
|
|
307
|
-
|
|
308
|
-
Resolved array of active tool names based on the current state.
|
|
309
|
-
|
|
310
|
-
```ts
|
|
311
|
-
const { activeTools } = toolSet;
|
|
312
|
-
```
|
|
313
|
-
|
|
314
361
|
#### `.activate(names)`
|
|
315
362
|
|
|
316
363
|
Statically activate tools by name. Returns a new instance (immutable) or `this` (mutable).
|
|
@@ -329,50 +376,69 @@ toolSet.deactivate(['search']);
|
|
|
329
376
|
|
|
330
377
|
#### `.activateWhen(name, predicate)` / `.activateWhen(predicates)`
|
|
331
378
|
|
|
332
|
-
Conditionally activate tools. The predicate receives `{ messages, context }` and returns `true` to activate.
|
|
379
|
+
Conditionally activate tools. The predicate receives `{ messages, context }` and returns `true` to activate. Both `messages` and `context` can be `undefined` if not provided to `inferTools`. Returning `undefined` is treated as `false`.
|
|
333
380
|
|
|
334
381
|
```ts
|
|
335
|
-
toolSet.activateWhen('cancel_order', ({ messages }) => hasOrders(
|
|
382
|
+
toolSet.activateWhen('cancel_order', ({ messages }) => messages?.some((m) => hasOrders(m)));
|
|
336
383
|
|
|
337
384
|
toolSet.activateWhen({
|
|
338
|
-
cancel_order: ({ messages }) => hasOrders(
|
|
339
|
-
list_orders: ({ context }) => context
|
|
385
|
+
cancel_order: ({ messages }) => messages?.some((m) => hasOrders(m)),
|
|
386
|
+
list_orders: ({ context }) => context?.isAuthenticated,
|
|
340
387
|
});
|
|
341
388
|
```
|
|
342
389
|
|
|
343
390
|
#### `.deactivateWhen(name, predicate)` / `.deactivateWhen(predicates)`
|
|
344
391
|
|
|
345
|
-
Conditionally deactivate tools. The predicate receives `{ messages, context }` and returns `true` to deactivate.
|
|
392
|
+
Conditionally deactivate tools. The predicate receives `{ messages, context }` and returns `true` to deactivate. Both `messages` and `context` can be `undefined` if not provided to `inferTools`. Returning `undefined` is treated as `false` (tool stays active).
|
|
346
393
|
|
|
347
394
|
```ts
|
|
348
|
-
toolSet.deactivateWhen('search', ({ messages }) => messages.length > 10);
|
|
395
|
+
toolSet.deactivateWhen('search', ({ messages }) => messages && messages.length > 10);
|
|
349
396
|
```
|
|
350
397
|
|
|
351
|
-
#### `.inferTools(input)`
|
|
398
|
+
#### `.inferTools(input?)`
|
|
352
399
|
|
|
353
|
-
Evaluate all predicates
|
|
400
|
+
Evaluate all predicates and return `{ tools, activeTools }`, directly spreadable into `generateText()` or `streamText()`. The input is optional; all fields are optional. Predicates receive `undefined` for fields not provided.
|
|
354
401
|
|
|
355
|
-
- `input
|
|
356
|
-
- `messages
|
|
357
|
-
- `context
|
|
402
|
+
- `input` (optional):
|
|
403
|
+
- `messages` (optional), the current conversation messages
|
|
404
|
+
- `context` (optional), arbitrary values passed to predicates
|
|
358
405
|
|
|
359
406
|
```ts
|
|
360
|
-
|
|
407
|
+
// Static-only (no predicates)
|
|
408
|
+
const { tools, activeTools } = toolSet.inferTools();
|
|
409
|
+
|
|
410
|
+
// With messages
|
|
411
|
+
const { tools, activeTools } = toolSet.inferTools({ messages });
|
|
412
|
+
|
|
413
|
+
// With context
|
|
414
|
+
const { tools, activeTools } = toolSet.inferTools({ context: { isAdmin: true } });
|
|
415
|
+
|
|
416
|
+
// With both
|
|
417
|
+
const { tools, activeTools } = toolSet.inferTools({ messages, context });
|
|
361
418
|
|
|
362
419
|
const result = await generateText({ model, tools, activeTools, messages });
|
|
363
420
|
```
|
|
364
421
|
|
|
422
|
+
#### `.clone(options?)`
|
|
423
|
+
|
|
424
|
+
Clone the toolset, preserving all activation entries. Pass `{ mutable: true }` to get a mutable clone, or omit for an immutable clone. Defaults to immutable.
|
|
425
|
+
|
|
426
|
+
```ts
|
|
427
|
+
const mutableClone = toolSet.clone({ mutable: true });
|
|
428
|
+
const immutableClone = toolSet.clone();
|
|
429
|
+
```
|
|
430
|
+
|
|
365
431
|
## Types
|
|
366
432
|
|
|
367
433
|
### `ActivationInput`
|
|
368
434
|
|
|
369
|
-
Input passed to activation predicates. Generic over `MESSAGE` and `CONTEXT`:
|
|
435
|
+
Input passed to activation predicates. Generic over `MESSAGE` and `CONTEXT`. Both `messages` and `context` are optional since they may not be provided to `inferTools`:
|
|
370
436
|
|
|
371
437
|
```ts
|
|
372
438
|
import type { ActivationInput } from 'ai-tool-set';
|
|
373
439
|
|
|
374
440
|
type MyInput = ActivationInput<MyUIMessage, { isAdmin: boolean }>;
|
|
375
|
-
// { messages
|
|
441
|
+
// { messages?: Array<MyUIMessage>; context?: { isAdmin: boolean } }
|
|
376
442
|
```
|
|
377
443
|
|
|
378
444
|
### `InferToolSet`
|
|
@@ -401,6 +467,38 @@ type MyUIMessage = UIMessage<unknown, any, InferUIToolSet<typeof toolSet>>;
|
|
|
401
467
|
// message.parts[0].output // typed as search tool's return type
|
|
402
468
|
```
|
|
403
469
|
|
|
470
|
+
### `ActiveTools`
|
|
471
|
+
|
|
472
|
+
Extract the tool names tracked as active from an immutable `ToolSet` instance. Tracks tools from `.activate()` and `.deactivateWhen()`.
|
|
473
|
+
|
|
474
|
+
> [!NOTE]
|
|
475
|
+
> `ActiveTools` returns `never` for mutable toolsets, since TypeScript cannot track type changes on the same reference across method calls.
|
|
476
|
+
|
|
477
|
+
```ts
|
|
478
|
+
import type { ActiveTools } from 'ai-tool-set';
|
|
479
|
+
|
|
480
|
+
const toolSet = createToolSet({ tools }).deactivate(['cancel_order']);
|
|
481
|
+
|
|
482
|
+
type Active = ActiveTools<typeof toolSet>;
|
|
483
|
+
// 'search' | 'list_orders'
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### `InactiveTools`
|
|
487
|
+
|
|
488
|
+
Extract the tool names tracked as inactive from an immutable `ToolSet` instance. Tracks tools from `.deactivate()` and `.activateWhen()`.
|
|
489
|
+
|
|
490
|
+
> [!NOTE]
|
|
491
|
+
> `InactiveTools` returns `never` for mutable toolsets, since TypeScript cannot track type changes on the same reference across method calls.
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
import type { InactiveTools } from 'ai-tool-set';
|
|
495
|
+
|
|
496
|
+
const toolSet = createToolSet({ tools }).deactivate(['cancel_order']);
|
|
497
|
+
|
|
498
|
+
type Inactive = InactiveTools<typeof toolSet>;
|
|
499
|
+
// 'cancel_order'
|
|
500
|
+
```
|
|
501
|
+
|
|
404
502
|
## License
|
|
405
503
|
|
|
406
504
|
MIT
|
package/dist/index.d.mts
CHANGED
|
@@ -26,14 +26,14 @@ type InactiveTools<T extends AnyToolSet> = T extends ImmutableToolSet<any, any,
|
|
|
26
26
|
* Use `ActivationInput<MyMsg>` to get per-tool narrowing in callbacks.
|
|
27
27
|
*/
|
|
28
28
|
type ActivationInput<MESSAGE extends MessageType = UIMessage, CONTEXT extends Record<string, unknown> = Record<string, unknown>> = {
|
|
29
|
-
messages
|
|
30
|
-
context
|
|
29
|
+
messages?: Array<MESSAGE>;
|
|
30
|
+
context?: CONTEXT;
|
|
31
31
|
};
|
|
32
|
-
/** Activation predicate — returns true if tool should be active. */
|
|
33
|
-
type ActivationPredicate<MESSAGE extends MessageType = UIMessage, CONTEXT extends Record<string, unknown> = Record<string, unknown>> = (input: ActivationInput<MESSAGE, CONTEXT>) => boolean;
|
|
32
|
+
/** Activation predicate — returns true if tool should be active. Undefined is treated as false. */
|
|
33
|
+
type ActivationPredicate<MESSAGE extends MessageType = UIMessage, CONTEXT extends Record<string, unknown> = Record<string, unknown>> = (input: ActivationInput<MESSAGE, CONTEXT>) => boolean | undefined;
|
|
34
34
|
type ActivationEntry = {
|
|
35
35
|
toolName: string;
|
|
36
|
-
resolve: (input: ActivationInput<any, any>) => boolean;
|
|
36
|
+
resolve: (input: ActivationInput<any, any>) => boolean | undefined;
|
|
37
37
|
};
|
|
38
38
|
/** Resolved tools and active tool names returned by `inferTools()`. */
|
|
39
39
|
type ResolvedToolSet<TOOLS extends ToolRecord> = {
|
|
@@ -54,14 +54,12 @@ declare class ToolSetState<TOOLS extends ToolRecord, MESSAGE extends MessageType
|
|
|
54
54
|
constructor(tools: TOOLS, entries: Array<ActivationEntry>);
|
|
55
55
|
/** All tools as a standard AI SDK tool record. */
|
|
56
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
57
|
activate(names: Array<string>): ToolSetState<TOOLS, MESSAGE, CONTEXT>;
|
|
60
58
|
deactivate(names: Array<string>): ToolSetState<TOOLS, MESSAGE, CONTEXT>;
|
|
61
59
|
activateWhen(nameOrPredicates: string | Partial<Record<string, ActivationPredicate<MESSAGE, CONTEXT>>>, predicate?: ActivationPredicate<MESSAGE, CONTEXT>): ToolSetState<TOOLS, MESSAGE, CONTEXT>;
|
|
62
60
|
deactivateWhen(nameOrPredicates: string | Partial<Record<string, ActivationPredicate<MESSAGE, CONTEXT>>>, predicate?: ActivationPredicate<MESSAGE, CONTEXT>): ToolSetState<TOOLS, MESSAGE, CONTEXT>;
|
|
63
61
|
/** Evaluate all predicates with the provided input and return resolved tools + activeTools. */
|
|
64
|
-
inferTools(input
|
|
62
|
+
inferTools(input?: ActivationInput<MESSAGE, CONTEXT>): ResolvedToolSet<TOOLS>;
|
|
65
63
|
}
|
|
66
64
|
/**
|
|
67
65
|
* An immutable tool set with chainable activation methods.
|
|
@@ -74,8 +72,6 @@ declare class ImmutableToolSet<TOOLS extends ToolRecord, MESSAGE extends Message
|
|
|
74
72
|
#private;
|
|
75
73
|
/** All tools as a standard AI SDK tool record. */
|
|
76
74
|
readonly tools: TOOLS;
|
|
77
|
-
/** Resolved list of active tool names based on current state. */
|
|
78
|
-
readonly activeTools: Array<keyof TOOLS & string>;
|
|
79
75
|
constructor(state: ToolSetState<TOOLS, MESSAGE, CONTEXT>);
|
|
80
76
|
/** Statically activate tools by name. */
|
|
81
77
|
activate<NAMES extends keyof TOOLS & string>(names: Array<NAMES>): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, ACTIVATED | NAMES, Exclude<DEACTIVATED, NAMES>>;
|
|
@@ -94,7 +90,14 @@ declare class ImmutableToolSet<TOOLS extends ToolRecord, MESSAGE extends Message
|
|
|
94
90
|
deactivateWhen<NAME extends keyof TOOLS & string>(name: NAME, predicate: ActivationPredicate<MESSAGE, CONTEXT>): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, ACTIVATED | NAME, Exclude<DEACTIVATED, NAME>>;
|
|
95
91
|
deactivateWhen<NAMES extends keyof TOOLS & string>(predicates: Partial<Record<NAMES, ActivationPredicate<MESSAGE, CONTEXT>>>): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, ACTIVATED | NAMES, Exclude<DEACTIVATED, NAMES>>;
|
|
96
92
|
/** Evaluate all predicates with the provided input. Returns resolved `{ tools, activeTools }`. */
|
|
97
|
-
inferTools(input
|
|
93
|
+
inferTools(input?: ActivationInput<MESSAGE, CONTEXT>): ResolvedToolSet<TOOLS>;
|
|
94
|
+
/** Clone this toolset, optionally switching between immutable and mutable. */
|
|
95
|
+
clone(options: {
|
|
96
|
+
mutable: true;
|
|
97
|
+
}): MutableToolSet<TOOLS, MESSAGE, CONTEXT>;
|
|
98
|
+
clone(options?: {
|
|
99
|
+
mutable?: false;
|
|
100
|
+
}): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, ACTIVATED, DEACTIVATED>;
|
|
98
101
|
}
|
|
99
102
|
/**
|
|
100
103
|
* A mutable tool set with chainable activation methods.
|
|
@@ -106,8 +109,6 @@ declare class MutableToolSet<TOOLS extends ToolRecord, MESSAGE extends MessageTy
|
|
|
106
109
|
#private;
|
|
107
110
|
/** All tools as a standard AI SDK tool record. */
|
|
108
111
|
readonly tools: TOOLS;
|
|
109
|
-
/** Resolved list of active tool names based on current state. */
|
|
110
|
-
activeTools: Array<keyof TOOLS & string>;
|
|
111
112
|
constructor(state: ToolSetState<TOOLS, MESSAGE, CONTEXT>);
|
|
112
113
|
/** Statically activate tools by name. */
|
|
113
114
|
activate(names: Array<keyof TOOLS & string>): this;
|
|
@@ -124,7 +125,14 @@ declare class MutableToolSet<TOOLS extends ToolRecord, MESSAGE extends MessageTy
|
|
|
124
125
|
deactivateWhen(name: keyof TOOLS & string, predicate: ActivationPredicate<MESSAGE, CONTEXT>): this;
|
|
125
126
|
deactivateWhen(predicates: Partial<Record<keyof TOOLS & string, ActivationPredicate<MESSAGE, CONTEXT>>>): this;
|
|
126
127
|
/** Evaluate all predicates with the provided input. Returns resolved `{ tools, activeTools }`. */
|
|
127
|
-
inferTools(input
|
|
128
|
+
inferTools(input?: ActivationInput<MESSAGE, CONTEXT>): ResolvedToolSet<TOOLS>;
|
|
129
|
+
/** Clone this toolset, optionally switching between immutable and mutable. */
|
|
130
|
+
clone(options: {
|
|
131
|
+
mutable: true;
|
|
132
|
+
}): MutableToolSet<TOOLS, MESSAGE, CONTEXT>;
|
|
133
|
+
clone(options?: {
|
|
134
|
+
mutable?: false;
|
|
135
|
+
}): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, keyof TOOLS & string>;
|
|
128
136
|
}
|
|
129
137
|
type CreateToolSetOptions<TOOLS extends ToolRecord> = {
|
|
130
138
|
tools: TOOLS;
|
package/dist/index.mjs
CHANGED
|
@@ -27,13 +27,6 @@ var ToolSetState = class ToolSetState {
|
|
|
27
27
|
get tools() {
|
|
28
28
|
return this.#tools;
|
|
29
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;
|
|
36
|
-
}
|
|
37
30
|
activate(names) {
|
|
38
31
|
const newEntries = names.map((name) => ({
|
|
39
32
|
toolName: name,
|
|
@@ -63,7 +56,7 @@ var ToolSetState = class ToolSetState {
|
|
|
63
56
|
const activeTools = Object.keys(this.#tools).filter((name) => {
|
|
64
57
|
const lastEntry = this.#entries.findLast((e) => e.toolName === name);
|
|
65
58
|
if (!lastEntry) return true;
|
|
66
|
-
return lastEntry.resolve(input);
|
|
59
|
+
return lastEntry.resolve(input ?? {});
|
|
67
60
|
});
|
|
68
61
|
return {
|
|
69
62
|
tools: this.#tools,
|
|
@@ -82,12 +75,9 @@ var ImmutableToolSet = class ImmutableToolSet {
|
|
|
82
75
|
#state;
|
|
83
76
|
/** All tools as a standard AI SDK tool record. */
|
|
84
77
|
tools;
|
|
85
|
-
/** Resolved list of active tool names based on current state. */
|
|
86
|
-
activeTools;
|
|
87
78
|
constructor(state) {
|
|
88
79
|
this.#state = state;
|
|
89
80
|
this.tools = state.tools;
|
|
90
|
-
this.activeTools = state.activeTools;
|
|
91
81
|
}
|
|
92
82
|
/** Statically activate tools by name. */
|
|
93
83
|
activate(names) {
|
|
@@ -107,6 +97,9 @@ var ImmutableToolSet = class ImmutableToolSet {
|
|
|
107
97
|
inferTools(input) {
|
|
108
98
|
return this.#state.inferTools(input);
|
|
109
99
|
}
|
|
100
|
+
clone(options) {
|
|
101
|
+
return options?.mutable ? new MutableToolSet(this.#state) : new ImmutableToolSet(this.#state);
|
|
102
|
+
}
|
|
110
103
|
};
|
|
111
104
|
/**
|
|
112
105
|
* A mutable tool set with chainable activation methods.
|
|
@@ -114,43 +107,39 @@ var ImmutableToolSet = class ImmutableToolSet {
|
|
|
114
107
|
* Same resolution semantics as ImmutableToolSet, but methods mutate
|
|
115
108
|
* in-place and return `this` instead of creating new instances.
|
|
116
109
|
*/
|
|
117
|
-
var MutableToolSet = class {
|
|
110
|
+
var MutableToolSet = class MutableToolSet {
|
|
118
111
|
#state;
|
|
119
112
|
/** All tools as a standard AI SDK tool record. */
|
|
120
113
|
tools;
|
|
121
|
-
/** Resolved list of active tool names based on current state. */
|
|
122
|
-
activeTools;
|
|
123
114
|
constructor(state) {
|
|
124
115
|
this.#state = state;
|
|
125
116
|
this.tools = state.tools;
|
|
126
|
-
this.activeTools = state.activeTools;
|
|
127
|
-
}
|
|
128
|
-
#apply(state) {
|
|
129
|
-
this.#state = state;
|
|
130
|
-
this.activeTools = state.activeTools;
|
|
131
117
|
}
|
|
132
118
|
/** Statically activate tools by name. */
|
|
133
119
|
activate(names) {
|
|
134
|
-
this.#
|
|
120
|
+
this.#state = this.#state.activate(names);
|
|
135
121
|
return this;
|
|
136
122
|
}
|
|
137
123
|
/** Statically deactivate tools by name. */
|
|
138
124
|
deactivate(names) {
|
|
139
|
-
this.#
|
|
125
|
+
this.#state = this.#state.deactivate(names);
|
|
140
126
|
return this;
|
|
141
127
|
}
|
|
142
128
|
activateWhen(nameOrPredicates, predicate) {
|
|
143
|
-
this.#
|
|
129
|
+
this.#state = this.#state.activateWhen(nameOrPredicates, predicate);
|
|
144
130
|
return this;
|
|
145
131
|
}
|
|
146
132
|
deactivateWhen(nameOrPredicates, predicate) {
|
|
147
|
-
this.#
|
|
133
|
+
this.#state = this.#state.deactivateWhen(nameOrPredicates, predicate);
|
|
148
134
|
return this;
|
|
149
135
|
}
|
|
150
136
|
/** Evaluate all predicates with the provided input. Returns resolved `{ tools, activeTools }`. */
|
|
151
137
|
inferTools(input) {
|
|
152
138
|
return this.#state.inferTools(input);
|
|
153
139
|
}
|
|
140
|
+
clone(options) {
|
|
141
|
+
return options?.mutable ? new MutableToolSet(this.#state) : new ImmutableToolSet(this.#state);
|
|
142
|
+
}
|
|
154
143
|
};
|
|
155
144
|
function createToolSet(options) {
|
|
156
145
|
const state = new ToolSetState(options.tools, []);
|