ai-tool-set 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Chris
3
+ Copyright (c) 2024 Chris Cook
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ai-tool-set
4
4
 
5
- <p align="center">AI SDK: Manage tool activation with type-safe, chainable tool sets</p>
5
+ <p align="center">Conditional tool activation for the AI SDK, fully type-safe</p>
6
6
  <p align="center">
7
7
  <a href="https://www.npmjs.com/package/ai-tool-set" alt="ai-tool-set"><img src="https://img.shields.io/npm/dt/ai-tool-set?label=ai-tool-set"></a> <a href="https://github.com/zirkelc/ai-tool-set/actions/workflows/ci.yml" alt="CI"><img src="https://img.shields.io/github/actions/workflow/status/zirkelc/ai-tool-set/ci.yml?branch=main"></a>
8
8
  </p>
@@ -441,6 +441,28 @@ type MyInput = ActivationInput<MyUIMessage, { isAdmin: boolean }>;
441
441
  // { messages?: Array<MyUIMessage>; context?: { isAdmin: boolean } }
442
442
  ```
443
443
 
444
+ ### `ToolSet`
445
+
446
+ Parameter type that accepts both immutable and mutable variants of an existing tool set. Use it for helpers that should work regardless of which flavor the caller is holding:
447
+
448
+ ```ts
449
+ import { createToolSet, type ToolSet } from 'ai-tool-set';
450
+
451
+ const toolSet = createToolSet({ tools }).deactivate(['cancel_order']);
452
+
453
+ type MyToolSet = ToolSet<typeof toolSet>;
454
+
455
+ // Accepts the immutable toolset AND the cloned mutable instance
456
+ function activateTools(toolSet: MyToolSet) {
457
+ toolSet.activate(['cancel_order']);
458
+ }
459
+
460
+ activateTools(toolSet);
461
+
462
+ const mutableToolSet = toolSet.clone({ mutable: true });
463
+ activateTools(mutableToolSet);
464
+ ```
465
+
444
466
  ### `InferToolSet`
445
467
 
446
468
  Extract the raw tool record from a tool record or `ToolSet` instance:
@@ -499,6 +521,19 @@ type Inactive = InferInactiveTools<typeof toolSet>;
499
521
  // 'cancel_order'
500
522
  ```
501
523
 
524
+ ### `InferAllTools`
525
+
526
+ Extract all tool names from a `ToolSet` instance, regardless of activation state. Works for both immutable and mutable toolsets since the tool record is statically known.
527
+
528
+ ```ts
529
+ import type { InferAllTools } from 'ai-tool-set';
530
+
531
+ const toolSet = createToolSet({ tools }).deactivate(['cancel_order']);
532
+
533
+ type All = InferAllTools<typeof toolSet>;
534
+ // 'search' | 'list_orders' | 'cancel_order'
535
+ ```
536
+
502
537
  ## License
503
538
 
504
539
  MIT
package/dist/index.d.mts CHANGED
@@ -8,19 +8,24 @@ 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 | AnyToolSet> = T extends ImmutableToolSet<infer TOOLS, any, any> ? TOOLS : T extends MutableToolSet<infer TOOLS, any, any> ? TOOLS : T;
11
+ type InferToolSet<TOOLSET extends ToolRecord | AnyToolSet> = TOOLSET extends ImmutableToolSet<infer TOOLS, any, any> ? TOOLS : TOOLSET extends MutableToolSet<infer TOOLS, any, any> ? TOOLS : TOOLSET;
12
12
  /** Infer the UI tool types from a tool record or ToolSet instance. */
13
- type InferUIToolSet<T extends ToolRecord | AnyToolSet> = { [K in keyof InferToolSet<T> & string]: InferUITool<InferToolSet<T>[K]> };
13
+ type InferUIToolSet<TOOLSET extends ToolRecord | AnyToolSet> = { [K in keyof InferToolSet<TOOLSET> & string]: InferUITool<InferToolSet<TOOLSET>[K]> };
14
14
  /**
15
15
  * Extract tool names tracked as active from an ImmutableToolSet instance.
16
16
  * Returns `never` for MutableToolSet (cannot be determined at compile time).
17
17
  */
18
- type InferActiveTools<T extends AnyToolSet> = T extends ImmutableToolSet<any, any, any, infer A, any> ? A : never;
18
+ type InferActiveTools<TOOLSET extends AnyToolSet> = TOOLSET extends ImmutableToolSet<any, any, any, infer A, any> ? A : never;
19
19
  /**
20
20
  * Extract tool names tracked as inactive from an ImmutableToolSet instance.
21
21
  * Returns `never` for MutableToolSet (cannot be determined at compile time).
22
22
  */
23
- type InferInactiveTools<T extends AnyToolSet> = T extends ImmutableToolSet<any, any, any, any, infer D> ? D : never;
23
+ type InferInactiveTools<TOOLSET extends AnyToolSet> = TOOLSET extends ImmutableToolSet<any, any, any, any, infer D> ? D : never;
24
+ /**
25
+ * Extract all tool names from a ToolSet instance — both active and inactive.
26
+ * Works for both ImmutableToolSet and MutableToolSet since the tool record is statically known.
27
+ */
28
+ type InferAllTools<TOOLSET extends AnyToolSet> = keyof InferToolSet<TOOLSET> & string;
24
29
  /**
25
30
  * Input passed to activation predicates.
26
31
  * Use `ActivationInput<MyMsg>` to get per-tool narrowing in callbacks.
@@ -41,7 +46,31 @@ type ResolvedToolSet<TOOLS extends ToolRecord> = {
41
46
  activeTools: Array<keyof TOOLS & string>;
42
47
  };
43
48
  /** Union of both toolset classes for type utility constraints. */
44
- type AnyToolSet = ImmutableToolSet<any> | MutableToolSet<any>;
49
+ type AnyToolSet = ImmutableToolSet<any, any, any> | MutableToolSet<any, any, any>;
50
+ /**
51
+ * Derive a parameter type that accepts both immutable and mutable variants of an existing tool set.
52
+ *
53
+ * `createToolSet({ tools })` returns an `ImmutableToolSet`, while `.clone({ mutable: true })`
54
+ * returns a structurally distinct `MutableToolSet`. Helpers written against `typeof baseToolSet`
55
+ * directly cannot accept the cloned mutable instance — `ToolSet<typeof baseToolSet>` resolves
56
+ * to a union of both flavors and infers `TOOLS`, `MESSAGE`, and `CONTEXT` from the source.
57
+ *
58
+ * @example Accept either flavor in a helper function
59
+ * ```ts
60
+ * const baseToolSet = createToolSet({ tools }).deactivate(['cancel_order']);
61
+ *
62
+ * type MyToolSet = ToolSet<typeof baseToolSet>;
63
+ *
64
+ * // Accepts the immutable baseToolSet AND the cloned mutable instance
65
+ * function activateAdminTools(toolSet: MyToolSet) {
66
+ * toolSet.activate(['cancel_order']);
67
+ * }
68
+ *
69
+ * activateAdminTools(baseToolSet);
70
+ * activateAdminTools(baseToolSet.clone({ mutable: true }));
71
+ * ```
72
+ */
73
+ type ToolSet<TOOLSET extends AnyToolSet> = TOOLSET extends ImmutableToolSet<infer TOOLS, infer MESSAGE, infer CONTEXT, infer ACTIVATED, infer DEACTIVATED> ? ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, ACTIVATED, DEACTIVATED> | MutableToolSet<TOOLS, MESSAGE, CONTEXT> : TOOLSET extends MutableToolSet<infer TOOLS, infer MESSAGE, infer CONTEXT> ? ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, any, any> | MutableToolSet<TOOLS, MESSAGE, CONTEXT> : never;
45
74
  /**
46
75
  * Immutable state container for tool activation.
47
76
  *
@@ -152,4 +181,4 @@ declare function createToolSet<const TOOLS extends ToolRecord, MESSAGE extends M
152
181
  mutable?: false;
153
182
  }): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, keyof TOOLS & string>;
154
183
  //#endregion
155
- export { type ActivationInput, type InferActiveTools, type InferInactiveTools, type InferToolSet, type InferUIToolSet, createToolSet };
184
+ export { type ActivationInput, type InferActiveTools, type InferAllTools, type InferInactiveTools, type InferToolSet, type InferUIToolSet, type ToolSet, createToolSet };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ai-tool-set",
3
- "version": "1.0.0",
4
- "description": "AI SDK: Manage tool activation with type-safe, chainable tool sets",
3
+ "version": "1.2.0",
4
+ "description": "Conditional tool activation for the AI SDK, fully type-safe",
5
5
  "keywords": [
6
6
  "ai",
7
7
  "ai-sdk",