@orkestrel/tool 0.0.12 → 0.0.14
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 +9 -11
- package/dist/src/core/index.cjs +65 -26
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +111 -62
- package/dist/src/core/index.d.ts +111 -62
- package/dist/src/core/index.js +65 -27
- package/dist/src/core/index.js.map +1 -1
- package/package.json +18 -15
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# @orkestrel/tool
|
|
2
2
|
|
|
3
|
-
The tool runtime for the `@orkestrel` line
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Nothing here is model-specific. An agent loop, an MCP bridge, and plain application code are all
|
|
13
|
-
just 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
|
|
package/dist/src/core/index.cjs
CHANGED
|
@@ -1,16 +1,48 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let _orkestrel_contract = require("@orkestrel/contract");
|
|
3
|
+
//#region src/core/helpers.ts
|
|
4
|
+
/**
|
|
5
|
+
* Projects a tool onto the plain definition advertised to a caller, advertising an
|
|
6
|
+
* authored `summary` in place of the full description and carrying the parameter schema
|
|
7
|
+
* by reference.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* The projection is a fresh object carrying `name`, then `description` only when the
|
|
11
|
+
* tool authored a summary or a description, then `parameters` only when the tool
|
|
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.
|
|
14
|
+
*
|
|
15
|
+
* @param tool - The tool to project
|
|
16
|
+
* @returns A fresh definition carrying only the fields the tool authored
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { Tool, toolToDefinition } from '@orkestrel/tool'
|
|
21
|
+
*
|
|
22
|
+
* const echo = new Tool({ name: 'echo', summary: 'Echo a value.', execute: (args) => args.value })
|
|
23
|
+
* toolToDefinition(echo) // { name: 'echo', description: 'Echo a value.' }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
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;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
3
34
|
//#region src/core/validators.ts
|
|
4
35
|
/**
|
|
5
|
-
*
|
|
36
|
+
* Determines whether an unknown value is structurally a {@link ToolCall}, staying total
|
|
37
|
+
* for malformed and adversarial input.
|
|
6
38
|
*
|
|
7
39
|
* @remarks
|
|
8
|
-
*
|
|
40
|
+
* The accepted shape is a plain record with string `id` and `name` fields and a
|
|
9
41
|
* plain-record `arguments` field. Optional caller context remains opaque and is not
|
|
10
|
-
* read or verified.
|
|
42
|
+
* read or verified.
|
|
11
43
|
*
|
|
12
44
|
* @param value - The value to test
|
|
13
|
-
* @returns
|
|
45
|
+
* @returns True if the value has the complete tool-call shape; false otherwise
|
|
14
46
|
*
|
|
15
47
|
* @example
|
|
16
48
|
* ```ts
|
|
@@ -26,7 +58,7 @@ function isToolCall(value) {
|
|
|
26
58
|
//#endregion
|
|
27
59
|
//#region src/core/tools/Tool.ts
|
|
28
60
|
/**
|
|
29
|
-
*
|
|
61
|
+
* Binds an executable tool definition to a handler.
|
|
30
62
|
*
|
|
31
63
|
* @remarks
|
|
32
64
|
* Schema fields, arguments, and present caller context are forwarded by reference.
|
|
@@ -69,14 +101,15 @@ var Tool = class {
|
|
|
69
101
|
//#endregion
|
|
70
102
|
//#region src/core/tools/ToolManager.ts
|
|
71
103
|
/**
|
|
72
|
-
*
|
|
104
|
+
* Represents an insertion-ordered tool registry with per-call error isolation.
|
|
73
105
|
*
|
|
74
106
|
* @remarks
|
|
75
107
|
* A repeated name overwrites the registered tool without changing its insertion
|
|
76
108
|
* position. Definitions advertise `summary` in place of `description` when present.
|
|
77
|
-
* Unknown names and handler throws resolve to error results;
|
|
78
|
-
*
|
|
79
|
-
*
|
|
109
|
+
* Unknown names and handler throws resolve to error results; a call whose `id` or `name`
|
|
110
|
+
* accessor throws when read makes its call, and the batch holding it, reject. Batch
|
|
111
|
+
* execution preserves input order and isolates each call whose members are plain
|
|
112
|
+
* values. Optional consumer-asserted caller context is forwarded without verification.
|
|
80
113
|
*
|
|
81
114
|
* @example
|
|
82
115
|
* ```ts
|
|
@@ -110,7 +143,7 @@ var ToolManager = class {
|
|
|
110
143
|
return [...this.#tools.values()];
|
|
111
144
|
}
|
|
112
145
|
definitions() {
|
|
113
|
-
return [...this.#tools.values()].map((tool) =>
|
|
146
|
+
return [...this.#tools.values()].map((tool) => toolToDefinition(tool));
|
|
114
147
|
}
|
|
115
148
|
execute(call) {
|
|
116
149
|
if ((0, _orkestrel_contract.isArray)(call)) return Promise.all(call.map((one) => this.#run(one)));
|
|
@@ -118,8 +151,8 @@ var ToolManager = class {
|
|
|
118
151
|
}
|
|
119
152
|
remove(names) {
|
|
120
153
|
if ((0, _orkestrel_contract.isArray)(names)) {
|
|
121
|
-
let removed =
|
|
122
|
-
for (const name of names) if (this.#tools.delete(name)) removed =
|
|
154
|
+
let removed = true;
|
|
155
|
+
for (const name of names) if (!this.#tools.delete(name)) removed = false;
|
|
123
156
|
return removed;
|
|
124
157
|
}
|
|
125
158
|
return this.#tools.delete(names);
|
|
@@ -154,30 +187,34 @@ var ToolManager = class {
|
|
|
154
187
|
};
|
|
155
188
|
}
|
|
156
189
|
}
|
|
157
|
-
#definition(tool) {
|
|
158
|
-
const definition = { name: tool.name };
|
|
159
|
-
const description = tool.summary ?? tool.description;
|
|
160
|
-
if (description !== void 0) definition.description = description;
|
|
161
|
-
if (tool.parameters !== void 0) definition.parameters = tool.parameters;
|
|
162
|
-
return definition;
|
|
163
|
-
}
|
|
164
190
|
};
|
|
165
191
|
//#endregion
|
|
166
192
|
//#region src/core/factories.ts
|
|
167
193
|
/**
|
|
168
|
-
*
|
|
194
|
+
* Creates an executable tool bound to the supplied handler, returned as a
|
|
195
|
+
* `ToolInterface` so a call site holds the published contract rather than the `Tool`
|
|
196
|
+
* class.
|
|
169
197
|
*
|
|
170
198
|
* @param options - The advertised definition and execution handler
|
|
171
199
|
* @returns A tool bound to the supplied handler
|
|
172
200
|
*
|
|
173
|
-
* @example
|
|
201
|
+
* @example Anatomy of a tool
|
|
174
202
|
* ```ts
|
|
175
203
|
* import { createTool } from '@orkestrel/tool'
|
|
176
204
|
*
|
|
177
205
|
* const add = createTool({
|
|
178
206
|
* name: 'add',
|
|
179
|
-
* description: 'Add two
|
|
180
|
-
*
|
|
207
|
+
* description: 'Add two numeric values and return their sum. Both operands are required.',
|
|
208
|
+
* summary: 'Add two numbers.',
|
|
209
|
+
* parameters: {
|
|
210
|
+
* type: 'object',
|
|
211
|
+
* properties: {
|
|
212
|
+
* left: { type: 'number' },
|
|
213
|
+
* right: { type: 'number' },
|
|
214
|
+
* },
|
|
215
|
+
* required: ['left', 'right'],
|
|
216
|
+
* },
|
|
217
|
+
* execute: (args) => Number(args.left) + Number(args.right),
|
|
181
218
|
* })
|
|
182
219
|
* ```
|
|
183
220
|
*/
|
|
@@ -185,10 +222,11 @@ function createTool(options) {
|
|
|
185
222
|
return new Tool(options);
|
|
186
223
|
}
|
|
187
224
|
/**
|
|
188
|
-
*
|
|
225
|
+
* Creates an empty registry that advertises definitions and executes calls with
|
|
226
|
+
* per-call error isolation, returned as a `ToolManagerInterface` so a caller holds the
|
|
227
|
+
* published contract rather than the `ToolManager` class.
|
|
189
228
|
*
|
|
190
|
-
* @returns A registry
|
|
191
|
-
* error isolation
|
|
229
|
+
* @returns A registry bound to no tools
|
|
192
230
|
*
|
|
193
231
|
* @example
|
|
194
232
|
* ```ts
|
|
@@ -212,5 +250,6 @@ exports.ToolManager = ToolManager;
|
|
|
212
250
|
exports.createTool = createTool;
|
|
213
251
|
exports.createToolManager = createToolManager;
|
|
214
252
|
exports.isToolCall = isToolCall;
|
|
253
|
+
exports.toolToDefinition = toolToDefinition;
|
|
215
254
|
|
|
216
255
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["#execute","#tools","#definition","#run"],"sources":["../../../src/core/validators.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. 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` 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, 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'\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. Optional\n * 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) => 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 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\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
|
+
{"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,30 +1,42 @@
|
|
|
1
|
-
import { Failure } from '@orkestrel/contract';
|
|
2
|
-
import { Success } from '@orkestrel/contract';
|
|
1
|
+
import type { Failure } from '@orkestrel/contract';
|
|
2
|
+
import type { Success } from '@orkestrel/contract';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Creates an executable tool bound to the supplied handler, returned as a
|
|
6
|
+
* `ToolInterface` so a call site holds the published contract rather than the `Tool`
|
|
7
|
+
* class.
|
|
6
8
|
*
|
|
7
9
|
* @param options - The advertised definition and execution handler
|
|
8
10
|
* @returns A tool bound to the supplied handler
|
|
9
11
|
*
|
|
10
|
-
* @example
|
|
12
|
+
* @example Anatomy of a tool
|
|
11
13
|
* ```ts
|
|
12
14
|
* import { createTool } from '@orkestrel/tool'
|
|
13
15
|
*
|
|
14
16
|
* const add = createTool({
|
|
15
17
|
* name: 'add',
|
|
16
|
-
* description: 'Add two
|
|
17
|
-
*
|
|
18
|
+
* description: 'Add two numeric values and return their sum. Both operands are required.',
|
|
19
|
+
* summary: 'Add two numbers.',
|
|
20
|
+
* parameters: {
|
|
21
|
+
* type: 'object',
|
|
22
|
+
* properties: {
|
|
23
|
+
* left: { type: 'number' },
|
|
24
|
+
* right: { type: 'number' },
|
|
25
|
+
* },
|
|
26
|
+
* required: ['left', 'right'],
|
|
27
|
+
* },
|
|
28
|
+
* execute: (args) => Number(args.left) + Number(args.right),
|
|
18
29
|
* })
|
|
19
30
|
* ```
|
|
20
31
|
*/
|
|
21
32
|
export declare function createTool(options: ToolOptions): ToolInterface;
|
|
22
33
|
|
|
23
34
|
/**
|
|
24
|
-
*
|
|
35
|
+
* Creates an empty registry that advertises definitions and executes calls with
|
|
36
|
+
* per-call error isolation, returned as a `ToolManagerInterface` so a caller holds the
|
|
37
|
+
* published contract rather than the `ToolManager` class.
|
|
25
38
|
*
|
|
26
|
-
* @returns A registry
|
|
27
|
-
* error isolation
|
|
39
|
+
* @returns A registry bound to no tools
|
|
28
40
|
*
|
|
29
41
|
* @example
|
|
30
42
|
* ```ts
|
|
@@ -42,15 +54,16 @@ export declare function createTool(options: ToolOptions): ToolInterface;
|
|
|
42
54
|
export declare function createToolManager(): ToolManagerInterface;
|
|
43
55
|
|
|
44
56
|
/**
|
|
45
|
-
*
|
|
57
|
+
* Determines whether an unknown value is structurally a {@link ToolCall}, staying total
|
|
58
|
+
* for malformed and adversarial input.
|
|
46
59
|
*
|
|
47
60
|
* @remarks
|
|
48
|
-
*
|
|
61
|
+
* The accepted shape is a plain record with string `id` and `name` fields and a
|
|
49
62
|
* plain-record `arguments` field. Optional caller context remains opaque and is not
|
|
50
|
-
* read or verified.
|
|
63
|
+
* read or verified.
|
|
51
64
|
*
|
|
52
65
|
* @param value - The value to test
|
|
53
|
-
* @returns
|
|
66
|
+
* @returns True if the value has the complete tool-call shape; false otherwise
|
|
54
67
|
*
|
|
55
68
|
* @example
|
|
56
69
|
* ```ts
|
|
@@ -63,7 +76,7 @@ export declare function createToolManager(): ToolManagerInterface;
|
|
|
63
76
|
export declare function isToolCall(value: unknown): value is ToolCall;
|
|
64
77
|
|
|
65
78
|
/**
|
|
66
|
-
*
|
|
79
|
+
* Binds an executable tool definition to a handler.
|
|
67
80
|
*
|
|
68
81
|
* @remarks
|
|
69
82
|
* Schema fields, arguments, and present caller context are forwarded by reference.
|
|
@@ -96,7 +109,7 @@ export declare class Tool implements ToolInterface {
|
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
/**
|
|
99
|
-
*
|
|
112
|
+
* Describes one request to run a named tool.
|
|
100
113
|
*
|
|
101
114
|
* @remarks
|
|
102
115
|
* `id` correlates the call with its later {@link ToolResult}. `arguments` is the
|
|
@@ -105,33 +118,33 @@ export declare class Tool implements ToolInterface {
|
|
|
105
118
|
* every trust decision.
|
|
106
119
|
*/
|
|
107
120
|
export declare interface ToolCall {
|
|
108
|
-
/**
|
|
121
|
+
/** Correlates this call with its result. */
|
|
109
122
|
readonly id: string;
|
|
110
|
-
/**
|
|
123
|
+
/** Selects the tool to execute. */
|
|
111
124
|
readonly name: string;
|
|
112
|
-
/**
|
|
125
|
+
/** Carries the record the caller supplied. */
|
|
113
126
|
readonly arguments: Readonly<Record<string, unknown>>;
|
|
114
|
-
/**
|
|
127
|
+
/** Carries consumer-asserted context, forwarded without verification. */
|
|
115
128
|
readonly caller?: unknown;
|
|
116
129
|
}
|
|
117
130
|
|
|
118
131
|
/**
|
|
119
|
-
*
|
|
132
|
+
* Describes a tool as advertised to a caller.
|
|
120
133
|
*
|
|
121
134
|
* @remarks
|
|
122
135
|
* `parameters` is an open JSON Schema record describing the arguments the tool accepts.
|
|
123
136
|
*/
|
|
124
137
|
export declare interface ToolDefinition {
|
|
125
|
-
/**
|
|
138
|
+
/** Identifies the tool a caller selects. */
|
|
126
139
|
readonly name: string;
|
|
127
|
-
/**
|
|
140
|
+
/** Describes the tool's behavior. */
|
|
128
141
|
readonly description?: string;
|
|
129
|
-
/**
|
|
142
|
+
/** Holds the JSON Schema for the tool's arguments. */
|
|
130
143
|
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
131
144
|
}
|
|
132
145
|
|
|
133
146
|
/**
|
|
134
|
-
*
|
|
147
|
+
* Reports the failed outcome of executing a {@link ToolCall}.
|
|
135
148
|
*
|
|
136
149
|
* @remarks
|
|
137
150
|
* `error` is the failure message: an unknown tool name, an `Error`'s message, or
|
|
@@ -140,24 +153,31 @@ export declare interface ToolDefinition {
|
|
|
140
153
|
* `tool.execute(args)` in its own `try`/`catch`.
|
|
141
154
|
*/
|
|
142
155
|
export declare interface ToolFailure extends Failure<string> {
|
|
143
|
-
/**
|
|
156
|
+
/** Identifies the corresponding call. */
|
|
144
157
|
readonly id: string;
|
|
145
|
-
/**
|
|
158
|
+
/** Identifies the called tool. */
|
|
146
159
|
readonly name: string;
|
|
147
160
|
}
|
|
148
161
|
|
|
149
162
|
/**
|
|
150
|
-
*
|
|
163
|
+
* Represents an executable tool: its advertised definition plus its local handler.
|
|
151
164
|
*
|
|
152
165
|
* @remarks
|
|
153
166
|
* `summary`, when present, is advertised in place of the full `description` by a
|
|
154
167
|
* {@link ToolManagerInterface}. The full description remains available on the tool.
|
|
155
168
|
*/
|
|
156
169
|
export declare interface ToolInterface extends ToolDefinition {
|
|
157
|
-
/**
|
|
170
|
+
/** Holds a concise description to advertise in place of the full description. */
|
|
158
171
|
readonly summary?: string;
|
|
159
172
|
/**
|
|
160
|
-
*
|
|
173
|
+
* Runs the tool's handler with the caller-supplied arguments and any consumer-asserted
|
|
174
|
+
* caller context.
|
|
175
|
+
*
|
|
176
|
+
* @remarks
|
|
177
|
+
* Failures are not contained here: a synchronous throw propagates and an
|
|
178
|
+
* asynchronous rejection rejects. {@link ToolManagerInterface.execute} is where a
|
|
179
|
+
* call becomes a result. The registry omits `caller` from the invocation when the
|
|
180
|
+
* call carries none, so a handler reading its own arity sees one argument.
|
|
161
181
|
*
|
|
162
182
|
* @param args - The caller-supplied arguments record
|
|
163
183
|
* @param caller - Optional consumer-asserted caller context, forwarded without verification
|
|
@@ -167,14 +187,15 @@ export declare interface ToolInterface extends ToolDefinition {
|
|
|
167
187
|
}
|
|
168
188
|
|
|
169
189
|
/**
|
|
170
|
-
*
|
|
190
|
+
* Represents an insertion-ordered tool registry with per-call error isolation.
|
|
171
191
|
*
|
|
172
192
|
* @remarks
|
|
173
193
|
* A repeated name overwrites the registered tool without changing its insertion
|
|
174
194
|
* position. Definitions advertise `summary` in place of `description` when present.
|
|
175
|
-
* Unknown names and handler throws resolve to error results;
|
|
176
|
-
*
|
|
177
|
-
*
|
|
195
|
+
* Unknown names and handler throws resolve to error results; a call whose `id` or `name`
|
|
196
|
+
* accessor throws when read makes its call, and the batch holding it, reject. Batch
|
|
197
|
+
* execution preserves input order and isolates each call whose members are plain
|
|
198
|
+
* values. Optional consumer-asserted caller context is forwarded without verification.
|
|
178
199
|
*
|
|
179
200
|
* @example
|
|
180
201
|
* ```ts
|
|
@@ -205,47 +226,49 @@ export declare class ToolManager implements ToolManagerInterface {
|
|
|
205
226
|
}
|
|
206
227
|
|
|
207
228
|
/**
|
|
208
|
-
*
|
|
229
|
+
* Represents a registry of executable tools with per-call error isolation.
|
|
209
230
|
*
|
|
210
231
|
* @remarks
|
|
211
232
|
* Tools are keyed by name in insertion order. Adding an existing name overwrites its
|
|
212
|
-
* value without changing its position. Every call
|
|
213
|
-
* missing tools and thrown handlers become error
|
|
214
|
-
*
|
|
233
|
+
* value without changing its position. Every call whose members are plain values
|
|
234
|
+
* resolves to a {@link ToolResult}; missing tools and thrown handlers become error
|
|
235
|
+
* results, and a call whose `id` or `name` accessor throws when read makes `execute`
|
|
236
|
+
* reject instead. Batch execution preserves input order.
|
|
215
237
|
*/
|
|
216
238
|
export declare interface ToolManagerInterface {
|
|
217
|
-
/**
|
|
239
|
+
/** Reports how many tools are registered. */
|
|
218
240
|
readonly count: number;
|
|
219
241
|
/**
|
|
220
|
-
*
|
|
242
|
+
* Registers one tool.
|
|
221
243
|
*
|
|
222
244
|
* @param tool - The tool to register
|
|
223
245
|
* @returns Nothing
|
|
224
246
|
*/
|
|
225
247
|
add(tool: ToolInterface): void;
|
|
226
248
|
/**
|
|
227
|
-
*
|
|
249
|
+
* Registers a batch of tools.
|
|
228
250
|
*
|
|
229
251
|
* @param tools - The tools to register
|
|
230
252
|
* @returns Nothing
|
|
231
253
|
*/
|
|
232
254
|
add(tools: readonly ToolInterface[]): void;
|
|
233
255
|
/**
|
|
234
|
-
*
|
|
256
|
+
* Finds one registered tool by name.
|
|
235
257
|
*
|
|
236
258
|
* @param name - The registered tool name
|
|
237
|
-
* @returns The
|
|
259
|
+
* @returns The exact registered instance when found, otherwise `undefined`
|
|
238
260
|
*/
|
|
239
261
|
tool(name: string): ToolInterface | undefined;
|
|
240
262
|
/**
|
|
241
|
-
*
|
|
263
|
+
* Lists the registered tools in insertion order.
|
|
242
264
|
*
|
|
243
265
|
* @returns A new readonly array of registered tools
|
|
244
266
|
*/
|
|
245
267
|
tools(): readonly ToolInterface[];
|
|
246
268
|
/**
|
|
247
|
-
*
|
|
269
|
+
* Lists the definitions advertised to a caller.
|
|
248
270
|
*
|
|
271
|
+
* @remarks
|
|
249
272
|
* The projected `description` is the tool's `summary` when one was authored,
|
|
250
273
|
* advertised in place of the full description. The full text stays on the tool
|
|
251
274
|
* for direct lookup.
|
|
@@ -254,35 +277,35 @@ export declare interface ToolManagerInterface {
|
|
|
254
277
|
*/
|
|
255
278
|
definitions(): readonly ToolDefinition[];
|
|
256
279
|
/**
|
|
257
|
-
*
|
|
280
|
+
* Executes one call with error isolation.
|
|
258
281
|
*
|
|
259
282
|
* @param call - The tool call to execute, including optional caller context
|
|
260
283
|
* @returns The correlated result
|
|
261
284
|
*/
|
|
262
285
|
execute(call: ToolCall): Promise<ToolResult>;
|
|
263
286
|
/**
|
|
264
|
-
*
|
|
287
|
+
* Executes a batch of calls with per-call error isolation.
|
|
265
288
|
*
|
|
266
289
|
* @param calls - The tool calls to execute, including optional caller context
|
|
267
290
|
* @returns The correlated results in input order
|
|
268
291
|
*/
|
|
269
292
|
execute(calls: readonly ToolCall[]): Promise<readonly ToolResult[]>;
|
|
270
293
|
/**
|
|
271
|
-
*
|
|
294
|
+
* Removes one registered tool.
|
|
272
295
|
*
|
|
273
296
|
* @param name - The tool name to remove
|
|
274
|
-
* @returns
|
|
297
|
+
* @returns True if the tool was present; false otherwise
|
|
275
298
|
*/
|
|
276
299
|
remove(name: string): boolean;
|
|
277
300
|
/**
|
|
278
|
-
*
|
|
301
|
+
* Removes a batch of registered tools.
|
|
279
302
|
*
|
|
280
303
|
* @param names - The tool names to remove
|
|
281
|
-
* @returns
|
|
304
|
+
* @returns True if every named tool was present; false otherwise
|
|
282
305
|
*/
|
|
283
306
|
remove(names: readonly string[]): boolean;
|
|
284
307
|
/**
|
|
285
|
-
*
|
|
308
|
+
* Removes every registered tool.
|
|
286
309
|
*
|
|
287
310
|
* @returns Nothing
|
|
288
311
|
*/
|
|
@@ -290,7 +313,7 @@ export declare interface ToolManagerInterface {
|
|
|
290
313
|
}
|
|
291
314
|
|
|
292
315
|
/**
|
|
293
|
-
*
|
|
316
|
+
* Configures an executable tool.
|
|
294
317
|
*
|
|
295
318
|
* @remarks
|
|
296
319
|
* `name` identifies the tool, `description` and `parameters` define what is advertised
|
|
@@ -299,38 +322,64 @@ export declare interface ToolManagerInterface {
|
|
|
299
322
|
* context. This package forwards that context without verification.
|
|
300
323
|
*/
|
|
301
324
|
export declare interface ToolOptions {
|
|
302
|
-
/**
|
|
325
|
+
/** Identifies the tool a caller selects. */
|
|
303
326
|
readonly name: string;
|
|
304
|
-
/**
|
|
327
|
+
/** Describes the tool's behavior in full. */
|
|
305
328
|
readonly description?: string;
|
|
306
|
-
/**
|
|
329
|
+
/** Holds a concise description to advertise in place of the full description. */
|
|
307
330
|
readonly summary?: string;
|
|
308
|
-
/**
|
|
331
|
+
/** Holds the JSON Schema for the tool's arguments. */
|
|
309
332
|
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
310
|
-
/**
|
|
333
|
+
/** Handles the arguments and optional unverified caller context. */
|
|
311
334
|
readonly execute: (args: Readonly<Record<string, unknown>>, caller?: unknown) => Promise<unknown> | unknown;
|
|
312
335
|
}
|
|
313
336
|
|
|
314
337
|
/**
|
|
315
|
-
*
|
|
338
|
+
* Represents the outcome of executing a {@link ToolCall}.
|
|
316
339
|
*
|
|
317
340
|
* @remarks
|
|
318
|
-
* Always a result and never a throw.
|
|
341
|
+
* Always a result and never a throw for a call whose members are plain values. A call
|
|
342
|
+
* whose `id` or `name` accessor throws when read makes `execute` reject instead, because
|
|
343
|
+
* no correlated result can be built without them. Narrow on `success`.
|
|
319
344
|
*/
|
|
320
345
|
export declare type ToolResult = ToolSuccess | ToolFailure;
|
|
321
346
|
|
|
322
347
|
/**
|
|
323
|
-
*
|
|
348
|
+
* Reports the successful outcome of executing a {@link ToolCall}.
|
|
324
349
|
*
|
|
325
350
|
* @remarks
|
|
326
351
|
* `value` is whatever the handler returned — including `undefined`, `null`, `0`,
|
|
327
352
|
* `''`, or `false`. A present value never implies a meaningful one.
|
|
328
353
|
*/
|
|
329
354
|
export declare interface ToolSuccess extends Success<unknown> {
|
|
330
|
-
/**
|
|
355
|
+
/** Identifies the corresponding call. */
|
|
331
356
|
readonly id: string;
|
|
332
|
-
/**
|
|
357
|
+
/** Identifies the called tool. */
|
|
333
358
|
readonly name: string;
|
|
334
359
|
}
|
|
335
360
|
|
|
361
|
+
/**
|
|
362
|
+
* Projects a tool onto the plain definition advertised to a caller, advertising an
|
|
363
|
+
* authored `summary` in place of the full description and carrying the parameter schema
|
|
364
|
+
* by reference.
|
|
365
|
+
*
|
|
366
|
+
* @remarks
|
|
367
|
+
* The projection is a fresh object carrying `name`, then `description` only when the
|
|
368
|
+
* tool authored a summary or a description, then `parameters` only when the tool
|
|
369
|
+
* authored a schema. The full `description` stays on the tool for direct lookup, and
|
|
370
|
+
* the definition is never a live handle on the tool's handler.
|
|
371
|
+
*
|
|
372
|
+
* @param tool - The tool to project
|
|
373
|
+
* @returns A fresh definition carrying only the fields the tool authored
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```ts
|
|
377
|
+
* import { Tool, toolToDefinition } from '@orkestrel/tool'
|
|
378
|
+
*
|
|
379
|
+
* const echo = new Tool({ name: 'echo', summary: 'Echo a value.', execute: (args) => args.value })
|
|
380
|
+
* toolToDefinition(echo) // { name: 'echo', description: 'Echo a value.' }
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
export declare function toolToDefinition(tool: ToolInterface): ToolDefinition;
|
|
384
|
+
|
|
336
385
|
export { }
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -1,30 +1,42 @@
|
|
|
1
|
-
import { Failure } from '@orkestrel/contract';
|
|
2
|
-
import { Success } from '@orkestrel/contract';
|
|
1
|
+
import type { Failure } from '@orkestrel/contract';
|
|
2
|
+
import type { Success } from '@orkestrel/contract';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Creates an executable tool bound to the supplied handler, returned as a
|
|
6
|
+
* `ToolInterface` so a call site holds the published contract rather than the `Tool`
|
|
7
|
+
* class.
|
|
6
8
|
*
|
|
7
9
|
* @param options - The advertised definition and execution handler
|
|
8
10
|
* @returns A tool bound to the supplied handler
|
|
9
11
|
*
|
|
10
|
-
* @example
|
|
12
|
+
* @example Anatomy of a tool
|
|
11
13
|
* ```ts
|
|
12
14
|
* import { createTool } from '@orkestrel/tool'
|
|
13
15
|
*
|
|
14
16
|
* const add = createTool({
|
|
15
17
|
* name: 'add',
|
|
16
|
-
* description: 'Add two
|
|
17
|
-
*
|
|
18
|
+
* description: 'Add two numeric values and return their sum. Both operands are required.',
|
|
19
|
+
* summary: 'Add two numbers.',
|
|
20
|
+
* parameters: {
|
|
21
|
+
* type: 'object',
|
|
22
|
+
* properties: {
|
|
23
|
+
* left: { type: 'number' },
|
|
24
|
+
* right: { type: 'number' },
|
|
25
|
+
* },
|
|
26
|
+
* required: ['left', 'right'],
|
|
27
|
+
* },
|
|
28
|
+
* execute: (args) => Number(args.left) + Number(args.right),
|
|
18
29
|
* })
|
|
19
30
|
* ```
|
|
20
31
|
*/
|
|
21
32
|
export declare function createTool(options: ToolOptions): ToolInterface;
|
|
22
33
|
|
|
23
34
|
/**
|
|
24
|
-
*
|
|
35
|
+
* Creates an empty registry that advertises definitions and executes calls with
|
|
36
|
+
* per-call error isolation, returned as a `ToolManagerInterface` so a caller holds the
|
|
37
|
+
* published contract rather than the `ToolManager` class.
|
|
25
38
|
*
|
|
26
|
-
* @returns A registry
|
|
27
|
-
* error isolation
|
|
39
|
+
* @returns A registry bound to no tools
|
|
28
40
|
*
|
|
29
41
|
* @example
|
|
30
42
|
* ```ts
|
|
@@ -42,15 +54,16 @@ export declare function createTool(options: ToolOptions): ToolInterface;
|
|
|
42
54
|
export declare function createToolManager(): ToolManagerInterface;
|
|
43
55
|
|
|
44
56
|
/**
|
|
45
|
-
*
|
|
57
|
+
* Determines whether an unknown value is structurally a {@link ToolCall}, staying total
|
|
58
|
+
* for malformed and adversarial input.
|
|
46
59
|
*
|
|
47
60
|
* @remarks
|
|
48
|
-
*
|
|
61
|
+
* The accepted shape is a plain record with string `id` and `name` fields and a
|
|
49
62
|
* plain-record `arguments` field. Optional caller context remains opaque and is not
|
|
50
|
-
* read or verified.
|
|
63
|
+
* read or verified.
|
|
51
64
|
*
|
|
52
65
|
* @param value - The value to test
|
|
53
|
-
* @returns
|
|
66
|
+
* @returns True if the value has the complete tool-call shape; false otherwise
|
|
54
67
|
*
|
|
55
68
|
* @example
|
|
56
69
|
* ```ts
|
|
@@ -63,7 +76,7 @@ export declare function createToolManager(): ToolManagerInterface;
|
|
|
63
76
|
export declare function isToolCall(value: unknown): value is ToolCall;
|
|
64
77
|
|
|
65
78
|
/**
|
|
66
|
-
*
|
|
79
|
+
* Binds an executable tool definition to a handler.
|
|
67
80
|
*
|
|
68
81
|
* @remarks
|
|
69
82
|
* Schema fields, arguments, and present caller context are forwarded by reference.
|
|
@@ -96,7 +109,7 @@ export declare class Tool implements ToolInterface {
|
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
/**
|
|
99
|
-
*
|
|
112
|
+
* Describes one request to run a named tool.
|
|
100
113
|
*
|
|
101
114
|
* @remarks
|
|
102
115
|
* `id` correlates the call with its later {@link ToolResult}. `arguments` is the
|
|
@@ -105,33 +118,33 @@ export declare class Tool implements ToolInterface {
|
|
|
105
118
|
* every trust decision.
|
|
106
119
|
*/
|
|
107
120
|
export declare interface ToolCall {
|
|
108
|
-
/**
|
|
121
|
+
/** Correlates this call with its result. */
|
|
109
122
|
readonly id: string;
|
|
110
|
-
/**
|
|
123
|
+
/** Selects the tool to execute. */
|
|
111
124
|
readonly name: string;
|
|
112
|
-
/**
|
|
125
|
+
/** Carries the record the caller supplied. */
|
|
113
126
|
readonly arguments: Readonly<Record<string, unknown>>;
|
|
114
|
-
/**
|
|
127
|
+
/** Carries consumer-asserted context, forwarded without verification. */
|
|
115
128
|
readonly caller?: unknown;
|
|
116
129
|
}
|
|
117
130
|
|
|
118
131
|
/**
|
|
119
|
-
*
|
|
132
|
+
* Describes a tool as advertised to a caller.
|
|
120
133
|
*
|
|
121
134
|
* @remarks
|
|
122
135
|
* `parameters` is an open JSON Schema record describing the arguments the tool accepts.
|
|
123
136
|
*/
|
|
124
137
|
export declare interface ToolDefinition {
|
|
125
|
-
/**
|
|
138
|
+
/** Identifies the tool a caller selects. */
|
|
126
139
|
readonly name: string;
|
|
127
|
-
/**
|
|
140
|
+
/** Describes the tool's behavior. */
|
|
128
141
|
readonly description?: string;
|
|
129
|
-
/**
|
|
142
|
+
/** Holds the JSON Schema for the tool's arguments. */
|
|
130
143
|
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
131
144
|
}
|
|
132
145
|
|
|
133
146
|
/**
|
|
134
|
-
*
|
|
147
|
+
* Reports the failed outcome of executing a {@link ToolCall}.
|
|
135
148
|
*
|
|
136
149
|
* @remarks
|
|
137
150
|
* `error` is the failure message: an unknown tool name, an `Error`'s message, or
|
|
@@ -140,24 +153,31 @@ export declare interface ToolDefinition {
|
|
|
140
153
|
* `tool.execute(args)` in its own `try`/`catch`.
|
|
141
154
|
*/
|
|
142
155
|
export declare interface ToolFailure extends Failure<string> {
|
|
143
|
-
/**
|
|
156
|
+
/** Identifies the corresponding call. */
|
|
144
157
|
readonly id: string;
|
|
145
|
-
/**
|
|
158
|
+
/** Identifies the called tool. */
|
|
146
159
|
readonly name: string;
|
|
147
160
|
}
|
|
148
161
|
|
|
149
162
|
/**
|
|
150
|
-
*
|
|
163
|
+
* Represents an executable tool: its advertised definition plus its local handler.
|
|
151
164
|
*
|
|
152
165
|
* @remarks
|
|
153
166
|
* `summary`, when present, is advertised in place of the full `description` by a
|
|
154
167
|
* {@link ToolManagerInterface}. The full description remains available on the tool.
|
|
155
168
|
*/
|
|
156
169
|
export declare interface ToolInterface extends ToolDefinition {
|
|
157
|
-
/**
|
|
170
|
+
/** Holds a concise description to advertise in place of the full description. */
|
|
158
171
|
readonly summary?: string;
|
|
159
172
|
/**
|
|
160
|
-
*
|
|
173
|
+
* Runs the tool's handler with the caller-supplied arguments and any consumer-asserted
|
|
174
|
+
* caller context.
|
|
175
|
+
*
|
|
176
|
+
* @remarks
|
|
177
|
+
* Failures are not contained here: a synchronous throw propagates and an
|
|
178
|
+
* asynchronous rejection rejects. {@link ToolManagerInterface.execute} is where a
|
|
179
|
+
* call becomes a result. The registry omits `caller` from the invocation when the
|
|
180
|
+
* call carries none, so a handler reading its own arity sees one argument.
|
|
161
181
|
*
|
|
162
182
|
* @param args - The caller-supplied arguments record
|
|
163
183
|
* @param caller - Optional consumer-asserted caller context, forwarded without verification
|
|
@@ -167,14 +187,15 @@ export declare interface ToolInterface extends ToolDefinition {
|
|
|
167
187
|
}
|
|
168
188
|
|
|
169
189
|
/**
|
|
170
|
-
*
|
|
190
|
+
* Represents an insertion-ordered tool registry with per-call error isolation.
|
|
171
191
|
*
|
|
172
192
|
* @remarks
|
|
173
193
|
* A repeated name overwrites the registered tool without changing its insertion
|
|
174
194
|
* position. Definitions advertise `summary` in place of `description` when present.
|
|
175
|
-
* Unknown names and handler throws resolve to error results;
|
|
176
|
-
*
|
|
177
|
-
*
|
|
195
|
+
* Unknown names and handler throws resolve to error results; a call whose `id` or `name`
|
|
196
|
+
* accessor throws when read makes its call, and the batch holding it, reject. Batch
|
|
197
|
+
* execution preserves input order and isolates each call whose members are plain
|
|
198
|
+
* values. Optional consumer-asserted caller context is forwarded without verification.
|
|
178
199
|
*
|
|
179
200
|
* @example
|
|
180
201
|
* ```ts
|
|
@@ -205,47 +226,49 @@ export declare class ToolManager implements ToolManagerInterface {
|
|
|
205
226
|
}
|
|
206
227
|
|
|
207
228
|
/**
|
|
208
|
-
*
|
|
229
|
+
* Represents a registry of executable tools with per-call error isolation.
|
|
209
230
|
*
|
|
210
231
|
* @remarks
|
|
211
232
|
* Tools are keyed by name in insertion order. Adding an existing name overwrites its
|
|
212
|
-
* value without changing its position. Every call
|
|
213
|
-
* missing tools and thrown handlers become error
|
|
214
|
-
*
|
|
233
|
+
* value without changing its position. Every call whose members are plain values
|
|
234
|
+
* resolves to a {@link ToolResult}; missing tools and thrown handlers become error
|
|
235
|
+
* results, and a call whose `id` or `name` accessor throws when read makes `execute`
|
|
236
|
+
* reject instead. Batch execution preserves input order.
|
|
215
237
|
*/
|
|
216
238
|
export declare interface ToolManagerInterface {
|
|
217
|
-
/**
|
|
239
|
+
/** Reports how many tools are registered. */
|
|
218
240
|
readonly count: number;
|
|
219
241
|
/**
|
|
220
|
-
*
|
|
242
|
+
* Registers one tool.
|
|
221
243
|
*
|
|
222
244
|
* @param tool - The tool to register
|
|
223
245
|
* @returns Nothing
|
|
224
246
|
*/
|
|
225
247
|
add(tool: ToolInterface): void;
|
|
226
248
|
/**
|
|
227
|
-
*
|
|
249
|
+
* Registers a batch of tools.
|
|
228
250
|
*
|
|
229
251
|
* @param tools - The tools to register
|
|
230
252
|
* @returns Nothing
|
|
231
253
|
*/
|
|
232
254
|
add(tools: readonly ToolInterface[]): void;
|
|
233
255
|
/**
|
|
234
|
-
*
|
|
256
|
+
* Finds one registered tool by name.
|
|
235
257
|
*
|
|
236
258
|
* @param name - The registered tool name
|
|
237
|
-
* @returns The
|
|
259
|
+
* @returns The exact registered instance when found, otherwise `undefined`
|
|
238
260
|
*/
|
|
239
261
|
tool(name: string): ToolInterface | undefined;
|
|
240
262
|
/**
|
|
241
|
-
*
|
|
263
|
+
* Lists the registered tools in insertion order.
|
|
242
264
|
*
|
|
243
265
|
* @returns A new readonly array of registered tools
|
|
244
266
|
*/
|
|
245
267
|
tools(): readonly ToolInterface[];
|
|
246
268
|
/**
|
|
247
|
-
*
|
|
269
|
+
* Lists the definitions advertised to a caller.
|
|
248
270
|
*
|
|
271
|
+
* @remarks
|
|
249
272
|
* The projected `description` is the tool's `summary` when one was authored,
|
|
250
273
|
* advertised in place of the full description. The full text stays on the tool
|
|
251
274
|
* for direct lookup.
|
|
@@ -254,35 +277,35 @@ export declare interface ToolManagerInterface {
|
|
|
254
277
|
*/
|
|
255
278
|
definitions(): readonly ToolDefinition[];
|
|
256
279
|
/**
|
|
257
|
-
*
|
|
280
|
+
* Executes one call with error isolation.
|
|
258
281
|
*
|
|
259
282
|
* @param call - The tool call to execute, including optional caller context
|
|
260
283
|
* @returns The correlated result
|
|
261
284
|
*/
|
|
262
285
|
execute(call: ToolCall): Promise<ToolResult>;
|
|
263
286
|
/**
|
|
264
|
-
*
|
|
287
|
+
* Executes a batch of calls with per-call error isolation.
|
|
265
288
|
*
|
|
266
289
|
* @param calls - The tool calls to execute, including optional caller context
|
|
267
290
|
* @returns The correlated results in input order
|
|
268
291
|
*/
|
|
269
292
|
execute(calls: readonly ToolCall[]): Promise<readonly ToolResult[]>;
|
|
270
293
|
/**
|
|
271
|
-
*
|
|
294
|
+
* Removes one registered tool.
|
|
272
295
|
*
|
|
273
296
|
* @param name - The tool name to remove
|
|
274
|
-
* @returns
|
|
297
|
+
* @returns True if the tool was present; false otherwise
|
|
275
298
|
*/
|
|
276
299
|
remove(name: string): boolean;
|
|
277
300
|
/**
|
|
278
|
-
*
|
|
301
|
+
* Removes a batch of registered tools.
|
|
279
302
|
*
|
|
280
303
|
* @param names - The tool names to remove
|
|
281
|
-
* @returns
|
|
304
|
+
* @returns True if every named tool was present; false otherwise
|
|
282
305
|
*/
|
|
283
306
|
remove(names: readonly string[]): boolean;
|
|
284
307
|
/**
|
|
285
|
-
*
|
|
308
|
+
* Removes every registered tool.
|
|
286
309
|
*
|
|
287
310
|
* @returns Nothing
|
|
288
311
|
*/
|
|
@@ -290,7 +313,7 @@ export declare interface ToolManagerInterface {
|
|
|
290
313
|
}
|
|
291
314
|
|
|
292
315
|
/**
|
|
293
|
-
*
|
|
316
|
+
* Configures an executable tool.
|
|
294
317
|
*
|
|
295
318
|
* @remarks
|
|
296
319
|
* `name` identifies the tool, `description` and `parameters` define what is advertised
|
|
@@ -299,38 +322,64 @@ export declare interface ToolManagerInterface {
|
|
|
299
322
|
* context. This package forwards that context without verification.
|
|
300
323
|
*/
|
|
301
324
|
export declare interface ToolOptions {
|
|
302
|
-
/**
|
|
325
|
+
/** Identifies the tool a caller selects. */
|
|
303
326
|
readonly name: string;
|
|
304
|
-
/**
|
|
327
|
+
/** Describes the tool's behavior in full. */
|
|
305
328
|
readonly description?: string;
|
|
306
|
-
/**
|
|
329
|
+
/** Holds a concise description to advertise in place of the full description. */
|
|
307
330
|
readonly summary?: string;
|
|
308
|
-
/**
|
|
331
|
+
/** Holds the JSON Schema for the tool's arguments. */
|
|
309
332
|
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
310
|
-
/**
|
|
333
|
+
/** Handles the arguments and optional unverified caller context. */
|
|
311
334
|
readonly execute: (args: Readonly<Record<string, unknown>>, caller?: unknown) => Promise<unknown> | unknown;
|
|
312
335
|
}
|
|
313
336
|
|
|
314
337
|
/**
|
|
315
|
-
*
|
|
338
|
+
* Represents the outcome of executing a {@link ToolCall}.
|
|
316
339
|
*
|
|
317
340
|
* @remarks
|
|
318
|
-
* Always a result and never a throw.
|
|
341
|
+
* Always a result and never a throw for a call whose members are plain values. A call
|
|
342
|
+
* whose `id` or `name` accessor throws when read makes `execute` reject instead, because
|
|
343
|
+
* no correlated result can be built without them. Narrow on `success`.
|
|
319
344
|
*/
|
|
320
345
|
export declare type ToolResult = ToolSuccess | ToolFailure;
|
|
321
346
|
|
|
322
347
|
/**
|
|
323
|
-
*
|
|
348
|
+
* Reports the successful outcome of executing a {@link ToolCall}.
|
|
324
349
|
*
|
|
325
350
|
* @remarks
|
|
326
351
|
* `value` is whatever the handler returned — including `undefined`, `null`, `0`,
|
|
327
352
|
* `''`, or `false`. A present value never implies a meaningful one.
|
|
328
353
|
*/
|
|
329
354
|
export declare interface ToolSuccess extends Success<unknown> {
|
|
330
|
-
/**
|
|
355
|
+
/** Identifies the corresponding call. */
|
|
331
356
|
readonly id: string;
|
|
332
|
-
/**
|
|
357
|
+
/** Identifies the called tool. */
|
|
333
358
|
readonly name: string;
|
|
334
359
|
}
|
|
335
360
|
|
|
361
|
+
/**
|
|
362
|
+
* Projects a tool onto the plain definition advertised to a caller, advertising an
|
|
363
|
+
* authored `summary` in place of the full description and carrying the parameter schema
|
|
364
|
+
* by reference.
|
|
365
|
+
*
|
|
366
|
+
* @remarks
|
|
367
|
+
* The projection is a fresh object carrying `name`, then `description` only when the
|
|
368
|
+
* tool authored a summary or a description, then `parameters` only when the tool
|
|
369
|
+
* authored a schema. The full `description` stays on the tool for direct lookup, and
|
|
370
|
+
* the definition is never a live handle on the tool's handler.
|
|
371
|
+
*
|
|
372
|
+
* @param tool - The tool to project
|
|
373
|
+
* @returns A fresh definition carrying only the fields the tool authored
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```ts
|
|
377
|
+
* import { Tool, toolToDefinition } from '@orkestrel/tool'
|
|
378
|
+
*
|
|
379
|
+
* const echo = new Tool({ name: 'echo', summary: 'Echo a value.', execute: (args) => args.value })
|
|
380
|
+
* toolToDefinition(echo) // { name: 'echo', description: 'Echo a value.' }
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
export declare function toolToDefinition(tool: ToolInterface): ToolDefinition;
|
|
384
|
+
|
|
336
385
|
export { }
|
package/dist/src/core/index.js
CHANGED
|
@@ -1,15 +1,47 @@
|
|
|
1
1
|
import { attempt, holds, isArray, isRecord, isString } from "@orkestrel/contract";
|
|
2
|
+
//#region src/core/helpers.ts
|
|
3
|
+
/**
|
|
4
|
+
* Projects a tool onto the plain definition advertised to a caller, advertising an
|
|
5
|
+
* authored `summary` in place of the full description and carrying the parameter schema
|
|
6
|
+
* by reference.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* The projection is a fresh object carrying `name`, then `description` only when the
|
|
10
|
+
* tool authored a summary or a description, then `parameters` only when the tool
|
|
11
|
+
* authored a schema. The full `description` stays on the tool for direct lookup, and
|
|
12
|
+
* the definition is never a live handle on the tool's handler.
|
|
13
|
+
*
|
|
14
|
+
* @param tool - The tool to project
|
|
15
|
+
* @returns A fresh definition carrying only the fields the tool authored
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { Tool, toolToDefinition } from '@orkestrel/tool'
|
|
20
|
+
*
|
|
21
|
+
* const echo = new Tool({ name: 'echo', summary: 'Echo a value.', execute: (args) => args.value })
|
|
22
|
+
* toolToDefinition(echo) // { name: 'echo', description: 'Echo a value.' }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function toolToDefinition(tool) {
|
|
26
|
+
const definition = { name: tool.name };
|
|
27
|
+
const description = tool.summary ?? tool.description;
|
|
28
|
+
if (description !== void 0) definition.description = description;
|
|
29
|
+
if (tool.parameters !== void 0) definition.parameters = tool.parameters;
|
|
30
|
+
return definition;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
2
33
|
//#region src/core/validators.ts
|
|
3
34
|
/**
|
|
4
|
-
*
|
|
35
|
+
* Determines whether an unknown value is structurally a {@link ToolCall}, staying total
|
|
36
|
+
* for malformed and adversarial input.
|
|
5
37
|
*
|
|
6
38
|
* @remarks
|
|
7
|
-
*
|
|
39
|
+
* The accepted shape is a plain record with string `id` and `name` fields and a
|
|
8
40
|
* plain-record `arguments` field. Optional caller context remains opaque and is not
|
|
9
|
-
* read or verified.
|
|
41
|
+
* read or verified.
|
|
10
42
|
*
|
|
11
43
|
* @param value - The value to test
|
|
12
|
-
* @returns
|
|
44
|
+
* @returns True if the value has the complete tool-call shape; false otherwise
|
|
13
45
|
*
|
|
14
46
|
* @example
|
|
15
47
|
* ```ts
|
|
@@ -25,7 +57,7 @@ function isToolCall(value) {
|
|
|
25
57
|
//#endregion
|
|
26
58
|
//#region src/core/tools/Tool.ts
|
|
27
59
|
/**
|
|
28
|
-
*
|
|
60
|
+
* Binds an executable tool definition to a handler.
|
|
29
61
|
*
|
|
30
62
|
* @remarks
|
|
31
63
|
* Schema fields, arguments, and present caller context are forwarded by reference.
|
|
@@ -68,14 +100,15 @@ var Tool = class {
|
|
|
68
100
|
//#endregion
|
|
69
101
|
//#region src/core/tools/ToolManager.ts
|
|
70
102
|
/**
|
|
71
|
-
*
|
|
103
|
+
* Represents an insertion-ordered tool registry with per-call error isolation.
|
|
72
104
|
*
|
|
73
105
|
* @remarks
|
|
74
106
|
* A repeated name overwrites the registered tool without changing its insertion
|
|
75
107
|
* position. Definitions advertise `summary` in place of `description` when present.
|
|
76
|
-
* Unknown names and handler throws resolve to error results;
|
|
77
|
-
*
|
|
78
|
-
*
|
|
108
|
+
* Unknown names and handler throws resolve to error results; a call whose `id` or `name`
|
|
109
|
+
* accessor throws when read makes its call, and the batch holding it, reject. Batch
|
|
110
|
+
* execution preserves input order and isolates each call whose members are plain
|
|
111
|
+
* values. Optional consumer-asserted caller context is forwarded without verification.
|
|
79
112
|
*
|
|
80
113
|
* @example
|
|
81
114
|
* ```ts
|
|
@@ -109,7 +142,7 @@ var ToolManager = class {
|
|
|
109
142
|
return [...this.#tools.values()];
|
|
110
143
|
}
|
|
111
144
|
definitions() {
|
|
112
|
-
return [...this.#tools.values()].map((tool) =>
|
|
145
|
+
return [...this.#tools.values()].map((tool) => toolToDefinition(tool));
|
|
113
146
|
}
|
|
114
147
|
execute(call) {
|
|
115
148
|
if (isArray(call)) return Promise.all(call.map((one) => this.#run(one)));
|
|
@@ -117,8 +150,8 @@ var ToolManager = class {
|
|
|
117
150
|
}
|
|
118
151
|
remove(names) {
|
|
119
152
|
if (isArray(names)) {
|
|
120
|
-
let removed =
|
|
121
|
-
for (const name of names) if (this.#tools.delete(name)) removed =
|
|
153
|
+
let removed = true;
|
|
154
|
+
for (const name of names) if (!this.#tools.delete(name)) removed = false;
|
|
122
155
|
return removed;
|
|
123
156
|
}
|
|
124
157
|
return this.#tools.delete(names);
|
|
@@ -153,30 +186,34 @@ var ToolManager = class {
|
|
|
153
186
|
};
|
|
154
187
|
}
|
|
155
188
|
}
|
|
156
|
-
#definition(tool) {
|
|
157
|
-
const definition = { name: tool.name };
|
|
158
|
-
const description = tool.summary ?? tool.description;
|
|
159
|
-
if (description !== void 0) definition.description = description;
|
|
160
|
-
if (tool.parameters !== void 0) definition.parameters = tool.parameters;
|
|
161
|
-
return definition;
|
|
162
|
-
}
|
|
163
189
|
};
|
|
164
190
|
//#endregion
|
|
165
191
|
//#region src/core/factories.ts
|
|
166
192
|
/**
|
|
167
|
-
*
|
|
193
|
+
* Creates an executable tool bound to the supplied handler, returned as a
|
|
194
|
+
* `ToolInterface` so a call site holds the published contract rather than the `Tool`
|
|
195
|
+
* class.
|
|
168
196
|
*
|
|
169
197
|
* @param options - The advertised definition and execution handler
|
|
170
198
|
* @returns A tool bound to the supplied handler
|
|
171
199
|
*
|
|
172
|
-
* @example
|
|
200
|
+
* @example Anatomy of a tool
|
|
173
201
|
* ```ts
|
|
174
202
|
* import { createTool } from '@orkestrel/tool'
|
|
175
203
|
*
|
|
176
204
|
* const add = createTool({
|
|
177
205
|
* name: 'add',
|
|
178
|
-
* description: 'Add two
|
|
179
|
-
*
|
|
206
|
+
* description: 'Add two numeric values and return their sum. Both operands are required.',
|
|
207
|
+
* summary: 'Add two numbers.',
|
|
208
|
+
* parameters: {
|
|
209
|
+
* type: 'object',
|
|
210
|
+
* properties: {
|
|
211
|
+
* left: { type: 'number' },
|
|
212
|
+
* right: { type: 'number' },
|
|
213
|
+
* },
|
|
214
|
+
* required: ['left', 'right'],
|
|
215
|
+
* },
|
|
216
|
+
* execute: (args) => Number(args.left) + Number(args.right),
|
|
180
217
|
* })
|
|
181
218
|
* ```
|
|
182
219
|
*/
|
|
@@ -184,10 +221,11 @@ function createTool(options) {
|
|
|
184
221
|
return new Tool(options);
|
|
185
222
|
}
|
|
186
223
|
/**
|
|
187
|
-
*
|
|
224
|
+
* Creates an empty registry that advertises definitions and executes calls with
|
|
225
|
+
* per-call error isolation, returned as a `ToolManagerInterface` so a caller holds the
|
|
226
|
+
* published contract rather than the `ToolManager` class.
|
|
188
227
|
*
|
|
189
|
-
* @returns A registry
|
|
190
|
-
* error isolation
|
|
228
|
+
* @returns A registry bound to no tools
|
|
191
229
|
*
|
|
192
230
|
* @example
|
|
193
231
|
* ```ts
|
|
@@ -206,6 +244,6 @@ function createToolManager() {
|
|
|
206
244
|
return new ToolManager();
|
|
207
245
|
}
|
|
208
246
|
//#endregion
|
|
209
|
-
export { Tool, ToolManager, createTool, createToolManager, isToolCall };
|
|
247
|
+
export { Tool, ToolManager, createTool, createToolManager, isToolCall, toolToDefinition };
|
|
210
248
|
|
|
211
249
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#execute","#tools","#definition","#run"],"sources":["../../../src/core/validators.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. 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` 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, 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'\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. Optional\n * 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) => 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 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\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
|
+
{"version":3,"file":"index.js","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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orkestrel/tool",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
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",
|
|
@@ -45,40 +45,43 @@
|
|
|
45
45
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
46
46
|
"copy": "node -e \"const fs=require('node:fs'),p=require('node:path'),a=process.argv[1],b=process.argv[2];fs.mkdirSync(p.dirname(b),{recursive:true});fs.cpSync(a,b,{force:true});console.log('Copied: '+a+' to '+b)\"",
|
|
47
47
|
"scaffold": "scaffold",
|
|
48
|
-
"lint": "oxlint --config .oxlintrc.json --fix
|
|
48
|
+
"lint": "oxlint --config .oxlintrc.json --fix .",
|
|
49
49
|
"check": "tsc --noEmit --project tsconfig.json && npm run check:src",
|
|
50
50
|
"check:src": "npm run check:src:core",
|
|
51
51
|
"check:src:core": "tsc --noEmit -p configs/src/tsconfig.core.json",
|
|
52
52
|
"format": "oxfmt --config .oxfmtrc.json --write .",
|
|
53
53
|
"format:check": "oxfmt --config .oxfmtrc.json --check .",
|
|
54
54
|
"lint:check": "oxlint --config .oxlintrc.json --deny-warnings .",
|
|
55
|
-
"test": "npm run test:src && npm run test:policy && npm run test:config && npm run test:guides",
|
|
55
|
+
"test": "npm run test:src && npm run test:policy && npm run test:config && npm run test:setup && npm run test:guides",
|
|
56
56
|
"test:src": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core",
|
|
57
57
|
"test:src:core": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core",
|
|
58
58
|
"test:policy": "vitest run --config vite.config.ts --no-cache --reporter=dot --project policy",
|
|
59
59
|
"test:config": "vitest run --config vite.config.ts --no-cache --reporter=dot --project config",
|
|
60
|
-
"test:guides": "
|
|
60
|
+
"test:guides": "node --experimental-strip-types tests/guides.test.ts",
|
|
61
61
|
"build": "npm run clean && npm run build:src",
|
|
62
62
|
"build:src": "npm run build:src:core",
|
|
63
63
|
"build:src:core": "vite build --config configs/src/vite.core.config.ts && npm run copy dist/src/core/index.d.ts dist/src/core/index.d.cts",
|
|
64
|
-
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test"
|
|
64
|
+
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test && npm run test:distribution -- --mode release",
|
|
65
|
+
"test:distribution": "vitest run --config vite.config.ts --no-cache --reporter=dot --project distribution",
|
|
66
|
+
"test:probe": "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe",
|
|
67
|
+
"test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
|
|
68
|
+
"prepack": "npm run build",
|
|
69
|
+
"test:setup": "vitest run --config vite.config.ts --no-cache --reporter=dot --project setup"
|
|
65
70
|
},
|
|
66
71
|
"dependencies": {
|
|
67
|
-
"@orkestrel/contract": "^0.0.
|
|
72
|
+
"@orkestrel/contract": "^0.0.17"
|
|
68
73
|
},
|
|
69
74
|
"devDependencies": {
|
|
70
75
|
"@microsoft/api-extractor": "^7.59.0",
|
|
71
|
-
"@orkestrel/guide": "^0.0.
|
|
72
|
-
"@orkestrel/probe": "^0.0.
|
|
73
|
-
"@orkestrel/scaffold": "^0.0.
|
|
74
|
-
"@orkestrel/test": "^0.0.
|
|
75
|
-
"@types/node": "^26.
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"oxlint": "^1.79.0",
|
|
76
|
+
"@orkestrel/guide": "^0.0.17",
|
|
77
|
+
"@orkestrel/probe": "^0.0.12",
|
|
78
|
+
"@orkestrel/scaffold": "^0.0.63",
|
|
79
|
+
"@orkestrel/test": "^0.0.14",
|
|
80
|
+
"@types/node": "^26.4.1",
|
|
81
|
+
"oxfmt": "^0.66.0",
|
|
82
|
+
"oxlint": "^1.81.0",
|
|
79
83
|
"typescript": "^6.0.3",
|
|
80
84
|
"vite": "^8.2.2",
|
|
81
|
-
"vite-plugin-dts": "^5.0.3",
|
|
82
85
|
"vitest": "^4.1.11"
|
|
83
86
|
},
|
|
84
87
|
"engines": {
|