typed-agents 1.0.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 +19 -0
- package/README.md +201 -0
- package/dist/agents/agent.decorator.d.ts +19 -0
- package/dist/agents/agent.decorator.d.ts.map +1 -0
- package/dist/agents/agent.decorator.js +38 -0
- package/dist/agents/agent.decorator.js.map +1 -0
- package/dist/agents/agent.runtime.d.ts +133 -0
- package/dist/agents/agent.runtime.d.ts.map +1 -0
- package/dist/agents/agent.runtime.js +593 -0
- package/dist/agents/agent.runtime.js.map +1 -0
- package/dist/agents/agent.types.d.ts +245 -0
- package/dist/agents/agent.types.d.ts.map +1 -0
- package/dist/agents/agent.types.js +27 -0
- package/dist/agents/agent.types.js.map +1 -0
- package/dist/agents/behavior-engine/behavior.types.d.ts +23 -0
- package/dist/agents/behavior-engine/behavior.types.d.ts.map +1 -0
- package/dist/agents/behavior-engine/behavior.types.js +3 -0
- package/dist/agents/behavior-engine/behavior.types.js.map +1 -0
- package/dist/agents/behavior-engine/build-system-prompt.d.ts +12 -0
- package/dist/agents/behavior-engine/build-system-prompt.d.ts.map +1 -0
- package/dist/agents/behavior-engine/build-system-prompt.js +29 -0
- package/dist/agents/behavior-engine/build-system-prompt.js.map +1 -0
- package/dist/agents/behavior-engine/index.d.ts +7 -0
- package/dist/agents/behavior-engine/index.d.ts.map +1 -0
- package/dist/agents/behavior-engine/index.js +23 -0
- package/dist/agents/behavior-engine/index.js.map +1 -0
- package/dist/agents/behavior-engine/load-behavior.d.ts +16 -0
- package/dist/agents/behavior-engine/load-behavior.d.ts.map +1 -0
- package/dist/agents/behavior-engine/load-behavior.js +36 -0
- package/dist/agents/behavior-engine/load-behavior.js.map +1 -0
- package/dist/agents/behavior-engine/merge-behavior.d.ts +12 -0
- package/dist/agents/behavior-engine/merge-behavior.d.ts.map +1 -0
- package/dist/agents/behavior-engine/merge-behavior.js +33 -0
- package/dist/agents/behavior-engine/merge-behavior.js.map +1 -0
- package/dist/agents/behavior-engine/parse-behavior.d.ts +10 -0
- package/dist/agents/behavior-engine/parse-behavior.d.ts.map +1 -0
- package/dist/agents/behavior-engine/parse-behavior.js +66 -0
- package/dist/agents/behavior-engine/parse-behavior.js.map +1 -0
- package/dist/agents/behavior-engine/watch-behavior.d.ts +10 -0
- package/dist/agents/behavior-engine/watch-behavior.d.ts.map +1 -0
- package/dist/agents/behavior-engine/watch-behavior.js +34 -0
- package/dist/agents/behavior-engine/watch-behavior.js.map +1 -0
- package/dist/agents/compose.d.ts +41 -0
- package/dist/agents/compose.d.ts.map +1 -0
- package/dist/agents/compose.js +29 -0
- package/dist/agents/compose.js.map +1 -0
- package/dist/agents/index.d.ts +7 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +25 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/runtime-engine/build-tool-map.d.ts +16 -0
- package/dist/agents/runtime-engine/build-tool-map.d.ts.map +1 -0
- package/dist/agents/runtime-engine/build-tool-map.js +88 -0
- package/dist/agents/runtime-engine/build-tool-map.js.map +1 -0
- package/dist/agents/runtime-engine/convert-zod-to-tool-schema.d.ts +13 -0
- package/dist/agents/runtime-engine/convert-zod-to-tool-schema.d.ts.map +1 -0
- package/dist/agents/runtime-engine/convert-zod-to-tool-schema.js +26 -0
- package/dist/agents/runtime-engine/convert-zod-to-tool-schema.js.map +1 -0
- package/dist/agents/runtime-engine/execute-tool.d.ts +19 -0
- package/dist/agents/runtime-engine/execute-tool.d.ts.map +1 -0
- package/dist/agents/runtime-engine/execute-tool.js +100 -0
- package/dist/agents/runtime-engine/execute-tool.js.map +1 -0
- package/dist/agents/runtime-engine/index.d.ts +7 -0
- package/dist/agents/runtime-engine/index.d.ts.map +1 -0
- package/dist/agents/runtime-engine/index.js +23 -0
- package/dist/agents/runtime-engine/index.js.map +1 -0
- package/dist/agents/runtime-engine/parse-tool-arguments.d.ts +12 -0
- package/dist/agents/runtime-engine/parse-tool-arguments.d.ts.map +1 -0
- package/dist/agents/runtime-engine/parse-tool-arguments.js +42 -0
- package/dist/agents/runtime-engine/parse-tool-arguments.js.map +1 -0
- package/dist/agents/runtime-engine/retry.utils.d.ts +26 -0
- package/dist/agents/runtime-engine/retry.utils.d.ts.map +1 -0
- package/dist/agents/runtime-engine/retry.utils.js +55 -0
- package/dist/agents/runtime-engine/retry.utils.js.map +1 -0
- package/dist/agents/runtime-engine/state-persistence.d.ts +56 -0
- package/dist/agents/runtime-engine/state-persistence.d.ts.map +1 -0
- package/dist/agents/runtime-engine/state-persistence.js +70 -0
- package/dist/agents/runtime-engine/state-persistence.js.map +1 -0
- package/dist/clients/index.d.ts +3 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +19 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/llm.client.d.ts +48 -0
- package/dist/clients/llm.client.d.ts.map +1 -0
- package/dist/clients/llm.client.js +3 -0
- package/dist/clients/llm.client.js.map +1 -0
- package/dist/clients/ollama.client.d.ts +20 -0
- package/dist/clients/ollama.client.d.ts.map +1 -0
- package/dist/clients/ollama.client.js +85 -0
- package/dist/clients/ollama.client.js.map +1 -0
- package/dist/core/logger/index.d.ts +2 -0
- package/dist/core/logger/index.d.ts.map +1 -0
- package/dist/core/logger/index.js +18 -0
- package/dist/core/logger/index.js.map +1 -0
- package/dist/core/logger/logger.d.ts +7 -0
- package/dist/core/logger/logger.d.ts.map +1 -0
- package/dist/core/logger/logger.js +19 -0
- package/dist/core/logger/logger.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/agent.runner.d.ts +29 -0
- package/dist/runtime/agent.runner.d.ts.map +1 -0
- package/dist/runtime/agent.runner.js +39 -0
- package/dist/runtime/agent.runner.js.map +1 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +18 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +20 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +128 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +140 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/tool.decorator.d.ts +71 -0
- package/dist/tools/tool.decorator.d.ts.map +1 -0
- package/dist/tools/tool.decorator.js +98 -0
- package/dist/tools/tool.decorator.js.map +1 -0
- package/dist/tools/tool.types.d.ts +231 -0
- package/dist/tools/tool.types.d.ts.map +1 -0
- package/dist/tools/tool.types.js +3 -0
- package/dist/tools/tool.types.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./registry"), exports);
|
|
18
|
+
__exportStar(require("./tool.decorator"), exports);
|
|
19
|
+
__exportStar(require("./tool.types"), exports);
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,mDAAiC;AACjC,+CAA6B"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { ToolClass, ToolMetadata } from "./tool.types";
|
|
2
|
+
/**
|
|
3
|
+
* Internal shape of a single entry stored inside the registry for each tool method.
|
|
4
|
+
* Groups the JavaScript method name with its associated metadata so both are
|
|
5
|
+
* always available together during tool resolution and dispatch.
|
|
6
|
+
*/
|
|
7
|
+
interface RegisteredTool {
|
|
8
|
+
/** The JavaScript property key of the decorated method on the tool class. */
|
|
9
|
+
method: string;
|
|
10
|
+
/** The full metadata supplied to the `@tool()` decorator for this method. */
|
|
11
|
+
metadata: ToolMetadata;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Global, static registry that tracks every tool method decorated with `@tool()`.
|
|
15
|
+
*
|
|
16
|
+
* `ToolRegistry` acts as the single source of truth for all tools known to the
|
|
17
|
+
* framework. It is populated automatically at class-definition time through the
|
|
18
|
+
* `@tool()` decorator — you should never need to call its methods directly in
|
|
19
|
+
* application code.
|
|
20
|
+
*
|
|
21
|
+
* Internally it maintains a `Map` keyed by tool class constructor, so multiple
|
|
22
|
+
* independent tool classes can coexist without naming collisions at the class level.
|
|
23
|
+
*
|
|
24
|
+
* ### Lifecycle
|
|
25
|
+
* 1. A module containing a `@tool()`-decorated class is imported.
|
|
26
|
+
* 2. TypeScript executes the decorator, which calls {@link ToolRegistry.registerMethod}.
|
|
27
|
+
* 3. The framework later calls {@link ToolRegistry.getTools} or
|
|
28
|
+
* {@link ToolRegistry.getAllRegisteredClasses} to build the tool dispatch map
|
|
29
|
+
* for an agent run.
|
|
30
|
+
* 4. In test environments, {@link ToolRegistry.clear} resets all state between tests.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
*
|
|
34
|
+
* // Inspect all tools registered on a specific class:
|
|
35
|
+
* const tools = ToolRegistry.getTools(MyToolsClass);
|
|
36
|
+
* tools.forEach(t => console.log(t.metadata.name));
|
|
37
|
+
*
|
|
38
|
+
*/
|
|
39
|
+
export declare class ToolRegistry {
|
|
40
|
+
/**
|
|
41
|
+
* The backing store mapping each tool class to the list of its registered methods.
|
|
42
|
+
* Kept private to enforce all access through the typed static API.
|
|
43
|
+
*/
|
|
44
|
+
private static tools;
|
|
45
|
+
/**
|
|
46
|
+
* Registers a single decorated method on a tool class.
|
|
47
|
+
*
|
|
48
|
+
* Called automatically by the `@tool()` decorator — **do not invoke manually**
|
|
49
|
+
* in production code. Each call appends the method entry to the class's existing
|
|
50
|
+
* list (or creates a new list if this is the first tool on the class).
|
|
51
|
+
*
|
|
52
|
+
* **Side-effects / warnings:**
|
|
53
|
+
* - Emits a `console.warn` if `metadata.description` is missing or empty,
|
|
54
|
+
* since a missing description degrades LLM tool-selection quality.
|
|
55
|
+
* - Emits a `console.warn` if another tool with the same `metadata.name` is
|
|
56
|
+
* already registered anywhere in the registry, because duplicate names cause
|
|
57
|
+
* non-deterministic behaviour when the model invokes that tool.
|
|
58
|
+
*
|
|
59
|
+
* @param toolClass - The class constructor on which the decorated method lives.
|
|
60
|
+
* @param method - The JavaScript property key of the decorated method (e.g. `'searchWeb'`).
|
|
61
|
+
* @param metadata - The full {@link ToolMetadata} passed to the `@tool()` decorator.
|
|
62
|
+
*/
|
|
63
|
+
static registerMethod(toolClass: ToolClass, method: string, metadata: ToolMetadata): void;
|
|
64
|
+
/**
|
|
65
|
+
* Returns all registered tool entries for a specific tool class.
|
|
66
|
+
*
|
|
67
|
+
* Use this to retrieve the tools belonging to a single class before building
|
|
68
|
+
* its dispatch map or generating its tool definitions for the LLM.
|
|
69
|
+
*
|
|
70
|
+
* @param toolClass - The class constructor whose tools you want to retrieve.
|
|
71
|
+
* @returns An array of `{ method, metadata }` entries, or an empty array if
|
|
72
|
+
* the class has no registered tools (or was never imported).
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
*
|
|
76
|
+
* const entries = ToolRegistry.getTools(WebSearchTools);
|
|
77
|
+
* const definitions = entries.map(e => toToolDefinition(e.metadata));
|
|
78
|
+
*
|
|
79
|
+
*/
|
|
80
|
+
static getTools(toolClass: ToolClass): RegisteredTool[];
|
|
81
|
+
/**
|
|
82
|
+
* Returns the constructors of every class that has at least one registered tool.
|
|
83
|
+
*
|
|
84
|
+
* Useful when building a full agent tool set dynamically — iterate the result,
|
|
85
|
+
* instantiate each class, and bind its tools via {@link getTools}.
|
|
86
|
+
*
|
|
87
|
+
* @returns An array of class constructors in insertion order.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
*
|
|
91
|
+
* const allClasses = ToolRegistry.getAllRegisteredClasses();
|
|
92
|
+
* const instances = allClasses.map(Cls => new Cls());
|
|
93
|
+
*
|
|
94
|
+
*/
|
|
95
|
+
static getAllRegisteredClasses(): ToolClass[];
|
|
96
|
+
/**
|
|
97
|
+
* Returns the `name` values of every registered tool, across all classes.
|
|
98
|
+
*
|
|
99
|
+
* Primarily used internally for duplicate-name detection inside
|
|
100
|
+
* {@link registerMethod}, but also handy for debugging or building allow-lists.
|
|
101
|
+
*
|
|
102
|
+
* @returns A flat array of tool name strings in registration order.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
*
|
|
106
|
+
* console.log(ToolRegistry.getAllToolNames());
|
|
107
|
+
* // ['search_web', 'read_file', 'send_email']
|
|
108
|
+
*
|
|
109
|
+
*/
|
|
110
|
+
static getAllToolNames(): string[];
|
|
111
|
+
/**
|
|
112
|
+
* Removes all registered tools from the registry, resetting it to its initial state.
|
|
113
|
+
*
|
|
114
|
+
* **Only use this in test environments.** Calling `clear()` in production will
|
|
115
|
+
* silently break any agent that relies on the cleared tools, since the decorators
|
|
116
|
+
* only run once at module load time and will not re-register.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
*
|
|
120
|
+
* afterEach(() => {
|
|
121
|
+
* ToolRegistry.clear();
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
*/
|
|
125
|
+
static clear(): void;
|
|
126
|
+
}
|
|
127
|
+
export {};
|
|
128
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEvD;;;;GAIG;AACH,UAAU,cAAc;IACtB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IAEf,6EAA6E;IAC7E,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,YAAY;IACvB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAA0C;IAE9D;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,cAAc,CACnB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,YAAY,GACrB,IAAI;IAeP;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,cAAc,EAAE;IAIvD;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,uBAAuB,IAAI,SAAS,EAAE;IAI7C;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,eAAe,IAAI,MAAM,EAAE;IAMlC;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,KAAK,IAAI,IAAI;CAGrB"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ToolRegistry = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Global, static registry that tracks every tool method decorated with `@tool()`.
|
|
6
|
+
*
|
|
7
|
+
* `ToolRegistry` acts as the single source of truth for all tools known to the
|
|
8
|
+
* framework. It is populated automatically at class-definition time through the
|
|
9
|
+
* `@tool()` decorator — you should never need to call its methods directly in
|
|
10
|
+
* application code.
|
|
11
|
+
*
|
|
12
|
+
* Internally it maintains a `Map` keyed by tool class constructor, so multiple
|
|
13
|
+
* independent tool classes can coexist without naming collisions at the class level.
|
|
14
|
+
*
|
|
15
|
+
* ### Lifecycle
|
|
16
|
+
* 1. A module containing a `@tool()`-decorated class is imported.
|
|
17
|
+
* 2. TypeScript executes the decorator, which calls {@link ToolRegistry.registerMethod}.
|
|
18
|
+
* 3. The framework later calls {@link ToolRegistry.getTools} or
|
|
19
|
+
* {@link ToolRegistry.getAllRegisteredClasses} to build the tool dispatch map
|
|
20
|
+
* for an agent run.
|
|
21
|
+
* 4. In test environments, {@link ToolRegistry.clear} resets all state between tests.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
*
|
|
25
|
+
* // Inspect all tools registered on a specific class:
|
|
26
|
+
* const tools = ToolRegistry.getTools(MyToolsClass);
|
|
27
|
+
* tools.forEach(t => console.log(t.metadata.name));
|
|
28
|
+
*
|
|
29
|
+
*/
|
|
30
|
+
class ToolRegistry {
|
|
31
|
+
/**
|
|
32
|
+
* The backing store mapping each tool class to the list of its registered methods.
|
|
33
|
+
* Kept private to enforce all access through the typed static API.
|
|
34
|
+
*/
|
|
35
|
+
static tools = new Map();
|
|
36
|
+
/**
|
|
37
|
+
* Registers a single decorated method on a tool class.
|
|
38
|
+
*
|
|
39
|
+
* Called automatically by the `@tool()` decorator — **do not invoke manually**
|
|
40
|
+
* in production code. Each call appends the method entry to the class's existing
|
|
41
|
+
* list (or creates a new list if this is the first tool on the class).
|
|
42
|
+
*
|
|
43
|
+
* **Side-effects / warnings:**
|
|
44
|
+
* - Emits a `console.warn` if `metadata.description` is missing or empty,
|
|
45
|
+
* since a missing description degrades LLM tool-selection quality.
|
|
46
|
+
* - Emits a `console.warn` if another tool with the same `metadata.name` is
|
|
47
|
+
* already registered anywhere in the registry, because duplicate names cause
|
|
48
|
+
* non-deterministic behaviour when the model invokes that tool.
|
|
49
|
+
*
|
|
50
|
+
* @param toolClass - The class constructor on which the decorated method lives.
|
|
51
|
+
* @param method - The JavaScript property key of the decorated method (e.g. `'searchWeb'`).
|
|
52
|
+
* @param metadata - The full {@link ToolMetadata} passed to the `@tool()` decorator.
|
|
53
|
+
*/
|
|
54
|
+
static registerMethod(toolClass, method, metadata) {
|
|
55
|
+
if (!metadata.description) {
|
|
56
|
+
console.warn(`[ToolRegistry] Tool "${metadata.name}" has not description`);
|
|
57
|
+
}
|
|
58
|
+
const existing = this.tools.get(toolClass) ?? [];
|
|
59
|
+
existing.push({ method, metadata });
|
|
60
|
+
this.tools.set(toolClass, existing);
|
|
61
|
+
const allNames = this.getAllToolNames();
|
|
62
|
+
if (allNames.filter((n) => n === metadata.name).length > 1) {
|
|
63
|
+
console.warn(`[ToolRegistry] ⚠️ Duplicated tool: "${metadata.name}"`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Returns all registered tool entries for a specific tool class.
|
|
68
|
+
*
|
|
69
|
+
* Use this to retrieve the tools belonging to a single class before building
|
|
70
|
+
* its dispatch map or generating its tool definitions for the LLM.
|
|
71
|
+
*
|
|
72
|
+
* @param toolClass - The class constructor whose tools you want to retrieve.
|
|
73
|
+
* @returns An array of `{ method, metadata }` entries, or an empty array if
|
|
74
|
+
* the class has no registered tools (or was never imported).
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
*
|
|
78
|
+
* const entries = ToolRegistry.getTools(WebSearchTools);
|
|
79
|
+
* const definitions = entries.map(e => toToolDefinition(e.metadata));
|
|
80
|
+
*
|
|
81
|
+
*/
|
|
82
|
+
static getTools(toolClass) {
|
|
83
|
+
return this.tools.get(toolClass) ?? [];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Returns the constructors of every class that has at least one registered tool.
|
|
87
|
+
*
|
|
88
|
+
* Useful when building a full agent tool set dynamically — iterate the result,
|
|
89
|
+
* instantiate each class, and bind its tools via {@link getTools}.
|
|
90
|
+
*
|
|
91
|
+
* @returns An array of class constructors in insertion order.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
*
|
|
95
|
+
* const allClasses = ToolRegistry.getAllRegisteredClasses();
|
|
96
|
+
* const instances = allClasses.map(Cls => new Cls());
|
|
97
|
+
*
|
|
98
|
+
*/
|
|
99
|
+
static getAllRegisteredClasses() {
|
|
100
|
+
return Array.from(this.tools.keys());
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Returns the `name` values of every registered tool, across all classes.
|
|
104
|
+
*
|
|
105
|
+
* Primarily used internally for duplicate-name detection inside
|
|
106
|
+
* {@link registerMethod}, but also handy for debugging or building allow-lists.
|
|
107
|
+
*
|
|
108
|
+
* @returns A flat array of tool name strings in registration order.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
*
|
|
112
|
+
* console.log(ToolRegistry.getAllToolNames());
|
|
113
|
+
* // ['search_web', 'read_file', 'send_email']
|
|
114
|
+
*
|
|
115
|
+
*/
|
|
116
|
+
static getAllToolNames() {
|
|
117
|
+
return Array.from(this.tools.values())
|
|
118
|
+
.flat()
|
|
119
|
+
.map((t) => t.metadata.name);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Removes all registered tools from the registry, resetting it to its initial state.
|
|
123
|
+
*
|
|
124
|
+
* **Only use this in test environments.** Calling `clear()` in production will
|
|
125
|
+
* silently break any agent that relies on the cleared tools, since the decorators
|
|
126
|
+
* only run once at module load time and will not re-register.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
*
|
|
130
|
+
* afterEach(() => {
|
|
131
|
+
* ToolRegistry.clear();
|
|
132
|
+
* });
|
|
133
|
+
*
|
|
134
|
+
*/
|
|
135
|
+
static clear() {
|
|
136
|
+
this.tools.clear();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.ToolRegistry = ToolRegistry;
|
|
140
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":";;;AAeA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAa,YAAY;IACvB;;;OAGG;IACK,MAAM,CAAC,KAAK,GAAG,IAAI,GAAG,EAA+B,CAAC;IAE9D;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,cAAc,CACnB,SAAoB,EACpB,MAAc,EACd,QAAsB;QAEtB,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,wBAAwB,QAAQ,CAAC,IAAI,uBAAuB,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACjD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACxC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,uCAAuC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,QAAQ,CAAC,SAAoB;QAClC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IACzC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,uBAAuB;QAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,eAAe;QACpB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;aACnC,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,KAAK;QACV,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;;AAtHH,oCAuHC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { ToolMetadata } from "./tool.types";
|
|
3
|
+
/**
|
|
4
|
+
* Method decorator that marks a class method as an AI-invokable tool.
|
|
5
|
+
*
|
|
6
|
+
* Applying `@tool()` to a method does two things at class-definition time:
|
|
7
|
+
* 1. **Stores metadata** on the method via `Reflect.defineMetadata`, making it
|
|
8
|
+
* available for later introspection with `Reflect.getMetadata`.
|
|
9
|
+
* 2. **Registers the method** in the global {@link ToolRegistry}, so the framework
|
|
10
|
+
* can discover and dispatch it without any additional wiring.
|
|
11
|
+
*
|
|
12
|
+
* The decorator is designed to be the *only* configuration point you need:
|
|
13
|
+
* after decorating a method, its class can be passed directly to an agent and
|
|
14
|
+
* all tools will be available automatically.
|
|
15
|
+
*
|
|
16
|
+
* ### Requirements
|
|
17
|
+
* - `experimentalDecorators: true` and `emitDecoratorMetadata: true` must be
|
|
18
|
+
* enabled in `tsconfig.json`.
|
|
19
|
+
* - `reflect-metadata` must be imported once at the application entry point
|
|
20
|
+
* (or is handled by this module's top-level import).
|
|
21
|
+
*
|
|
22
|
+
* ### Warnings
|
|
23
|
+
* - If `metadata.description` is absent, the decorator applies a default description
|
|
24
|
+
* ("No description provided"), which may hurt LLM tool-selection quality. It is
|
|
25
|
+
* strongly recommended to always provide a meaningful description.
|
|
26
|
+
* - Registering two tools with the same `metadata.name` (across any class) may lead
|
|
27
|
+
* to non-deterministic model behaviour. Ensure tool names are unique globally.
|
|
28
|
+
*
|
|
29
|
+
* @param metadata - Configuration object describing the tool to the framework and
|
|
30
|
+
* to the language model. At minimum, `name` and `description`
|
|
31
|
+
* should always be provided.
|
|
32
|
+
*
|
|
33
|
+
* @returns A standard TypeScript method decorator function.
|
|
34
|
+
*
|
|
35
|
+
* @example — Basic tool
|
|
36
|
+
*
|
|
37
|
+
* import { z } from 'zod';
|
|
38
|
+
* import { tool } from './tool.decorator';
|
|
39
|
+
*
|
|
40
|
+
* class WebTools {
|
|
41
|
+
* @tool({
|
|
42
|
+
* name: 'search_web',
|
|
43
|
+
* description: 'Searches the web and returns the top results for a query.',
|
|
44
|
+
* inputSchema: z.object({ query: z.string().describe('The search query') }),
|
|
45
|
+
* outputSchema: z.array(z.string()),
|
|
46
|
+
* })
|
|
47
|
+
* async searchWeb(input: { query: string }): Promise<string[]> {
|
|
48
|
+
* // implementation
|
|
49
|
+
* }
|
|
50
|
+
* }
|
|
51
|
+
*
|
|
52
|
+
*
|
|
53
|
+
* @example — Composable tool (delegates to a sub-agent)
|
|
54
|
+
*
|
|
55
|
+
* class OrchestratorTools {
|
|
56
|
+
* @tool({
|
|
57
|
+
* name: 'run_research_agent',
|
|
58
|
+
* description: 'Runs a specialised research agent for in-depth information gathering.',
|
|
59
|
+
* inputSchema: z.object({ topic: z.string() }),
|
|
60
|
+
* isComposable: true,
|
|
61
|
+
* agentClass: ResearchAgent,
|
|
62
|
+
* maxSteps: 15,
|
|
63
|
+
* })
|
|
64
|
+
* async runResearch(input: { topic: string }) {
|
|
65
|
+
* // The framework handles delegation — this body may be empty.
|
|
66
|
+
* }
|
|
67
|
+
* }
|
|
68
|
+
*
|
|
69
|
+
*/
|
|
70
|
+
export declare function tool(metadata: ToolMetadata): (target: object, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
71
|
+
//# sourceMappingURL=tool.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.decorator.d.ts","sourceRoot":"","sources":["../../src/tools/tool.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAa,MAAM,cAAc,CAAC;AAcvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,YAAY,IAEvC,QAAQ,MAAM,EACd,aAAa,MAAM,EACnB,YAAY,kBAAkB,UAyBjC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tool = tool;
|
|
4
|
+
require("reflect-metadata");
|
|
5
|
+
const registry_1 = require("./registry");
|
|
6
|
+
/**
|
|
7
|
+
* Reflect metadata key used to store {@link ToolMetadata} on a decorated method.
|
|
8
|
+
*
|
|
9
|
+
* Scoped with a namespaced string (`typed-agents:tool`) to avoid collisions with
|
|
10
|
+
* other libraries that also use `reflect-metadata`. Kept as a module-level constant
|
|
11
|
+
* so it can be referenced both when writing and when reading the metadata.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
const TOOL_METADATA_KEY = Symbol("typed-agents:tool");
|
|
16
|
+
/**
|
|
17
|
+
* Method decorator that marks a class method as an AI-invokable tool.
|
|
18
|
+
*
|
|
19
|
+
* Applying `@tool()` to a method does two things at class-definition time:
|
|
20
|
+
* 1. **Stores metadata** on the method via `Reflect.defineMetadata`, making it
|
|
21
|
+
* available for later introspection with `Reflect.getMetadata`.
|
|
22
|
+
* 2. **Registers the method** in the global {@link ToolRegistry}, so the framework
|
|
23
|
+
* can discover and dispatch it without any additional wiring.
|
|
24
|
+
*
|
|
25
|
+
* The decorator is designed to be the *only* configuration point you need:
|
|
26
|
+
* after decorating a method, its class can be passed directly to an agent and
|
|
27
|
+
* all tools will be available automatically.
|
|
28
|
+
*
|
|
29
|
+
* ### Requirements
|
|
30
|
+
* - `experimentalDecorators: true` and `emitDecoratorMetadata: true` must be
|
|
31
|
+
* enabled in `tsconfig.json`.
|
|
32
|
+
* - `reflect-metadata` must be imported once at the application entry point
|
|
33
|
+
* (or is handled by this module's top-level import).
|
|
34
|
+
*
|
|
35
|
+
* ### Warnings
|
|
36
|
+
* - If `metadata.description` is absent, the decorator applies a default description
|
|
37
|
+
* ("No description provided"), which may hurt LLM tool-selection quality. It is
|
|
38
|
+
* strongly recommended to always provide a meaningful description.
|
|
39
|
+
* - Registering two tools with the same `metadata.name` (across any class) may lead
|
|
40
|
+
* to non-deterministic model behaviour. Ensure tool names are unique globally.
|
|
41
|
+
*
|
|
42
|
+
* @param metadata - Configuration object describing the tool to the framework and
|
|
43
|
+
* to the language model. At minimum, `name` and `description`
|
|
44
|
+
* should always be provided.
|
|
45
|
+
*
|
|
46
|
+
* @returns A standard TypeScript method decorator function.
|
|
47
|
+
*
|
|
48
|
+
* @example — Basic tool
|
|
49
|
+
*
|
|
50
|
+
* import { z } from 'zod';
|
|
51
|
+
* import { tool } from './tool.decorator';
|
|
52
|
+
*
|
|
53
|
+
* class WebTools {
|
|
54
|
+
* @tool({
|
|
55
|
+
* name: 'search_web',
|
|
56
|
+
* description: 'Searches the web and returns the top results for a query.',
|
|
57
|
+
* inputSchema: z.object({ query: z.string().describe('The search query') }),
|
|
58
|
+
* outputSchema: z.array(z.string()),
|
|
59
|
+
* })
|
|
60
|
+
* async searchWeb(input: { query: string }): Promise<string[]> {
|
|
61
|
+
* // implementation
|
|
62
|
+
* }
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
*
|
|
66
|
+
* @example — Composable tool (delegates to a sub-agent)
|
|
67
|
+
*
|
|
68
|
+
* class OrchestratorTools {
|
|
69
|
+
* @tool({
|
|
70
|
+
* name: 'run_research_agent',
|
|
71
|
+
* description: 'Runs a specialised research agent for in-depth information gathering.',
|
|
72
|
+
* inputSchema: z.object({ topic: z.string() }),
|
|
73
|
+
* isComposable: true,
|
|
74
|
+
* agentClass: ResearchAgent,
|
|
75
|
+
* maxSteps: 15,
|
|
76
|
+
* })
|
|
77
|
+
* async runResearch(input: { topic: string }) {
|
|
78
|
+
* // The framework handles delegation — this body may be empty.
|
|
79
|
+
* }
|
|
80
|
+
* }
|
|
81
|
+
*
|
|
82
|
+
*/
|
|
83
|
+
function tool(metadata) {
|
|
84
|
+
return function (target, propertyKey, descriptor) {
|
|
85
|
+
/**
|
|
86
|
+
* Resolved metadata with guaranteed defaults applied.
|
|
87
|
+
* `description` falls back to a placeholder so downstream consumers
|
|
88
|
+
* (e.g. tool-definition serialisers) never receive `undefined`.
|
|
89
|
+
*/
|
|
90
|
+
const finalMetadata = {
|
|
91
|
+
...metadata,
|
|
92
|
+
description: metadata.description ?? "No description provided",
|
|
93
|
+
};
|
|
94
|
+
Reflect.defineMetadata(TOOL_METADATA_KEY, finalMetadata, target, propertyKey);
|
|
95
|
+
registry_1.ToolRegistry.registerMethod(target.constructor, propertyKey, finalMetadata);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=tool.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.decorator.js","sourceRoot":"","sources":["../../src/tools/tool.decorator.ts"],"names":[],"mappings":";;AAkFA,oBA6BC;AA/GD,4BAA0B;AAE1B,yCAA0C;AAE1C;;;;;;;;GAQG;AACH,MAAM,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,SAAgB,IAAI,CAAC,QAAsB;IACzC,OAAO,UACL,MAAc,EACd,WAAmB,EACnB,UAA8B;QAE9B;;;;WAIG;QACH,MAAM,aAAa,GAAiB;YAClC,GAAG,QAAQ;YACX,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,yBAAyB;SAC/D,CAAC;QAEF,OAAO,CAAC,cAAc,CACpB,iBAAiB,EACjB,aAAa,EACb,MAAM,EACN,WAAW,CACZ,CAAC;QAEF,uBAAY,CAAC,cAAc,CACzB,MAAM,CAAC,WAAwB,EAC/B,WAAW,EACX,aAAa,CACd,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|