@orkestrel/tool 0.0.7 → 0.0.8
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
|
@@ -47,7 +47,11 @@ const result = await tools.execute({
|
|
|
47
47
|
name: 'add',
|
|
48
48
|
arguments: { left: 2, right: 3 },
|
|
49
49
|
})
|
|
50
|
-
|
|
50
|
+
if (result.success) {
|
|
51
|
+
result.value // 5
|
|
52
|
+
} else {
|
|
53
|
+
result.error // the failure message
|
|
54
|
+
}
|
|
51
55
|
```
|
|
52
56
|
|
|
53
57
|
Handlers may be synchronous or asynchronous. An unknown name or a thrown handler becomes an
|
package/dist/src/core/index.cjs
CHANGED
|
@@ -128,6 +128,7 @@ var ToolManager = class {
|
|
|
128
128
|
if (tool === void 0) return {
|
|
129
129
|
id: call.id,
|
|
130
130
|
name: call.name,
|
|
131
|
+
success: false,
|
|
131
132
|
error: `tool not found: ${call.name}`
|
|
132
133
|
};
|
|
133
134
|
try {
|
|
@@ -135,6 +136,7 @@ var ToolManager = class {
|
|
|
135
136
|
return {
|
|
136
137
|
id: call.id,
|
|
137
138
|
name: call.name,
|
|
139
|
+
success: true,
|
|
138
140
|
value
|
|
139
141
|
};
|
|
140
142
|
} catch (error) {
|
|
@@ -142,6 +144,7 @@ var ToolManager = class {
|
|
|
142
144
|
return {
|
|
143
145
|
id: call.id,
|
|
144
146
|
name: call.name,
|
|
147
|
+
success: false,
|
|
145
148
|
error: message.success ? message.value : "Unknown thrown value"
|
|
146
149
|
};
|
|
147
150
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["#execute","#tools","#definition","#run"],"sources":["../../../src/core/helpers.ts","../../../src/core/tools/Tool.ts","../../../src/core/tools/ToolManager.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { ToolCall } from './types.js'\nimport { holds, isRecord, isString } from '@orkestrel/contract'\n\n/**\n * Determine 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. Adversarial values return `false`.\n *\n * @param value - The value to test\n * @returns `true` when the value has the complete tool-call shape\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 * An executable tool definition bound to a handler.\n *\n * @remarks\n * Schema fields and arguments are forwarded by reference. 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: (args: Readonly<Record<string, unknown>>) => 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>>): Promise<unknown> | unknown {\n\t\treturn this.#execute(args)\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'\n\n/**\n * 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; batch execution preserves\n * input order and never fails as a whole because of an individual call.\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) => this.#definition(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 = false\n\t\t\tfor (const name of names) {\n\t\t\t\tif (this.#tools.delete(name)) removed = true\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 {
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["#execute","#tools","#definition","#run"],"sources":["../../../src/core/helpers.ts","../../../src/core/tools/Tool.ts","../../../src/core/tools/ToolManager.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { ToolCall } from './types.js'\nimport { holds, isRecord, isString } from '@orkestrel/contract'\n\n/**\n * Determine 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. Adversarial values return `false`.\n *\n * @param value - The value to test\n * @returns `true` when the value has the complete tool-call shape\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 * An executable tool definition bound to a handler.\n *\n * @remarks\n * Schema fields and arguments are forwarded by reference. 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: (args: Readonly<Record<string, unknown>>) => 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>>): Promise<unknown> | unknown {\n\t\treturn this.#execute(args)\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'\n\n/**\n * 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; batch execution preserves\n * input order and never fails as a whole because of an individual call.\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) => this.#definition(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 = false\n\t\t\tfor (const name of names) {\n\t\t\t\tif (this.#tools.delete(name)) removed = true\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 value = await tool.execute(call.arguments)\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\t#definition(tool: ToolInterface): ToolDefinition {\n\t\tconst definition: {\n\t\t\tname: string\n\t\t\tdescription?: string\n\t\t\tparameters?: Readonly<Record<string, unknown>>\n\t\t} = {\n\t\t\tname: tool.name,\n\t\t}\n\t\tconst description = tool.summary ?? tool.description\n\t\tif (description !== undefined) definition.description = description\n\t\tif (tool.parameters !== undefined) definition.parameters = tool.parameters\n\t\treturn definition\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 * Create 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 * Create 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,3 +1,6 @@
|
|
|
1
|
+
import { Failure } from '@orkestrel/contract';
|
|
2
|
+
import { Success } from '@orkestrel/contract';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Create an executable tool.
|
|
3
6
|
*
|
|
@@ -121,6 +124,22 @@ export declare interface ToolDefinition {
|
|
|
121
124
|
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
122
125
|
}
|
|
123
126
|
|
|
127
|
+
/**
|
|
128
|
+
* The failed outcome of executing a {@link ToolCall}.
|
|
129
|
+
*
|
|
130
|
+
* @remarks
|
|
131
|
+
* `error` is the failure message: an unknown tool name, an `Error`'s message, or
|
|
132
|
+
* a String-converted throw. The registry carries no further structure. An
|
|
133
|
+
* in-process caller needing a typed error calls `tools.tool(name)`, then
|
|
134
|
+
* `tool.execute(args)` in its own `try`/`catch`.
|
|
135
|
+
*/
|
|
136
|
+
export declare interface ToolFailure extends Failure<string> {
|
|
137
|
+
/** The identifier of the corresponding call. */
|
|
138
|
+
readonly id: string;
|
|
139
|
+
/** The name of the called tool. */
|
|
140
|
+
readonly name: string;
|
|
141
|
+
}
|
|
142
|
+
|
|
124
143
|
/**
|
|
125
144
|
* An executable tool: its advertised definition plus its local handler.
|
|
126
145
|
*
|
|
@@ -219,6 +238,10 @@ export declare interface ToolManagerInterface {
|
|
|
219
238
|
/**
|
|
220
239
|
* List the definitions advertised to a caller.
|
|
221
240
|
*
|
|
241
|
+
* The projected `description` is the tool's `summary` when one was authored,
|
|
242
|
+
* advertised in place of the full description. The full text stays on the tool
|
|
243
|
+
* for direct lookup.
|
|
244
|
+
*
|
|
222
245
|
* @returns A new readonly array of tool definitions
|
|
223
246
|
*/
|
|
224
247
|
definitions(): readonly ToolDefinition[];
|
|
@@ -283,17 +306,22 @@ export declare interface ToolOptions {
|
|
|
283
306
|
* The outcome of executing a {@link ToolCall}.
|
|
284
307
|
*
|
|
285
308
|
* @remarks
|
|
286
|
-
*
|
|
309
|
+
* Always a result and never a throw. Narrow on `success`.
|
|
310
|
+
*/
|
|
311
|
+
export declare type ToolResult = ToolSuccess | ToolFailure;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* The successful outcome of executing a {@link ToolCall}.
|
|
315
|
+
*
|
|
316
|
+
* @remarks
|
|
317
|
+
* `value` is whatever the handler returned — including `undefined`, `null`, `0`,
|
|
318
|
+
* `''`, or `false`. A present value never implies a meaningful one.
|
|
287
319
|
*/
|
|
288
|
-
export declare interface
|
|
320
|
+
export declare interface ToolSuccess extends Success<unknown> {
|
|
289
321
|
/** The identifier of the corresponding call. */
|
|
290
322
|
readonly id: string;
|
|
291
323
|
/** The name of the called tool. */
|
|
292
324
|
readonly name: string;
|
|
293
|
-
/** The successful return value. */
|
|
294
|
-
readonly value?: unknown;
|
|
295
|
-
/** The failure message. */
|
|
296
|
-
readonly error?: string;
|
|
297
325
|
}
|
|
298
326
|
|
|
299
327
|
export { }
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { Failure } from '@orkestrel/contract';
|
|
2
|
+
import { Success } from '@orkestrel/contract';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Create an executable tool.
|
|
3
6
|
*
|
|
@@ -121,6 +124,22 @@ export declare interface ToolDefinition {
|
|
|
121
124
|
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
122
125
|
}
|
|
123
126
|
|
|
127
|
+
/**
|
|
128
|
+
* The failed outcome of executing a {@link ToolCall}.
|
|
129
|
+
*
|
|
130
|
+
* @remarks
|
|
131
|
+
* `error` is the failure message: an unknown tool name, an `Error`'s message, or
|
|
132
|
+
* a String-converted throw. The registry carries no further structure. An
|
|
133
|
+
* in-process caller needing a typed error calls `tools.tool(name)`, then
|
|
134
|
+
* `tool.execute(args)` in its own `try`/`catch`.
|
|
135
|
+
*/
|
|
136
|
+
export declare interface ToolFailure extends Failure<string> {
|
|
137
|
+
/** The identifier of the corresponding call. */
|
|
138
|
+
readonly id: string;
|
|
139
|
+
/** The name of the called tool. */
|
|
140
|
+
readonly name: string;
|
|
141
|
+
}
|
|
142
|
+
|
|
124
143
|
/**
|
|
125
144
|
* An executable tool: its advertised definition plus its local handler.
|
|
126
145
|
*
|
|
@@ -219,6 +238,10 @@ export declare interface ToolManagerInterface {
|
|
|
219
238
|
/**
|
|
220
239
|
* List the definitions advertised to a caller.
|
|
221
240
|
*
|
|
241
|
+
* The projected `description` is the tool's `summary` when one was authored,
|
|
242
|
+
* advertised in place of the full description. The full text stays on the tool
|
|
243
|
+
* for direct lookup.
|
|
244
|
+
*
|
|
222
245
|
* @returns A new readonly array of tool definitions
|
|
223
246
|
*/
|
|
224
247
|
definitions(): readonly ToolDefinition[];
|
|
@@ -283,17 +306,22 @@ export declare interface ToolOptions {
|
|
|
283
306
|
* The outcome of executing a {@link ToolCall}.
|
|
284
307
|
*
|
|
285
308
|
* @remarks
|
|
286
|
-
*
|
|
309
|
+
* Always a result and never a throw. Narrow on `success`.
|
|
310
|
+
*/
|
|
311
|
+
export declare type ToolResult = ToolSuccess | ToolFailure;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* The successful outcome of executing a {@link ToolCall}.
|
|
315
|
+
*
|
|
316
|
+
* @remarks
|
|
317
|
+
* `value` is whatever the handler returned — including `undefined`, `null`, `0`,
|
|
318
|
+
* `''`, or `false`. A present value never implies a meaningful one.
|
|
287
319
|
*/
|
|
288
|
-
export declare interface
|
|
320
|
+
export declare interface ToolSuccess extends Success<unknown> {
|
|
289
321
|
/** The identifier of the corresponding call. */
|
|
290
322
|
readonly id: string;
|
|
291
323
|
/** The name of the called tool. */
|
|
292
324
|
readonly name: string;
|
|
293
|
-
/** The successful return value. */
|
|
294
|
-
readonly value?: unknown;
|
|
295
|
-
/** The failure message. */
|
|
296
|
-
readonly error?: string;
|
|
297
325
|
}
|
|
298
326
|
|
|
299
327
|
export { }
|
package/dist/src/core/index.js
CHANGED
|
@@ -127,6 +127,7 @@ var ToolManager = class {
|
|
|
127
127
|
if (tool === void 0) return {
|
|
128
128
|
id: call.id,
|
|
129
129
|
name: call.name,
|
|
130
|
+
success: false,
|
|
130
131
|
error: `tool not found: ${call.name}`
|
|
131
132
|
};
|
|
132
133
|
try {
|
|
@@ -134,6 +135,7 @@ var ToolManager = class {
|
|
|
134
135
|
return {
|
|
135
136
|
id: call.id,
|
|
136
137
|
name: call.name,
|
|
138
|
+
success: true,
|
|
137
139
|
value
|
|
138
140
|
};
|
|
139
141
|
} catch (error) {
|
|
@@ -141,6 +143,7 @@ var ToolManager = class {
|
|
|
141
143
|
return {
|
|
142
144
|
id: call.id,
|
|
143
145
|
name: call.name,
|
|
146
|
+
success: false,
|
|
144
147
|
error: message.success ? message.value : "Unknown thrown value"
|
|
145
148
|
};
|
|
146
149
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#execute","#tools","#definition","#run"],"sources":["../../../src/core/helpers.ts","../../../src/core/tools/Tool.ts","../../../src/core/tools/ToolManager.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { ToolCall } from './types.js'\nimport { holds, isRecord, isString } from '@orkestrel/contract'\n\n/**\n * Determine 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. Adversarial values return `false`.\n *\n * @param value - The value to test\n * @returns `true` when the value has the complete tool-call shape\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 * An executable tool definition bound to a handler.\n *\n * @remarks\n * Schema fields and arguments are forwarded by reference. 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: (args: Readonly<Record<string, unknown>>) => 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>>): Promise<unknown> | unknown {\n\t\treturn this.#execute(args)\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'\n\n/**\n * 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; batch execution preserves\n * input order and never fails as a whole because of an individual call.\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) => this.#definition(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 = false\n\t\t\tfor (const name of names) {\n\t\t\t\tif (this.#tools.delete(name)) removed = true\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 {
|
|
1
|
+
{"version":3,"file":"index.js","names":["#execute","#tools","#definition","#run"],"sources":["../../../src/core/helpers.ts","../../../src/core/tools/Tool.ts","../../../src/core/tools/ToolManager.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { ToolCall } from './types.js'\nimport { holds, isRecord, isString } from '@orkestrel/contract'\n\n/**\n * Determine 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. Adversarial values return `false`.\n *\n * @param value - The value to test\n * @returns `true` when the value has the complete tool-call shape\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 * An executable tool definition bound to a handler.\n *\n * @remarks\n * Schema fields and arguments are forwarded by reference. 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: (args: Readonly<Record<string, unknown>>) => 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>>): Promise<unknown> | unknown {\n\t\treturn this.#execute(args)\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'\n\n/**\n * 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; batch execution preserves\n * input order and never fails as a whole because of an individual call.\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) => this.#definition(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 = false\n\t\t\tfor (const name of names) {\n\t\t\t\tif (this.#tools.delete(name)) removed = true\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 value = await tool.execute(call.arguments)\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\t#definition(tool: ToolInterface): ToolDefinition {\n\t\tconst definition: {\n\t\t\tname: string\n\t\t\tdescription?: string\n\t\t\tparameters?: Readonly<Record<string, unknown>>\n\t\t} = {\n\t\t\tname: tool.name,\n\t\t}\n\t\tconst description = tool.summary ?? tool.description\n\t\tif (description !== undefined) definition.description = description\n\t\tif (tool.parameters !== undefined) definition.parameters = tool.parameters\n\t\treturn definition\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 * Create 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 * Create 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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orkestrel/tool",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "The tool runtime for the @orkestrel line — JSON-Schema tool definitions, calls, results, executable tools, and a registry with per-call error isolation. Part of the @orkestrel line.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@microsoft/api-extractor": "^7.58.12",
|
|
70
70
|
"@orkestrel/guide": "^0.0.8",
|
|
71
|
-
"@orkestrel/scaffold": "^0.0.
|
|
71
|
+
"@orkestrel/scaffold": "^0.0.13",
|
|
72
72
|
"@types/node": "^26.1.2",
|
|
73
73
|
"@vitest/browser-playwright": "^4.1.10",
|
|
74
74
|
"oxfmt": "^0.61.0",
|