@orkestrel/tool 0.0.14 → 0.0.15
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/dist/src/core/index.cjs +149 -40
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +182 -33
- package/dist/src/core/index.d.ts +182 -33
- package/dist/src/core/index.js +149 -42
- package/dist/src/core/index.js.map +1 -1
- package/package.json +11 -10
package/dist/src/core/index.cjs
CHANGED
|
@@ -1,34 +1,44 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let _orkestrel_contract = require("@orkestrel/contract");
|
|
3
|
-
|
|
3
|
+
let _orkestrel_emitter = require("@orkestrel/emitter");
|
|
4
|
+
//#region src/core/errors.ts
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
* authored `summary` in place of the full description and carrying the parameter schema
|
|
7
|
-
* by reference.
|
|
6
|
+
* Reports a schema conflict or argument validation failure with a machine-readable code.
|
|
8
7
|
*
|
|
9
|
-
* @
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* authored a schema. The full `description` stays on the tool for direct lookup, and
|
|
13
|
-
* the definition is never a live handle on the tool's handler.
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { ToolError } from '@orkestrel/tool'
|
|
14
11
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* const error = new ToolError('SCHEMA', 'Choose contract or parameters')
|
|
13
|
+
* error.code // 'SCHEMA'
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
var ToolError = class extends Error {
|
|
17
|
+
name = "ToolError";
|
|
18
|
+
code;
|
|
19
|
+
context;
|
|
20
|
+
constructor(code, message, context) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.code = code;
|
|
23
|
+
if (context !== void 0) this.context = context;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Checks whether a value is a tool error, containing hostile prototype access.
|
|
28
|
+
*
|
|
29
|
+
* @param value - The value to test
|
|
30
|
+
* @returns True if the value is an instance of the tool error class; false otherwise
|
|
17
31
|
*
|
|
18
32
|
* @example
|
|
19
33
|
* ```ts
|
|
20
|
-
* import {
|
|
34
|
+
* import { ToolError, isToolError } from '@orkestrel/tool'
|
|
21
35
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
36
|
+
* isToolError(new ToolError('ARGUMENTS', 'Invalid amount')) // true
|
|
37
|
+
* isToolError(new Error('Unrelated')) // false
|
|
24
38
|
* ```
|
|
25
39
|
*/
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
const description = tool.summary ?? tool.description;
|
|
29
|
-
if (description !== void 0) definition.description = description;
|
|
30
|
-
if (tool.parameters !== void 0) definition.parameters = tool.parameters;
|
|
31
|
-
return definition;
|
|
40
|
+
function isToolError(value) {
|
|
41
|
+
return (0, _orkestrel_contract.isInstance)(value, ToolError);
|
|
32
42
|
}
|
|
33
43
|
//#endregion
|
|
34
44
|
//#region src/core/validators.ts
|
|
@@ -38,8 +48,7 @@ function toolToDefinition(tool) {
|
|
|
38
48
|
*
|
|
39
49
|
* @remarks
|
|
40
50
|
* The accepted shape is a plain record with string `id` and `name` fields and a
|
|
41
|
-
* plain-record `arguments` field.
|
|
42
|
-
* read or verified.
|
|
51
|
+
* plain-record `arguments` field. Extra fields are not read or verified.
|
|
43
52
|
*
|
|
44
53
|
* @param value - The value to test
|
|
45
54
|
* @returns True if the value has the complete tool-call shape; false otherwise
|
|
@@ -56,12 +65,48 @@ function isToolCall(value) {
|
|
|
56
65
|
return (0, _orkestrel_contract.holds)(() => (0, _orkestrel_contract.isRecord)(value) && (0, _orkestrel_contract.isString)(value.id) && (0, _orkestrel_contract.isString)(value.name) && (0, _orkestrel_contract.isRecord)(value.arguments));
|
|
57
66
|
}
|
|
58
67
|
//#endregion
|
|
68
|
+
//#region src/core/helpers.ts
|
|
69
|
+
/**
|
|
70
|
+
* Projects a tool onto the plain definition advertised to a caller, advertising an
|
|
71
|
+
* authored `summary` in place of the full description and carrying `parameters` and
|
|
72
|
+
* `annotations` by reference.
|
|
73
|
+
*
|
|
74
|
+
* @remarks
|
|
75
|
+
* The projection carries `name` and present `title`, `description`, `parameters`, and
|
|
76
|
+
* `annotations` fields in that order. The full `description` stays on the tool for
|
|
77
|
+
* direct lookup, and the definition is never a live handle on the tool's handler.
|
|
78
|
+
*
|
|
79
|
+
* @param tool - The tool to project
|
|
80
|
+
* @returns A fresh definition carrying only the fields the tool authored
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { Tool, toolToDefinition } from '@orkestrel/tool'
|
|
85
|
+
*
|
|
86
|
+
* const echo = new Tool({ name: 'echo', summary: 'Echo a value.', execute: (args) => args.value })
|
|
87
|
+
* toolToDefinition(echo) // { name: 'echo', description: 'Echo a value.' }
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
function toolToDefinition(tool) {
|
|
91
|
+
const description = tool.summary ?? tool.description;
|
|
92
|
+
return {
|
|
93
|
+
name: tool.name,
|
|
94
|
+
...tool.title === void 0 ? {} : { title: tool.title },
|
|
95
|
+
...description === void 0 ? {} : { description },
|
|
96
|
+
...tool.parameters === void 0 ? {} : { parameters: tool.parameters },
|
|
97
|
+
...tool.annotations === void 0 ? {} : { annotations: tool.annotations }
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
59
101
|
//#region src/core/tools/Tool.ts
|
|
60
102
|
/**
|
|
61
103
|
* Binds an executable tool definition to a handler.
|
|
62
104
|
*
|
|
63
105
|
* @remarks
|
|
64
|
-
*
|
|
106
|
+
* Advertised fields and execution context are forwarded by reference.
|
|
107
|
+
* A contract derives parameters at construction and refuses parse faults before the
|
|
108
|
+
* handler runs, then forwards the parsed arguments; without a contract, arguments
|
|
109
|
+
* retain their identity. Supplying a contract and parameters throws a schema conflict.
|
|
65
110
|
* Caller context is consumer-asserted and is not verified. Handler failures are not
|
|
66
111
|
* caught here; {@link ToolManager} owns per-call error isolation.
|
|
67
112
|
*
|
|
@@ -81,21 +126,47 @@ function isToolCall(value) {
|
|
|
81
126
|
* ```
|
|
82
127
|
*/
|
|
83
128
|
var Tool = class {
|
|
129
|
+
#contract;
|
|
130
|
+
#execute;
|
|
84
131
|
name;
|
|
132
|
+
title;
|
|
85
133
|
description;
|
|
86
134
|
summary;
|
|
87
135
|
parameters;
|
|
88
|
-
|
|
136
|
+
annotations;
|
|
89
137
|
constructor(options) {
|
|
138
|
+
if (options.contract !== void 0 && options.parameters !== void 0) throw new ToolError("SCHEMA", "Choose contract or parameters, not both");
|
|
90
139
|
this.name = options.name;
|
|
140
|
+
if (options.title !== void 0) this.title = options.title;
|
|
91
141
|
if (options.description !== void 0) this.description = options.description;
|
|
92
142
|
if (options.summary !== void 0) this.summary = options.summary;
|
|
93
|
-
if (options.
|
|
143
|
+
if (options.annotations !== void 0) this.annotations = options.annotations;
|
|
144
|
+
if (options.contract !== void 0) {
|
|
145
|
+
this.#contract = (0, _orkestrel_contract.createContract)(options.contract);
|
|
146
|
+
const parameters = (0, _orkestrel_contract.schemaToParameters)(this.#contract.schema);
|
|
147
|
+
if (parameters !== void 0) this.parameters = parameters;
|
|
148
|
+
} else if (options.parameters !== void 0) this.parameters = options.parameters;
|
|
94
149
|
this.#execute = options.execute;
|
|
95
150
|
}
|
|
96
|
-
execute(args,
|
|
97
|
-
|
|
98
|
-
|
|
151
|
+
execute(args, context) {
|
|
152
|
+
const faults = this.#contract?.explain(args) ?? [];
|
|
153
|
+
const fault = faults[0];
|
|
154
|
+
if (fault !== void 0) {
|
|
155
|
+
let message = `${(0, _orkestrel_contract.isString)(fault.path) ? fault.path : fault.path.join(".")}: ${fault.reason}`;
|
|
156
|
+
if ("expected" in fault) message += `; expected ${fault.expected}`;
|
|
157
|
+
if ("received" in fault) message += `; received ${fault.received}`;
|
|
158
|
+
if ("constraint" in fault) message += `; constraint ${fault.constraint}`;
|
|
159
|
+
if ("limit" in fault && fault.limit !== void 0) message += `; limit ${fault.limit}`;
|
|
160
|
+
if ("variants" in fault) message += `; variants ${fault.variants}`;
|
|
161
|
+
if ("matched" in fault) message += `; matched ${fault.matched}`;
|
|
162
|
+
throw new ToolError("ARGUMENTS", message, { faults });
|
|
163
|
+
}
|
|
164
|
+
if (this.#contract !== void 0) {
|
|
165
|
+
const parsed = this.#contract.parse(args);
|
|
166
|
+
if (!(0, _orkestrel_contract.isRecord)(parsed)) throw new ToolError("ARGUMENTS", "Arguments did not parse");
|
|
167
|
+
return this.#execute(parsed, context);
|
|
168
|
+
}
|
|
169
|
+
return this.#execute(args, context);
|
|
99
170
|
}
|
|
100
171
|
};
|
|
101
172
|
//#endregion
|
|
@@ -109,7 +180,13 @@ var Tool = class {
|
|
|
109
180
|
* Unknown names and handler throws resolve to error results; a call whose `id` or `name`
|
|
110
181
|
* accessor throws when read makes its call, and the batch holding it, reject. Batch
|
|
111
182
|
* execution preserves input order and isolates each call whose members are plain
|
|
112
|
-
* values.
|
|
183
|
+
* values. Execution context is shared across a batch and forwarded unchanged. An
|
|
184
|
+
* omitted context receives a non-aborted signal. A signal aborted before handler
|
|
185
|
+
* entry produces an error result; later cancellation is the handler's responsibility.
|
|
186
|
+
* Registry changes publish synchronously. Replacements publish `remove`, then `add`
|
|
187
|
+
* if the map still holds that exact replacement after the removal listeners return.
|
|
188
|
+
* Destruction clears the tools before releasing listeners. A destroyed registry
|
|
189
|
+
* publishes nothing, even when later additions update its tool map.
|
|
113
190
|
*
|
|
114
191
|
* @example
|
|
115
192
|
* ```ts
|
|
@@ -126,15 +203,25 @@ var Tool = class {
|
|
|
126
203
|
*/
|
|
127
204
|
var ToolManager = class {
|
|
128
205
|
#tools = /* @__PURE__ */ new Map();
|
|
206
|
+
#emitter;
|
|
207
|
+
constructor(options) {
|
|
208
|
+
this.#emitter = new _orkestrel_emitter.Emitter(options);
|
|
209
|
+
}
|
|
129
210
|
get count() {
|
|
130
211
|
return this.#tools.size;
|
|
131
212
|
}
|
|
213
|
+
get emitter() {
|
|
214
|
+
return this.#emitter;
|
|
215
|
+
}
|
|
132
216
|
add(tools) {
|
|
133
217
|
if ((0, _orkestrel_contract.isArray)(tools)) {
|
|
134
|
-
for (const tool of tools) this
|
|
218
|
+
for (const tool of tools) this.add(tool);
|
|
135
219
|
return;
|
|
136
220
|
}
|
|
221
|
+
const previous = this.#tools.get(tools.name);
|
|
137
222
|
this.#tools.set(tools.name, tools);
|
|
223
|
+
if (previous !== void 0) this.#emitter.emit("remove", previous);
|
|
224
|
+
if (this.#tools.get(tools.name) === tools) this.#emitter.emit("add", tools);
|
|
138
225
|
}
|
|
139
226
|
tool(name) {
|
|
140
227
|
return this.#tools.get(name);
|
|
@@ -145,22 +232,33 @@ var ToolManager = class {
|
|
|
145
232
|
definitions() {
|
|
146
233
|
return [...this.#tools.values()].map((tool) => toolToDefinition(tool));
|
|
147
234
|
}
|
|
148
|
-
execute(call) {
|
|
149
|
-
if ((0, _orkestrel_contract.isArray)(call)) return Promise.all(call.map((one) => this.#run(one)));
|
|
150
|
-
return this.#run(call);
|
|
235
|
+
execute(call, context = { signal: new AbortController().signal }) {
|
|
236
|
+
if ((0, _orkestrel_contract.isArray)(call)) return Promise.all(call.map((one) => this.#run(one, context)));
|
|
237
|
+
return this.#run(call, context);
|
|
151
238
|
}
|
|
152
239
|
remove(names) {
|
|
153
240
|
if ((0, _orkestrel_contract.isArray)(names)) {
|
|
154
241
|
let removed = true;
|
|
155
|
-
for (const name of names) if (!this
|
|
242
|
+
for (const name of names) if (!this.remove(name)) removed = false;
|
|
156
243
|
return removed;
|
|
157
244
|
}
|
|
158
|
-
|
|
245
|
+
const tool = this.#tools.get(names);
|
|
246
|
+
if (tool === void 0) return false;
|
|
247
|
+
this.#tools.delete(names);
|
|
248
|
+
this.#emitter.emit("remove", tool);
|
|
249
|
+
return true;
|
|
159
250
|
}
|
|
160
251
|
clear() {
|
|
252
|
+
const tools = this.tools();
|
|
253
|
+
this.#tools.clear();
|
|
254
|
+
this.#emitter.emit("clear", tools);
|
|
255
|
+
}
|
|
256
|
+
destroy() {
|
|
257
|
+
this.clear();
|
|
258
|
+
this.#emitter.destroy();
|
|
161
259
|
this.#tools.clear();
|
|
162
260
|
}
|
|
163
|
-
async #run(call) {
|
|
261
|
+
async #run(call, context) {
|
|
164
262
|
const tool = this.#tools.get(call.name);
|
|
165
263
|
if (tool === void 0) return {
|
|
166
264
|
id: call.id,
|
|
@@ -169,8 +267,16 @@ var ToolManager = class {
|
|
|
169
267
|
error: `tool not found: ${call.name}`
|
|
170
268
|
};
|
|
171
269
|
try {
|
|
172
|
-
|
|
173
|
-
|
|
270
|
+
if (context.signal.aborted) {
|
|
271
|
+
const reason = context.signal.reason;
|
|
272
|
+
return {
|
|
273
|
+
id: call.id,
|
|
274
|
+
name: call.name,
|
|
275
|
+
success: false,
|
|
276
|
+
error: reason === void 0 ? "aborted" : String(reason)
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const value = await tool.execute(call.arguments, context);
|
|
174
280
|
return {
|
|
175
281
|
id: call.id,
|
|
176
282
|
name: call.name,
|
|
@@ -226,6 +332,7 @@ function createTool(options) {
|
|
|
226
332
|
* per-call error isolation, returned as a `ToolManagerInterface` so a caller holds the
|
|
227
333
|
* published contract rather than the `ToolManager` class.
|
|
228
334
|
*
|
|
335
|
+
* @param options - The initial registry listeners and listener-error handler
|
|
229
336
|
* @returns A registry bound to no tools
|
|
230
337
|
*
|
|
231
338
|
* @example
|
|
@@ -241,15 +348,17 @@ function createTool(options) {
|
|
|
241
348
|
* })
|
|
242
349
|
* ```
|
|
243
350
|
*/
|
|
244
|
-
function createToolManager() {
|
|
245
|
-
return new ToolManager();
|
|
351
|
+
function createToolManager(options) {
|
|
352
|
+
return new ToolManager(options);
|
|
246
353
|
}
|
|
247
354
|
//#endregion
|
|
248
355
|
exports.Tool = Tool;
|
|
356
|
+
exports.ToolError = ToolError;
|
|
249
357
|
exports.ToolManager = ToolManager;
|
|
250
358
|
exports.createTool = createTool;
|
|
251
359
|
exports.createToolManager = createToolManager;
|
|
252
360
|
exports.isToolCall = isToolCall;
|
|
361
|
+
exports.isToolError = isToolError;
|
|
253
362
|
exports.toolToDefinition = toolToDefinition;
|
|
254
363
|
|
|
255
364
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/core/helpers.ts","../../../src/core/validators.ts","../../../src/core/tools/Tool.ts","../../../src/core/tools/ToolManager.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { ToolDefinition, ToolInterface } from './types.js'\n\n/**\n * Projects a tool onto the plain definition advertised to a caller, advertising an\n * authored `summary` in place of the full description and carrying the parameter schema\n * by reference.\n *\n * @remarks\n * The projection is a fresh object carrying `name`, then `description` only when the\n * tool authored a summary or a description, then `parameters` only when the tool\n * authored a schema. The full `description` stays on the tool for direct lookup, and\n * the definition is never a live handle on the tool's handler.\n *\n * @param tool - The tool to project\n * @returns A fresh definition carrying only the fields the tool authored\n *\n * @example\n * ```ts\n * import { Tool, toolToDefinition } from '@orkestrel/tool'\n *\n * const echo = new Tool({ name: 'echo', summary: 'Echo a value.', execute: (args) => args.value })\n * toolToDefinition(echo) // { name: 'echo', description: 'Echo a value.' }\n * ```\n */\nexport function toolToDefinition(tool: ToolInterface): ToolDefinition {\n\tconst definition: {\n\t\tname: string\n\t\tdescription?: string\n\t\tparameters?: Readonly<Record<string, unknown>>\n\t} = {\n\t\tname: tool.name,\n\t}\n\tconst description = tool.summary ?? tool.description\n\tif (description !== undefined) definition.description = description\n\tif (tool.parameters !== undefined) definition.parameters = tool.parameters\n\treturn definition\n}\n","import type { ToolCall } from './types.js'\nimport { holds, isRecord, isString } from '@orkestrel/contract'\n\n/**\n * Determines whether an unknown value is structurally a {@link ToolCall}, staying total\n * for malformed and adversarial input.\n *\n * @remarks\n * The accepted shape is a plain record with string `id` and `name` fields and a\n * plain-record `arguments` field. Optional caller context remains opaque and is not\n * read or verified.\n *\n * @param value - The value to test\n * @returns True if the value has the complete tool-call shape; false otherwise\n *\n * @example\n * ```ts\n * import { isToolCall } from '@orkestrel/tool'\n *\n * isToolCall({ id: '1', name: 'search', arguments: { query: 'birds' } }) // true\n * isToolCall({ id: '1', name: 'search', arguments: [] }) // false\n * ```\n */\nexport function isToolCall(value: unknown): value is ToolCall {\n\treturn holds(\n\t\t() =>\n\t\t\tisRecord(value) && isString(value.id) && isString(value.name) && isRecord(value.arguments),\n\t)\n}\n","import type { ToolInterface, ToolOptions } from '../types.js'\n\n/**\n * Binds an executable tool definition to a handler.\n *\n * @remarks\n * Schema fields, arguments, and present caller context are forwarded by reference.\n * Caller context is consumer-asserted and is not verified. Handler failures are not\n * caught here; {@link ToolManager} owns per-call error isolation.\n *\n * @example\n * ```ts\n * import { Tool } from '@orkestrel/tool'\n *\n * const tool = new Tool({\n * \tname: 'add',\n * \tdescription: 'Add two numbers',\n * \tparameters: {\n * \t\ttype: 'object',\n * \t\tproperties: { a: { type: 'number' }, b: { type: 'number' } },\n * \t},\n * \texecute: (args) => Number(args.a) + Number(args.b),\n * })\n * ```\n */\nexport class Tool implements ToolInterface {\n\treadonly name: string\n\treadonly description?: string\n\treadonly summary?: string\n\treadonly parameters?: Readonly<Record<string, unknown>>\n\treadonly #execute: (\n\t\targs: Readonly<Record<string, unknown>>,\n\t\tcaller?: unknown,\n\t) => Promise<unknown> | unknown\n\n\tconstructor(options: ToolOptions) {\n\t\tthis.name = options.name\n\t\tif (options.description !== undefined) this.description = options.description\n\t\tif (options.summary !== undefined) this.summary = options.summary\n\t\tif (options.parameters !== undefined) this.parameters = options.parameters\n\t\tthis.#execute = options.execute\n\t}\n\n\texecute(args: Readonly<Record<string, unknown>>, caller?: unknown): Promise<unknown> | unknown {\n\t\tif (caller === undefined) return this.#execute(args)\n\t\treturn this.#execute(args, caller)\n\t}\n}\n","import type {\n\tToolCall,\n\tToolDefinition,\n\tToolInterface,\n\tToolManagerInterface,\n\tToolResult,\n} from '../types.js'\nimport { attempt, isArray } from '@orkestrel/contract'\nimport { toolToDefinition } from '../helpers.js'\n\n/**\n * Represents an insertion-ordered tool registry with per-call error isolation.\n *\n * @remarks\n * A repeated name overwrites the registered tool without changing its insertion\n * position. Definitions advertise `summary` in place of `description` when present.\n * Unknown names and handler throws resolve to error results; a call whose `id` or `name`\n * accessor throws when read makes its call, and the batch holding it, reject. Batch\n * execution preserves input order and isolates each call whose members are plain\n * values. Optional consumer-asserted caller context is forwarded without verification.\n *\n * @example\n * ```ts\n * import { Tool, ToolManager } from '@orkestrel/tool'\n *\n * const tools = new ToolManager()\n * tools.add(new Tool({ name: 'add', execute: (args) => Number(args.x) + Number(args.y) }))\n * const result = await tools.execute({\n * \tid: '1',\n * \tname: 'add',\n * \targuments: { x: 1, y: 2 },\n * })\n * ```\n */\nexport class ToolManager implements ToolManagerInterface {\n\treadonly #tools = new Map<string, ToolInterface>()\n\n\tget count(): number {\n\t\treturn this.#tools.size\n\t}\n\n\tadd(tool: ToolInterface): void\n\tadd(tools: readonly ToolInterface[]): void\n\tadd(tools: ToolInterface | readonly ToolInterface[]): void {\n\t\tif (isArray(tools)) {\n\t\t\tfor (const tool of tools) this.#tools.set(tool.name, tool)\n\t\t\treturn\n\t\t}\n\t\tthis.#tools.set(tools.name, tools)\n\t}\n\n\ttool(name: string): ToolInterface | undefined {\n\t\treturn this.#tools.get(name)\n\t}\n\n\ttools(): readonly ToolInterface[] {\n\t\treturn [...this.#tools.values()]\n\t}\n\n\tdefinitions(): readonly ToolDefinition[] {\n\t\treturn [...this.#tools.values()].map((tool) => toolToDefinition(tool))\n\t}\n\n\texecute(call: ToolCall): Promise<ToolResult>\n\texecute(calls: readonly ToolCall[]): Promise<readonly ToolResult[]>\n\texecute(call: ToolCall | readonly ToolCall[]): Promise<ToolResult | readonly ToolResult[]> {\n\t\tif (isArray(call)) return Promise.all(call.map((one) => this.#run(one)))\n\t\treturn this.#run(call)\n\t}\n\n\tremove(name: string): boolean\n\tremove(names: readonly string[]): boolean\n\tremove(names: string | readonly string[]): boolean {\n\t\tif (isArray(names)) {\n\t\t\tlet removed = true\n\t\t\tfor (const name of names) {\n\t\t\t\tif (!this.#tools.delete(name)) removed = false\n\t\t\t}\n\t\t\treturn removed\n\t\t}\n\t\treturn this.#tools.delete(names)\n\t}\n\n\tclear(): void {\n\t\tthis.#tools.clear()\n\t}\n\n\tasync #run(call: ToolCall): Promise<ToolResult> {\n\t\tconst tool = this.#tools.get(call.name)\n\t\tif (tool === undefined) {\n\t\t\treturn {\n\t\t\t\tid: call.id,\n\t\t\t\tname: call.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `tool not found: ${call.name}`,\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\tconst caller = call.caller\n\t\t\tconst value = await (caller === undefined\n\t\t\t\t? tool.execute(call.arguments)\n\t\t\t\t: tool.execute(call.arguments, caller))\n\t\t\treturn { id: call.id, name: call.name, success: true, value }\n\t\t} catch (error) {\n\t\t\tconst message = attempt(() =>\n\t\t\t\terror instanceof Error ? String(error.message) : String(error),\n\t\t\t)\n\t\t\treturn {\n\t\t\t\tid: call.id,\n\t\t\t\tname: call.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: message.success ? message.value : 'Unknown thrown value',\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { ToolInterface, ToolManagerInterface, ToolOptions } from './types.js'\nimport { Tool } from './tools/Tool.js'\nimport { ToolManager } from './tools/ToolManager.js'\n\n/**\n * Creates an executable tool bound to the supplied handler, returned as a\n * `ToolInterface` so a call site holds the published contract rather than the `Tool`\n * class.\n *\n * @param options - The advertised definition and execution handler\n * @returns A tool bound to the supplied handler\n *\n * @example Anatomy of a tool\n * ```ts\n * import { createTool } from '@orkestrel/tool'\n *\n * const add = createTool({\n * \tname: 'add',\n * \tdescription: 'Add two numeric values and return their sum. Both operands are required.',\n * \tsummary: 'Add two numbers.',\n * \tparameters: {\n * \t\ttype: 'object',\n * \t\tproperties: {\n * \t\t\tleft: { type: 'number' },\n * \t\t\tright: { type: 'number' },\n * \t\t},\n * \t\trequired: ['left', 'right'],\n * \t},\n * \texecute: (args) => Number(args.left) + Number(args.right),\n * })\n * ```\n */\nexport function createTool(options: ToolOptions): ToolInterface {\n\treturn new Tool(options)\n}\n\n/**\n * Creates an empty registry that advertises definitions and executes calls with\n * per-call error isolation, returned as a `ToolManagerInterface` so a caller holds the\n * published contract rather than the `ToolManager` class.\n *\n * @returns A registry bound to no tools\n *\n * @example\n * ```ts\n * import { createTool, createToolManager } from '@orkestrel/tool'\n *\n * const tools = createToolManager()\n * tools.add(createTool({ name: 'echo', execute: (args) => args.value }))\n * const result = await tools.execute({\n * \tid: '1',\n * \tname: 'echo',\n * \targuments: { value: 'hello' },\n * })\n * ```\n */\nexport function createToolManager(): ToolManagerInterface {\n\treturn new ToolManager()\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/core/errors.ts","../../../src/core/validators.ts","../../../src/core/helpers.ts","../../../src/core/tools/Tool.ts","../../../src/core/tools/ToolManager.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { ToolErrorCode, ToolErrorContext } from './types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n/**\n * Reports a schema conflict or argument validation failure with a machine-readable code.\n *\n * @example\n * ```ts\n * import { ToolError } from '@orkestrel/tool'\n *\n * const error = new ToolError('SCHEMA', 'Choose contract or parameters')\n * error.code // 'SCHEMA'\n * ```\n */\nexport class ToolError extends Error {\n\toverride readonly name = 'ToolError' as const\n\treadonly code: ToolErrorCode\n\treadonly context?: ToolErrorContext\n\n\tconstructor(code: ToolErrorCode, message: string, context?: ToolErrorContext) {\n\t\tsuper(message)\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Checks whether a value is a tool error, containing hostile prototype access.\n *\n * @param value - The value to test\n * @returns True if the value is an instance of the tool error class; false otherwise\n *\n * @example\n * ```ts\n * import { ToolError, isToolError } from '@orkestrel/tool'\n *\n * isToolError(new ToolError('ARGUMENTS', 'Invalid amount')) // true\n * isToolError(new Error('Unrelated')) // false\n * ```\n */\nexport function isToolError(value: unknown): value is ToolError {\n\treturn isInstance(value, ToolError)\n}\n","import type { ToolCall } from './types.js'\nimport { holds, isRecord, isString } from '@orkestrel/contract'\n\n/**\n * Determines whether an unknown value is structurally a {@link ToolCall}, staying total\n * for malformed and adversarial input.\n *\n * @remarks\n * The accepted shape is a plain record with string `id` and `name` fields and a\n * plain-record `arguments` field. Extra fields are not read or verified.\n *\n * @param value - The value to test\n * @returns True if the value has the complete tool-call shape; false otherwise\n *\n * @example\n * ```ts\n * import { isToolCall } from '@orkestrel/tool'\n *\n * isToolCall({ id: '1', name: 'search', arguments: { query: 'birds' } }) // true\n * isToolCall({ id: '1', name: 'search', arguments: [] }) // false\n * ```\n */\nexport function isToolCall(value: unknown): value is ToolCall {\n\treturn holds(\n\t\t() =>\n\t\t\tisRecord(value) && isString(value.id) && isString(value.name) && isRecord(value.arguments),\n\t)\n}\n","import type { ToolDefinition, ToolInterface } from './types.js'\n\n/**\n * Projects a tool onto the plain definition advertised to a caller, advertising an\n * authored `summary` in place of the full description and carrying `parameters` and\n * `annotations` by reference.\n *\n * @remarks\n * The projection carries `name` and present `title`, `description`, `parameters`, and\n * `annotations` fields in that order. The full `description` stays on the tool for\n * direct lookup, and the definition is never a live handle on the tool's handler.\n *\n * @param tool - The tool to project\n * @returns A fresh definition carrying only the fields the tool authored\n *\n * @example\n * ```ts\n * import { Tool, toolToDefinition } from '@orkestrel/tool'\n *\n * const echo = new Tool({ name: 'echo', summary: 'Echo a value.', execute: (args) => args.value })\n * toolToDefinition(echo) // { name: 'echo', description: 'Echo a value.' }\n * ```\n */\nexport function toolToDefinition(tool: ToolInterface): ToolDefinition {\n\tconst description = tool.summary ?? tool.description\n\treturn {\n\t\tname: tool.name,\n\t\t...(tool.title === undefined ? {} : { title: tool.title }),\n\t\t...(description === undefined ? {} : { description }),\n\t\t...(tool.parameters === undefined ? {} : { parameters: tool.parameters }),\n\t\t...(tool.annotations === undefined ? {} : { annotations: tool.annotations }),\n\t}\n}\n","import type { ContractInterface } from '@orkestrel/contract'\nimport type { ToolAnnotations, ToolContext, ToolInterface, ToolOptions } from '../types.js'\nimport { createContract, isRecord, isString, schemaToParameters } from '@orkestrel/contract'\nimport { ToolError } from '../errors.js'\n\n/**\n * Binds an executable tool definition to a handler.\n *\n * @remarks\n * Advertised fields and execution context are forwarded by reference.\n * A contract derives parameters at construction and refuses parse faults before the\n * handler runs, then forwards the parsed arguments; without a contract, arguments\n * retain their identity. Supplying a contract and parameters throws a schema conflict.\n * Caller context is consumer-asserted and is not verified. Handler failures are not\n * caught here; {@link ToolManager} owns per-call error isolation.\n *\n * @example\n * ```ts\n * import { Tool } from '@orkestrel/tool'\n *\n * const tool = new Tool({\n * \tname: 'add',\n * \tdescription: 'Add two numbers',\n * \tparameters: {\n * \t\ttype: 'object',\n * \t\tproperties: { a: { type: 'number' }, b: { type: 'number' } },\n * \t},\n * \texecute: (args) => Number(args.a) + Number(args.b),\n * })\n * ```\n */\nexport class Tool implements ToolInterface {\n\treadonly #contract?: ContractInterface<unknown>\n\treadonly #execute: ToolOptions['execute']\n\n\treadonly name: string\n\treadonly title?: string\n\treadonly description?: string\n\treadonly summary?: string\n\treadonly parameters?: Readonly<Record<string, unknown>>\n\treadonly annotations?: ToolAnnotations\n\n\tconstructor(options: ToolOptions) {\n\t\tif (options.contract !== undefined && options.parameters !== undefined) {\n\t\t\tthrow new ToolError('SCHEMA', 'Choose contract or parameters, not both')\n\t\t}\n\t\tthis.name = options.name\n\t\tif (options.title !== undefined) this.title = options.title\n\t\tif (options.description !== undefined) this.description = options.description\n\t\tif (options.summary !== undefined) this.summary = options.summary\n\t\tif (options.annotations !== undefined) this.annotations = options.annotations\n\t\tif (options.contract !== undefined) {\n\t\t\tthis.#contract = createContract(options.contract)\n\t\t\tconst parameters = schemaToParameters(this.#contract.schema)\n\t\t\tif (parameters !== undefined) this.parameters = parameters\n\t\t} else if (options.parameters !== undefined) this.parameters = options.parameters\n\t\tthis.#execute = options.execute\n\t}\n\n\texecute(\n\t\targs: Readonly<Record<string, unknown>>,\n\t\tcontext: ToolContext,\n\t): Promise<unknown> | unknown {\n\t\tconst faults = this.#contract?.explain(args) ?? []\n\t\tconst fault = faults[0]\n\t\tif (fault !== undefined) {\n\t\t\tconst path = isString(fault.path) ? fault.path : fault.path.join('.')\n\t\t\tlet message = `${path}: ${fault.reason}`\n\t\t\tif ('expected' in fault) message += `; expected ${fault.expected}`\n\t\t\tif ('received' in fault) message += `; received ${fault.received}`\n\t\t\tif ('constraint' in fault) message += `; constraint ${fault.constraint}`\n\t\t\tif ('limit' in fault && fault.limit !== undefined) message += `; limit ${fault.limit}`\n\t\t\tif ('variants' in fault) message += `; variants ${fault.variants}`\n\t\t\tif ('matched' in fault) message += `; matched ${fault.matched}`\n\t\t\tthrow new ToolError('ARGUMENTS', message, { faults })\n\t\t}\n\t\tif (this.#contract !== undefined) {\n\t\t\tconst parsed = this.#contract.parse(args)\n\t\t\tif (!isRecord(parsed)) throw new ToolError('ARGUMENTS', 'Arguments did not parse')\n\t\t\treturn this.#execute(parsed, context)\n\t\t}\n\t\treturn this.#execute(args, context)\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tToolCall,\n\tToolContext,\n\tToolDefinition,\n\tToolInterface,\n\tToolManagerEventMap,\n\tToolManagerInterface,\n\tToolManagerOptions,\n\tToolResult,\n} from '../types.js'\nimport { attempt, isArray } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { toolToDefinition } from '../helpers.js'\n\n/**\n * Represents an insertion-ordered tool registry with per-call error isolation.\n *\n * @remarks\n * A repeated name overwrites the registered tool without changing its insertion\n * position. Definitions advertise `summary` in place of `description` when present.\n * Unknown names and handler throws resolve to error results; a call whose `id` or `name`\n * accessor throws when read makes its call, and the batch holding it, reject. Batch\n * execution preserves input order and isolates each call whose members are plain\n * values. Execution context is shared across a batch and forwarded unchanged. An\n * omitted context receives a non-aborted signal. A signal aborted before handler\n * entry produces an error result; later cancellation is the handler's responsibility.\n * Registry changes publish synchronously. Replacements publish `remove`, then `add`\n * if the map still holds that exact replacement after the removal listeners return.\n * Destruction clears the tools before releasing listeners. A destroyed registry\n * publishes nothing, even when later additions update its tool map.\n *\n * @example\n * ```ts\n * import { Tool, ToolManager } from '@orkestrel/tool'\n *\n * const tools = new ToolManager()\n * tools.add(new Tool({ name: 'add', execute: (args) => Number(args.x) + Number(args.y) }))\n * const result = await tools.execute({\n * \tid: '1',\n * \tname: 'add',\n * \targuments: { x: 1, y: 2 },\n * })\n * ```\n */\nexport class ToolManager implements ToolManagerInterface {\n\treadonly #tools = new Map<string, ToolInterface>()\n\treadonly #emitter: Emitter<ToolManagerEventMap>\n\n\tconstructor(options?: ToolManagerOptions) {\n\t\tthis.#emitter = new Emitter<ToolManagerEventMap>(options)\n\t}\n\n\tget count(): number {\n\t\treturn this.#tools.size\n\t}\n\n\tget emitter(): EmitterInterface<ToolManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tadd(tool: ToolInterface): void\n\tadd(tools: readonly ToolInterface[]): void\n\tadd(tools: ToolInterface | readonly ToolInterface[]): void {\n\t\tif (isArray(tools)) {\n\t\t\tfor (const tool of tools) this.add(tool)\n\t\t\treturn\n\t\t}\n\t\tconst previous = this.#tools.get(tools.name)\n\t\tthis.#tools.set(tools.name, tools)\n\t\tif (previous !== undefined) this.#emitter.emit('remove', previous)\n\t\tif (this.#tools.get(tools.name) === tools) this.#emitter.emit('add', tools)\n\t}\n\n\ttool(name: string): ToolInterface | undefined {\n\t\treturn this.#tools.get(name)\n\t}\n\n\ttools(): readonly ToolInterface[] {\n\t\treturn [...this.#tools.values()]\n\t}\n\n\tdefinitions(): readonly ToolDefinition[] {\n\t\treturn [...this.#tools.values()].map((tool) => toolToDefinition(tool))\n\t}\n\n\texecute(call: ToolCall, context?: ToolContext): Promise<ToolResult>\n\texecute(calls: readonly ToolCall[], context?: ToolContext): Promise<readonly ToolResult[]>\n\texecute(\n\t\tcall: ToolCall | readonly ToolCall[],\n\t\tcontext: ToolContext = { signal: new AbortController().signal },\n\t): Promise<ToolResult | readonly ToolResult[]> {\n\t\tif (isArray(call)) return Promise.all(call.map((one) => this.#run(one, context)))\n\t\treturn this.#run(call, context)\n\t}\n\n\tremove(name: string): boolean\n\tremove(names: readonly string[]): boolean\n\tremove(names: string | readonly string[]): boolean {\n\t\tif (isArray(names)) {\n\t\t\tlet removed = true\n\t\t\tfor (const name of names) {\n\t\t\t\tif (!this.remove(name)) removed = false\n\t\t\t}\n\t\t\treturn removed\n\t\t}\n\t\tconst tool = this.#tools.get(names)\n\t\tif (tool === undefined) return false\n\t\tthis.#tools.delete(names)\n\t\tthis.#emitter.emit('remove', tool)\n\t\treturn true\n\t}\n\n\tclear(): void {\n\t\tconst tools = this.tools()\n\t\tthis.#tools.clear()\n\t\tthis.#emitter.emit('clear', tools)\n\t}\n\n\tdestroy(): void {\n\t\tthis.clear()\n\t\tthis.#emitter.destroy()\n\t\tthis.#tools.clear()\n\t}\n\n\tasync #run(call: ToolCall, context: ToolContext): Promise<ToolResult> {\n\t\tconst tool = this.#tools.get(call.name)\n\t\tif (tool === undefined) {\n\t\t\treturn {\n\t\t\t\tid: call.id,\n\t\t\t\tname: call.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `tool not found: ${call.name}`,\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\tif (context.signal.aborted) {\n\t\t\t\tconst reason: unknown = context.signal.reason\n\t\t\t\treturn {\n\t\t\t\t\tid: call.id,\n\t\t\t\t\tname: call.name,\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: reason === undefined ? 'aborted' : String(reason),\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst value = await tool.execute(call.arguments, context)\n\t\t\treturn { id: call.id, name: call.name, success: true, value }\n\t\t} catch (error) {\n\t\t\tconst message = attempt(() =>\n\t\t\t\terror instanceof Error ? String(error.message) : String(error),\n\t\t\t)\n\t\t\treturn {\n\t\t\t\tid: call.id,\n\t\t\t\tname: call.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: message.success ? message.value : 'Unknown thrown value',\n\t\t\t}\n\t\t}\n\t}\n}\n","import type {\n\tToolInterface,\n\tToolManagerInterface,\n\tToolManagerOptions,\n\tToolOptions,\n} from './types.js'\nimport { Tool } from './tools/Tool.js'\nimport { ToolManager } from './tools/ToolManager.js'\n\n/**\n * Creates an executable tool bound to the supplied handler, returned as a\n * `ToolInterface` so a call site holds the published contract rather than the `Tool`\n * class.\n *\n * @param options - The advertised definition and execution handler\n * @returns A tool bound to the supplied handler\n *\n * @example Anatomy of a tool\n * ```ts\n * import { createTool } from '@orkestrel/tool'\n *\n * const add = createTool({\n * \tname: 'add',\n * \tdescription: 'Add two numeric values and return their sum. Both operands are required.',\n * \tsummary: 'Add two numbers.',\n * \tparameters: {\n * \t\ttype: 'object',\n * \t\tproperties: {\n * \t\t\tleft: { type: 'number' },\n * \t\t\tright: { type: 'number' },\n * \t\t},\n * \t\trequired: ['left', 'right'],\n * \t},\n * \texecute: (args) => Number(args.left) + Number(args.right),\n * })\n * ```\n */\nexport function createTool(options: ToolOptions): ToolInterface {\n\treturn new Tool(options)\n}\n\n/**\n * Creates an empty registry that advertises definitions and executes calls with\n * per-call error isolation, returned as a `ToolManagerInterface` so a caller holds the\n * published contract rather than the `ToolManager` class.\n *\n * @param options - The initial registry listeners and listener-error handler\n * @returns A registry bound to no tools\n *\n * @example\n * ```ts\n * import { createTool, createToolManager } from '@orkestrel/tool'\n *\n * const tools = createToolManager()\n * tools.add(createTool({ name: 'echo', execute: (args) => args.value }))\n * const result = await tools.execute({\n * \tid: '1',\n * \tname: 'echo',\n * \targuments: { value: 'hello' },\n * })\n * ```\n */\nexport function createToolManager(options?: ToolManagerOptions): ToolManagerInterface {\n\treturn new ToolManager(options)\n}\n"],"mappings":"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"}
|