ai-tool-set 1.0.0 → 1.1.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:
package/dist/index.d.mts CHANGED
@@ -8,19 +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 | 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
24
  /**
25
25
  * Input passed to activation predicates.
26
26
  * Use `ActivationInput<MyMsg>` to get per-tool narrowing in callbacks.
@@ -41,7 +41,31 @@ type ResolvedToolSet<TOOLS extends ToolRecord> = {
41
41
  activeTools: Array<keyof TOOLS & string>;
42
42
  };
43
43
  /** Union of both toolset classes for type utility constraints. */
44
- type AnyToolSet = ImmutableToolSet<any> | MutableToolSet<any>;
44
+ type AnyToolSet = ImmutableToolSet<any, any, any> | MutableToolSet<any, any, any>;
45
+ /**
46
+ * Derive a parameter type that accepts both immutable and mutable variants of an existing tool set.
47
+ *
48
+ * `createToolSet({ tools })` returns an `ImmutableToolSet`, while `.clone({ mutable: true })`
49
+ * returns a structurally distinct `MutableToolSet`. Helpers written against `typeof baseToolSet`
50
+ * directly cannot accept the cloned mutable instance — `ToolSet<typeof baseToolSet>` resolves
51
+ * to a union of both flavors and infers `TOOLS`, `MESSAGE`, and `CONTEXT` from the source.
52
+ *
53
+ * @example Accept either flavor in a helper function
54
+ * ```ts
55
+ * const baseToolSet = createToolSet({ tools }).deactivate(['cancel_order']);
56
+ *
57
+ * type MyToolSet = ToolSet<typeof baseToolSet>;
58
+ *
59
+ * // Accepts the immutable baseToolSet AND the cloned mutable instance
60
+ * function activateAdminTools(toolSet: MyToolSet) {
61
+ * toolSet.activate(['cancel_order']);
62
+ * }
63
+ *
64
+ * activateAdminTools(baseToolSet);
65
+ * activateAdminTools(baseToolSet.clone({ mutable: true }));
66
+ * ```
67
+ */
68
+ 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
69
  /**
46
70
  * Immutable state container for tool activation.
47
71
  *
@@ -152,4 +176,4 @@ declare function createToolSet<const TOOLS extends ToolRecord, MESSAGE extends M
152
176
  mutable?: false;
153
177
  }): ImmutableToolSet<TOOLS, MESSAGE, CONTEXT, keyof TOOLS & string>;
154
178
  //#endregion
155
- export { type ActivationInput, type InferActiveTools, type InferInactiveTools, type InferToolSet, type InferUIToolSet, createToolSet };
179
+ export { type ActivationInput, type InferActiveTools, 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.1.0",
4
+ "description": "Conditional tool activation for the AI SDK, fully type-safe",
5
5
  "keywords": [
6
6
  "ai",
7
7
  "ai-sdk",