@orkestrel/tool 0.0.13 → 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/README.md CHANGED
@@ -1,16 +1,14 @@
1
1
  # @orkestrel/tool
2
2
 
3
- The tool runtime for the `@orkestrel` line.
4
-
5
- A tool is a callable function described by a JSON Schema: a name, an optional description, an
6
- optional parameter schema, and the handler that runs it. That is the whole idea — a tool is an
7
- API call whose shape is data, so whoever calls it can discover it, present it, and invoke it
8
- without knowing anything about the code behind it. This package ships that shape and the
9
- registry around it: definitions to advertise, calls to dispatch, results to correlate, and
10
- per-call error isolation so one bad tool never takes down the run.
11
-
12
- Nothing here is model-specific. An agent loop, an MCP bridge, and plain application code are all
13
- callers.
3
+ > The tool runtime for the `@orkestrel` line: a `Tool` binding an advertised JSON Schema
4
+ > definition to its handler, a `ToolManager` registry that advertises those definitions and
5
+ > executes calls with per-call error isolation, and the correlated `ToolCall` and `ToolResult`
6
+ > pair that travels between a caller and the registry.
7
+
8
+ Build a tool with the `createTool` function, register it in a registry from the
9
+ `createToolManager` function, hand `definitions()` to whatever chooses the call, and pass the
10
+ call you get back to `execute`. Nothing here is model-specific an agent loop, an MCP bridge,
11
+ and plain application code are all callers.
14
12
 
15
13
  ## Install
16
14
 
@@ -1,44 +1,54 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let _orkestrel_contract = require("@orkestrel/contract");
3
- //#region src/core/helpers.ts
3
+ let _orkestrel_emitter = require("@orkestrel/emitter");
4
+ //#region src/core/errors.ts
4
5
  /**
5
- * Projects a tool onto the plain definition advertised to a caller.
6
+ * Reports a schema conflict or argument validation failure with a machine-readable code.
6
7
  *
7
- * @remarks
8
- * The projection is a fresh object carrying `name`, then `description` only when the
9
- * tool authored a summary or a description, then `parameters` only when the tool
10
- * authored a schema. An authored `summary` is advertised in place of the full
11
- * `description`, which stays on the tool for direct lookup. The parameter schema is
12
- * copied by reference and never cloned, so the definition is never a live handle on
13
- * the tool's handler.
8
+ * @example
9
+ * ```ts
10
+ * import { ToolError } from '@orkestrel/tool'
14
11
  *
15
- * @param tool - The tool to project
16
- * @returns A fresh definition carrying only the fields the tool authored
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 { Tool, toolToDefinition } from '@orkestrel/tool'
34
+ * import { ToolError, isToolError } from '@orkestrel/tool'
21
35
  *
22
- * const echo = new Tool({ name: 'echo', summary: 'Echo a value.', execute: (args) => args.value })
23
- * toolToDefinition(echo) // { name: 'echo', description: 'Echo a value.' }
36
+ * isToolError(new ToolError('ARGUMENTS', 'Invalid amount')) // true
37
+ * isToolError(new Error('Unrelated')) // false
24
38
  * ```
25
39
  */
26
- function toolToDefinition(tool) {
27
- const definition = { name: tool.name };
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
35
45
  /**
36
- * Determines whether an unknown value is structurally a {@link ToolCall}.
46
+ * Determines whether an unknown value is structurally a {@link ToolCall}, staying total
47
+ * for malformed and adversarial input.
37
48
  *
38
49
  * @remarks
39
- * This total guard accepts a plain record with string `id` and `name` fields and a
40
- * plain-record `arguments` field. Optional caller context remains opaque and is not
41
- * read or verified. Adversarial values return `false`.
50
+ * The accepted shape is a plain record with string `id` and `name` fields and a
51
+ * plain-record `arguments` field. Extra fields are not read or verified.
42
52
  *
43
53
  * @param value - The value to test
44
54
  * @returns True if the value has the complete tool-call shape; false otherwise
@@ -55,12 +65,48 @@ function isToolCall(value) {
55
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));
56
66
  }
57
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
58
101
  //#region src/core/tools/Tool.ts
59
102
  /**
60
103
  * Binds an executable tool definition to a handler.
61
104
  *
62
105
  * @remarks
63
- * Schema fields, arguments, and present caller context are forwarded by reference.
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.
64
110
  * Caller context is consumer-asserted and is not verified. Handler failures are not
65
111
  * caught here; {@link ToolManager} owns per-call error isolation.
66
112
  *
@@ -80,21 +126,47 @@ function isToolCall(value) {
80
126
  * ```
81
127
  */
82
128
  var Tool = class {
129
+ #contract;
130
+ #execute;
83
131
  name;
132
+ title;
84
133
  description;
85
134
  summary;
86
135
  parameters;
87
- #execute;
136
+ annotations;
88
137
  constructor(options) {
138
+ if (options.contract !== void 0 && options.parameters !== void 0) throw new ToolError("SCHEMA", "Choose contract or parameters, not both");
89
139
  this.name = options.name;
140
+ if (options.title !== void 0) this.title = options.title;
90
141
  if (options.description !== void 0) this.description = options.description;
91
142
  if (options.summary !== void 0) this.summary = options.summary;
92
- if (options.parameters !== void 0) this.parameters = options.parameters;
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;
93
149
  this.#execute = options.execute;
94
150
  }
95
- execute(args, caller) {
96
- if (caller === void 0) return this.#execute(args);
97
- return this.#execute(args, caller);
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);
98
170
  }
99
171
  };
100
172
  //#endregion
@@ -108,7 +180,13 @@ var Tool = class {
108
180
  * Unknown names and handler throws resolve to error results; a call whose `id` or `name`
109
181
  * accessor throws when read makes its call, and the batch holding it, reject. Batch
110
182
  * execution preserves input order and isolates each call whose members are plain
111
- * values. Optional consumer-asserted caller context is forwarded without verification.
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.
112
190
  *
113
191
  * @example
114
192
  * ```ts
@@ -125,15 +203,25 @@ var Tool = class {
125
203
  */
126
204
  var ToolManager = class {
127
205
  #tools = /* @__PURE__ */ new Map();
206
+ #emitter;
207
+ constructor(options) {
208
+ this.#emitter = new _orkestrel_emitter.Emitter(options);
209
+ }
128
210
  get count() {
129
211
  return this.#tools.size;
130
212
  }
213
+ get emitter() {
214
+ return this.#emitter;
215
+ }
131
216
  add(tools) {
132
217
  if ((0, _orkestrel_contract.isArray)(tools)) {
133
- for (const tool of tools) this.#tools.set(tool.name, tool);
218
+ for (const tool of tools) this.add(tool);
134
219
  return;
135
220
  }
221
+ const previous = this.#tools.get(tools.name);
136
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);
137
225
  }
138
226
  tool(name) {
139
227
  return this.#tools.get(name);
@@ -144,22 +232,33 @@ var ToolManager = class {
144
232
  definitions() {
145
233
  return [...this.#tools.values()].map((tool) => toolToDefinition(tool));
146
234
  }
147
- execute(call) {
148
- if ((0, _orkestrel_contract.isArray)(call)) return Promise.all(call.map((one) => this.#run(one)));
149
- 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);
150
238
  }
151
239
  remove(names) {
152
240
  if ((0, _orkestrel_contract.isArray)(names)) {
153
241
  let removed = true;
154
- for (const name of names) if (!this.#tools.delete(name)) removed = false;
242
+ for (const name of names) if (!this.remove(name)) removed = false;
155
243
  return removed;
156
244
  }
157
- return this.#tools.delete(names);
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;
158
250
  }
159
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();
160
259
  this.#tools.clear();
161
260
  }
162
- async #run(call) {
261
+ async #run(call, context) {
163
262
  const tool = this.#tools.get(call.name);
164
263
  if (tool === void 0) return {
165
264
  id: call.id,
@@ -168,8 +267,16 @@ var ToolManager = class {
168
267
  error: `tool not found: ${call.name}`
169
268
  };
170
269
  try {
171
- const caller = call.caller;
172
- const value = await (caller === void 0 ? tool.execute(call.arguments) : tool.execute(call.arguments, caller));
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);
173
280
  return {
174
281
  id: call.id,
175
282
  name: call.name,
@@ -190,19 +297,30 @@ var ToolManager = class {
190
297
  //#endregion
191
298
  //#region src/core/factories.ts
192
299
  /**
193
- * Creates an executable tool.
300
+ * Creates an executable tool bound to the supplied handler, returned as a
301
+ * `ToolInterface` so a call site holds the published contract rather than the `Tool`
302
+ * class.
194
303
  *
195
304
  * @param options - The advertised definition and execution handler
196
305
  * @returns A tool bound to the supplied handler
197
306
  *
198
- * @example
307
+ * @example Anatomy of a tool
199
308
  * ```ts
200
309
  * import { createTool } from '@orkestrel/tool'
201
310
  *
202
311
  * const add = createTool({
203
312
  * name: 'add',
204
- * description: 'Add two numbers',
205
- * execute: (args) => Number(args.a) + Number(args.b),
313
+ * description: 'Add two numeric values and return their sum. Both operands are required.',
314
+ * summary: 'Add two numbers.',
315
+ * parameters: {
316
+ * type: 'object',
317
+ * properties: {
318
+ * left: { type: 'number' },
319
+ * right: { type: 'number' },
320
+ * },
321
+ * required: ['left', 'right'],
322
+ * },
323
+ * execute: (args) => Number(args.left) + Number(args.right),
206
324
  * })
207
325
  * ```
208
326
  */
@@ -210,10 +328,12 @@ function createTool(options) {
210
328
  return new Tool(options);
211
329
  }
212
330
  /**
213
- * Creates an empty tool registry.
331
+ * Creates an empty registry that advertises definitions and executes calls with
332
+ * per-call error isolation, returned as a `ToolManagerInterface` so a caller holds the
333
+ * published contract rather than the `ToolManager` class.
214
334
  *
215
- * @returns A registry that advertises definitions and executes calls with per-call
216
- * error isolation
335
+ * @param options - The initial registry listeners and listener-error handler
336
+ * @returns A registry bound to no tools
217
337
  *
218
338
  * @example
219
339
  * ```ts
@@ -228,15 +348,17 @@ function createTool(options) {
228
348
  * })
229
349
  * ```
230
350
  */
231
- function createToolManager() {
232
- return new ToolManager();
351
+ function createToolManager(options) {
352
+ return new ToolManager(options);
233
353
  }
234
354
  //#endregion
235
355
  exports.Tool = Tool;
356
+ exports.ToolError = ToolError;
236
357
  exports.ToolManager = ToolManager;
237
358
  exports.createTool = createTool;
238
359
  exports.createToolManager = createToolManager;
239
360
  exports.isToolCall = isToolCall;
361
+ exports.isToolError = isToolError;
240
362
  exports.toolToDefinition = toolToDefinition;
241
363
 
242
364
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["#execute","#tools","#run"],"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.\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. An authored `summary` is advertised in place of the full\n * `description`, which stays on the tool for direct lookup. The parameter schema is\n * copied by reference and never cloned, so the definition is never a live handle on\n * 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}.\n *\n * @remarks\n * This total guard accepts 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. Adversarial values return `false`.\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.\n *\n * @param options - The advertised definition and execution handler\n * @returns A tool bound to the supplied handler\n *\n * @example\n * ```ts\n * import { createTool } from '@orkestrel/tool'\n *\n * const add = createTool({\n * \tname: 'add',\n * \tdescription: 'Add two numbers',\n * \texecute: (args) => Number(args.a) + Number(args.b),\n * })\n * ```\n */\nexport function createTool(options: ToolOptions): ToolInterface {\n\treturn new Tool(options)\n}\n\n/**\n * Creates an empty tool registry.\n *\n * @returns A registry that advertises definitions and executes calls with per-call\n * error isolation\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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"}