@orkestrel/tool 0.0.6 → 0.0.7
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 +51 -33
- package/dist/src/core/index.cjs +133 -3297
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +215 -2565
- package/dist/src/core/index.d.ts +215 -2565
- package/dist/src/core/index.js +130 -3193
- package/dist/src/core/index.js.map +1 -1
- package/package.json +12 -31
- package/dist/src/server/index.cjs +0 -267
- package/dist/src/server/index.cjs.map +0 -1
- package/dist/src/server/index.d.cts +0 -167
- package/dist/src/server/index.d.ts +0 -167
- package/dist/src/server/index.js +0 -262
- package/dist/src/server/index.js.map +0 -1
package/dist/src/core/index.d.ts
CHANGED
|
@@ -1,2649 +1,299 @@
|
|
|
1
|
-
import { AgentInterface } from '@orkestrel/agent';
|
|
2
|
-
import { AgentRegistryInterface } from '@orkestrel/agent';
|
|
3
|
-
import { ArrayShape } from '@orkestrel/contract';
|
|
4
|
-
import { BooleanShape } from '@orkestrel/contract';
|
|
5
|
-
import { ColumnSchema } from '@orkestrel/database';
|
|
6
|
-
import { Condition } from '@orkestrel/database';
|
|
7
|
-
import { Connector } from '@orkestrel/database';
|
|
8
|
-
import { ContractInterface } from '@orkestrel/contract';
|
|
9
|
-
import { ContractShape } from '@orkestrel/contract';
|
|
10
|
-
import { ConversationStoreInterface } from '@orkestrel/agent';
|
|
11
|
-
import { Criteria } from '@orkestrel/database';
|
|
12
|
-
import { DatabaseErrorCode } from '@orkestrel/database';
|
|
13
|
-
import { DatabaseInterface } from '@orkestrel/database';
|
|
14
|
-
import { Direction } from '@orkestrel/database';
|
|
15
|
-
import { DriverInterface } from '@orkestrel/database';
|
|
16
|
-
import { Include } from '@orkestrel/relation';
|
|
17
|
-
import { JSONShape } from '@orkestrel/contract';
|
|
18
|
-
import { KeyFunction } from '@orkestrel/database';
|
|
19
|
-
import { LiteralShape } from '@orkestrel/contract';
|
|
20
|
-
import { ModelInterface } from '@orkestrel/relation';
|
|
21
|
-
import { NumberShape } from '@orkestrel/contract';
|
|
22
|
-
import { ObjectShape } from '@orkestrel/contract';
|
|
23
|
-
import { OptionalShape } from '@orkestrel/contract';
|
|
24
|
-
import { PromptType } from '@orkestrel/terminal';
|
|
25
|
-
import { RelationErrorCode } from '@orkestrel/relation';
|
|
26
|
-
import { RelationManagerInterface } from '@orkestrel/relation';
|
|
27
|
-
import { StringShape } from '@orkestrel/contract';
|
|
28
|
-
import { TableInterface } from '@orkestrel/database';
|
|
29
|
-
import { TableSchema } from '@orkestrel/database';
|
|
30
|
-
import { TablesShape } from '@orkestrel/database';
|
|
31
|
-
import { TerminalManagerInterface } from '@orkestrel/terminal';
|
|
32
|
-
import { ToolInterface } from '@orkestrel/agent';
|
|
33
|
-
import { ToolManagerInterface } from '@orkestrel/agent';
|
|
34
|
-
import { UnionShape } from '@orkestrel/contract';
|
|
35
|
-
import { WorkflowDefinition } from '@orkestrel/workflow';
|
|
36
|
-
import { WorkflowFunction } from '@orkestrel/workflow';
|
|
37
|
-
import { WorkflowResult } from '@orkestrel/workflow';
|
|
38
|
-
import { WorkflowRunnerInterface } from '@orkestrel/workflow';
|
|
39
|
-
import { WorkflowStatus } from '@orkestrel/workflow';
|
|
40
|
-
import { WorkflowStoreInterface } from '@orkestrel/workflow';
|
|
41
|
-
import { WorkspaceManagerInterface } from '@orkestrel/agent';
|
|
42
|
-
import { WorkspaceStoreInterface } from '@orkestrel/agent';
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* The maximum nesting depth a delegation chain (agent tool → sub-agent → agent tool → …) may
|
|
46
|
-
* reach — the bound {@link import('./factories.js').createAgentTool}'s depth/cycle guard
|
|
47
|
-
* enforces.
|
|
48
|
-
*
|
|
49
|
-
* @remarks
|
|
50
|
-
* Deliberately a SEPARATE constant from {@link MAX_WORKFLOW_DEPTH} (rather than the two guards
|
|
51
|
-
* sharing one reference): the two guards bound DIFFERENT chains (workflow nesting vs. agent
|
|
52
|
-
* delegation) that happen to share a value today, and keeping this bound decoupled means a
|
|
53
|
-
* future change to one never silently shifts the other. Same numeric value by convention, not
|
|
54
|
-
* by shared reference.
|
|
55
|
-
*/
|
|
56
|
-
export declare const AGENT_TOOL_DEPTH = 8;
|
|
57
|
-
|
|
58
|
-
export declare const AGENT_TOOL_DESCRIPTION: string;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* The name {@link import('./factories.js').createAgentTool} advertises by default — the key a
|
|
62
|
-
* model calls and the `ToolManagerInterface` (`@orkestrel/agent`) registers under.
|
|
63
|
-
*/
|
|
64
|
-
export declare const AGENT_TOOL_NAME = "agent";
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* The lean {@link import('@orkestrel/agent').ToolInterface.summary} {@link import('./factories.js').createAgentTool}
|
|
68
|
-
* advertises in place of {@link AGENT_TOOL_DESCRIPTION} — a `ToolManagerInterface.definitions()`
|
|
69
|
-
* (`@orkestrel/agent`) advertises `summary ?? description`, so this one-sentence text stands in
|
|
70
|
-
* for the full teaching description; the full text stays retrievable via
|
|
71
|
-
* {@link import('./factories.js').createDescribeTool}.
|
|
72
|
-
*/
|
|
73
|
-
export declare const AGENT_TOOL_SUMMARY = "Delegate a task to a sub-agent and return its result; each call runs one sub-agent turn to completion. Call describe('agent') for the optional provider/tools/system overrides.";
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Options for {@link import('./factories.js').createAgentFunction} — the OPT-IN adapter that
|
|
77
|
-
* wraps a live `AgentInterface` (`@orkestrel/agent`) as a `WorkflowFunction`
|
|
78
|
-
* (`@orkestrel/workflow`), folding a nested workflow-authoring depth / cycle guard into its
|
|
79
|
-
* closure.
|
|
80
|
-
*
|
|
81
|
-
* @remarks
|
|
82
|
-
* All fields are optional: omitted entirely, the adapter runs the agent with no nested workflow
|
|
83
|
-
* tool bound and no depth/cycle bound (depth `0`, empty ancestry).
|
|
84
|
-
* - `runner` — when supplied, the adapter BINDS a depth/cycle-aware
|
|
85
|
-
* {@link import('./factories.js').createWorkflowTool} onto the agent's `context.tools` (the
|
|
86
|
-
* propagation seam), so the agent can author + run a NESTED workflow through it. Omitted ⇒ the
|
|
87
|
-
* agent runs with no workflow tool bound.
|
|
88
|
-
* - `depth` — this invocation's nesting depth (default `0`); the bound workflow tool runs its
|
|
89
|
-
* nested workflow at `depth + 1`, bounded by
|
|
90
|
-
* {@link import('./constants.js').MAX_WORKFLOW_DEPTH}.
|
|
91
|
-
* - `ancestry` — the workflow / agent identifiers already in this run chain (default empty); a
|
|
92
|
-
* cycle (this agent already present) is rejected with a typed `DEPTH` `WorkflowError`
|
|
93
|
-
* (`@orkestrel/workflow`).
|
|
94
|
-
*/
|
|
95
|
-
export declare interface AgentFunctionOptions {
|
|
96
|
-
readonly runner?: WorkflowRunnerInterface;
|
|
97
|
-
readonly depth?: number;
|
|
98
|
-
readonly ancestry?: readonly string[];
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* The ancestry identifier of an agent in a run chain — `agent:<name>`.
|
|
103
|
-
*
|
|
104
|
-
* @remarks
|
|
105
|
-
* The agent counterpart of {@link workflowTag}: {@link import('./factories.js').createAgentFunction}
|
|
106
|
-
* / {@link import('./factories.js').createWorkflowTool} guard against re-entering an agent or
|
|
107
|
-
* workflow already in the chain (a typed `DEPTH` `WorkflowError`, `@orkestrel/workflow`). The
|
|
108
|
-
* `agent:` namespace keeps it distinct from a same-string workflow id.
|
|
109
|
-
*
|
|
110
|
-
* @param name - The agent's identifier / registry name
|
|
111
|
-
* @returns The namespaced ancestry tag (`agent:<name>`)
|
|
112
|
-
*/
|
|
113
|
-
export declare function agentTag(name: string): string;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* The FLAT args {@link import('./factories.js').createAgentTool} accepts — a delegated `task`
|
|
117
|
-
* plus the minimal optional `AgentJobInput` (`@orkestrel/agent`) fields a caller may override
|
|
118
|
-
* per-call.
|
|
119
|
-
*
|
|
120
|
-
* @remarks
|
|
121
|
-
* `task` becomes the seed user message in the sub-agent's rehydrated conversation
|
|
122
|
-
* (`AgentJobInput.messages`). `provider` / `tools` / `system` shadow the tool's own
|
|
123
|
-
* {@link AgentToolOptions} defaults for this ONE call when supplied.
|
|
124
|
-
*/
|
|
125
|
-
export declare interface AgentToolArguments {
|
|
126
|
-
readonly task: string;
|
|
127
|
-
readonly provider?: string;
|
|
128
|
-
readonly tools?: readonly string[];
|
|
129
|
-
readonly system?: string;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Thrown by {@link import('./factories.js').createAgentTool}'s and
|
|
134
|
-
* {@link import('./factories.js').createDescribeTool}'s handlers on every failure path — a
|
|
135
|
-
* malformed / unresolvable call or an unknown tool name (`TOOL`), a delegation that would
|
|
136
|
-
* exceed the configured depth bound or re-enter an ancestor (`DEPTH`), a prompt cycle
|
|
137
|
-
* (`DEADLOCK`), a prompt that expired before it was answered (`EXPIRE`), or an answer that
|
|
138
|
-
* failed to apply (`ANSWER`) — the last three thrown by
|
|
139
|
-
* {@link import('./factories.js').createPromptTool} / {@link import('./factories.js').createAnswerTool}.
|
|
140
|
-
* The upcoming database / relation tools (SRC-1's later units) will throw it too: a typed
|
|
141
|
-
* `@orkestrel/database` failure re-surfaces as `DATABASE`, a typed `@orkestrel/relation` failure
|
|
142
|
-
* as `RELATION` — each carrying the package's own granular error code in `context`.
|
|
143
|
-
*
|
|
144
|
-
* @remarks
|
|
145
|
-
* Carries a machine-readable `code` (see {@link import('./types.js').AgentToolErrorCode}) and
|
|
146
|
-
* an optional `context` bag for structured diagnostics. The `ToolManagerInterface`
|
|
147
|
-
* (`@orkestrel/agent`) isolates every throw into the canonical tool result's top-level `error`
|
|
148
|
-
* (AGENTS §14) — nothing escapes the run.
|
|
149
|
-
*
|
|
150
|
-
* @example
|
|
151
|
-
* ```ts
|
|
152
|
-
* import { AgentToolError, isAgentToolError } from '@src/core'
|
|
153
|
-
*
|
|
154
|
-
* try {
|
|
155
|
-
* throw new AgentToolError('TOOL', 'task is required')
|
|
156
|
-
* } catch (error) {
|
|
157
|
-
* if (isAgentToolError(error)) console.log(error.code) // 'TOOL'
|
|
158
|
-
* }
|
|
159
|
-
* ```
|
|
160
|
-
*/
|
|
161
|
-
export declare class AgentToolError extends Error {
|
|
162
|
-
readonly code: AgentToolErrorCode;
|
|
163
|
-
readonly context?: Readonly<Record<string, unknown>>;
|
|
164
|
-
constructor(code: AgentToolErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* The error CODE a thrown {@link import('./errors.js').AgentToolError} carries — the SAME
|
|
169
|
-
* two-code shape `@orkestrel/workflow`'s `WorkflowError` uses for its own tool guard, kept
|
|
170
|
-
* distinct per package (AGENTS §14: a thrown, typed, code-bearing error, never a `{ error }`
|
|
171
|
-
* return).
|
|
172
|
-
*
|
|
173
|
-
* @remarks
|
|
174
|
-
* `TOOL` — malformed / unresolvable call args (a missing `task`, no resolvable `provider`).
|
|
175
|
-
* `DEPTH` — the delegation would exceed {@link import('./constants.js').AGENT_TOOL_DEPTH}, or
|
|
176
|
-
* the resolved agent is already an ancestor (a cycle).
|
|
177
|
-
* `DEADLOCK` — an `ask` call ({@link import('./factories.js').createPromptTool}) would form a
|
|
178
|
-
* prompt cycle (`TerminalManagerInterface.ask`, `@orkestrel/terminal`, rejects with its own
|
|
179
|
-
* `TerminalError('DEADLOCK')`, re-surfaced here).
|
|
180
|
-
* `EXPIRE` — the addressed prompt expired before it was answered.
|
|
181
|
-
* `ANSWER` — {@link import('./factories.js').createAnswerTool}'s answer call failed to apply
|
|
182
|
-
* (an unknown prompt id, a rejected value, or the terminal itself unknown —
|
|
183
|
-
* `TerminalAnswerResult.error`, `@orkestrel/terminal`).
|
|
184
|
-
* `DATABASE` — a typed `@orkestrel/database` failure (`DatabaseError`), re-surfaced with the
|
|
185
|
-
* granular {@link import('@orkestrel/database').DatabaseErrorCode} carried in `context`.
|
|
186
|
-
* `RELATION` — a typed `@orkestrel/relation` failure (`RelationError`), re-surfaced with the
|
|
187
|
-
* granular {@link import('@orkestrel/relation').RelationErrorCode} carried in `context`.
|
|
188
|
-
*/
|
|
189
|
-
export declare type AgentToolErrorCode = 'TOOL' | 'DEPTH' | 'DEADLOCK' | 'EXPIRE' | 'ANSWER' | 'DATABASE' | 'RELATION';
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Options for {@link import('./factories.js').createAgentTool} — the sub-agent delegation
|
|
193
|
-
* defaults, the nesting-depth / cycle guard bookkeeping, and the advertised tool overrides.
|
|
194
|
-
*
|
|
195
|
-
* @remarks
|
|
196
|
-
* - `name` / `description` — advertised tool overrides; default to
|
|
197
|
-
* {@link import('./constants.js').AGENT_TOOL_NAME} / {@link import('./constants.js').AGENT_TOOL_DESCRIPTION}.
|
|
198
|
-
* - `provider` — the DEFAULT registry provider key used when a call omits `provider`; a call
|
|
199
|
-
* that supplies its own `provider` overrides this. One of `provider` (here or per-call) MUST
|
|
200
|
-
* resolve, or the handler throws a typed `TOOL` {@link import('./errors.js').AgentToolError}.
|
|
201
|
-
* - `tools` — the DEFAULT registry tool-name list loaded into the delegated sub-agent; a
|
|
202
|
-
* per-call `tools` list overrides (never merges with) this default.
|
|
203
|
-
* - `system` — the DEFAULT system prompt seeding the sub-agent's context; a per-call `system`
|
|
204
|
-
* overrides this.
|
|
205
|
-
* - `depth` — this invocation's nesting depth (default `0`); a delegated sub-agent that itself
|
|
206
|
-
* calls this tool again runs at `depth + 1`, bounded by
|
|
207
|
-
* {@link import('./constants.js').AGENT_TOOL_DEPTH}.
|
|
208
|
-
* - `ancestry` — the sub-agent identifiers already in this delegation chain (default empty); a
|
|
209
|
-
* cycle (the resolved agent already present) is rejected with a typed `DEPTH`
|
|
210
|
-
* {@link import('./errors.js').AgentToolError}.
|
|
211
|
-
* - `store` — this package's ADDITION: when supplied, the handler persists the delegated
|
|
212
|
-
* sub-agent's active conversation snapshot (`store.set(agent.context.conversations.active.snapshot())`)
|
|
213
|
-
* once `agent.generate()` settles successfully, before returning — one snapshot per delegation
|
|
214
|
-
* (each `registry.build` mints a fresh conversation id, so a shared store accumulates an
|
|
215
|
-
* audit log rather than colliding). Omitted ⇒ no persistence from this tool.
|
|
216
|
-
*
|
|
217
|
-
* Conversation persistence for a delegated sub-agent has TWO independent seams, composable
|
|
218
|
-
* together: this `store` slot persists EACH delegation's conversation individually, and/or an
|
|
219
|
-
* `AgentRegistryInterface` built with `AgentRegistryOptions.store` (`@orkestrel/agent`) backs
|
|
220
|
-
* EVERY agent it builds — including ones built through this tool — with a store-backed
|
|
221
|
-
* `ConversationManagerInterface` of its own. Neither is required; either or both may be used.
|
|
222
|
-
*/
|
|
223
|
-
export declare interface AgentToolOptions {
|
|
224
|
-
readonly name?: string;
|
|
225
|
-
readonly description?: string;
|
|
226
|
-
readonly provider?: string;
|
|
227
|
-
readonly tools?: readonly string[];
|
|
228
|
-
readonly system?: string;
|
|
229
|
-
readonly depth?: number;
|
|
230
|
-
readonly ancestry?: readonly string[];
|
|
231
|
-
readonly store?: ConversationStoreInterface;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* The shape of {@link import('./types.js').AgentToolArguments} —
|
|
236
|
-
* {@link import('./factories.js').createAgentTool}'s advertised `parameters`.
|
|
237
|
-
*
|
|
238
|
-
* @remarks
|
|
239
|
-
* `task` is the only required field (a non-empty string); `provider` / `tools` / `system`
|
|
240
|
-
* are per-call overrides of the tool's own configured defaults.
|
|
241
|
-
*/
|
|
242
|
-
export declare const agentToolShape: ObjectShape<{
|
|
243
|
-
task: StringShape;
|
|
244
|
-
provider: OptionalShape<StringShape>;
|
|
245
|
-
tools: OptionalShape<ArrayShape<StringShape>>;
|
|
246
|
-
system: OptionalShape<StringShape>;
|
|
247
|
-
}, false>;
|
|
248
|
-
|
|
249
|
-
export declare const ANSWER_TOOL_DESCRIPTION: string;
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* The name {@link import('./factories.js').createAnswerTool} advertises by default — the key a
|
|
253
|
-
* model calls and the `ToolManagerInterface` (`@orkestrel/agent`) registers under.
|
|
254
|
-
*/
|
|
255
|
-
export declare const ANSWER_TOOL_NAME = "answer";
|
|
256
|
-
|
|
257
1
|
/**
|
|
258
|
-
*
|
|
259
|
-
* advertises in place of {@link ANSWER_TOOL_DESCRIPTION} — a `ToolManagerInterface.definitions()`
|
|
260
|
-
* (`@orkestrel/agent`) advertises `summary ?? description`, so this one-sentence text stands in
|
|
261
|
-
* for the full teaching description; the full text stays retrievable via
|
|
262
|
-
* {@link import('./factories.js').createDescribeTool}.
|
|
263
|
-
*/
|
|
264
|
-
export declare const ANSWER_TOOL_SUMMARY = "List prompts addressed to this terminal, or answer one by id. Call describe('answer') for the required fields.";
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Options for {@link import('./factories.js').createAnswerTool} — the live
|
|
268
|
-
* {@link TerminalManagerInterface} (`@orkestrel/terminal`) to list / answer prompts through, the
|
|
269
|
-
* terminal name `to`, and the advertised tool overrides.
|
|
270
|
-
*
|
|
271
|
-
* @remarks
|
|
272
|
-
* - `manager` — the terminal manager whose `pending(to)` / `answer(to, id, value)` the tool's
|
|
273
|
-
* handler calls — `pending` lists the prompts currently addressed to `to`, `answer` resolves
|
|
274
|
-
* one by `id`. A failed `answer` (`TerminalAnswerResult.error`) re-surfaces as a typed
|
|
275
|
-
* `ANSWER` {@link import('./errors.js').AgentToolError}.
|
|
276
|
-
* - `to` — the terminal identity this tool lists / answers prompts FOR.
|
|
277
|
-
* - `name` / `description` — advertised tool overrides; default to
|
|
278
|
-
* {@link import('./constants.js').ANSWER_TOOL_NAME} / {@link import('./constants.js').ANSWER_TOOL_DESCRIPTION}.
|
|
279
|
-
*/
|
|
280
|
-
export declare interface AnswerToolOptions {
|
|
281
|
-
readonly manager: TerminalManagerInterface;
|
|
282
|
-
readonly to: string;
|
|
283
|
-
readonly name?: string;
|
|
284
|
-
readonly description?: string;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* The shape of {@link import('./factories.js').createAnswerTool}'s call arguments — discriminated
|
|
289
|
-
* by `operation`: `'pending'` lists the prompts addressed to this tool's terminal, `'answer'`
|
|
290
|
-
* resolves one by `id` with a `value`.
|
|
291
|
-
*
|
|
292
|
-
* @remarks
|
|
293
|
-
* `value`'s type varies by the ORIGINAL prompt's form (`string` for `'input'` / `'password'` /
|
|
294
|
-
* `'select'` / `'editor'`, `boolean` for `'confirm'`, `readonly string[]` for `'checkbox'`) —
|
|
295
|
-
* `unionShape(stringShape(), booleanShape(), arrayShape(stringShape()))` expresses that
|
|
296
|
-
* union directly, so `value` is typed as the full `string | boolean | readonly string[]` union
|
|
297
|
-
* here (no lossy string-only fallback needed).
|
|
298
|
-
*/
|
|
299
|
-
export declare const answerToolShape: UnionShape<readonly [ ObjectShape<{
|
|
300
|
-
operation: LiteralShape<readonly ["pending"]>;
|
|
301
|
-
}, false>, ObjectShape<{
|
|
302
|
-
operation: LiteralShape<readonly ["answer"]>;
|
|
303
|
-
id: StringShape;
|
|
304
|
-
value: UnionShape<readonly [ StringShape, BooleanShape, ArrayShape<StringShape>]>;
|
|
305
|
-
}, false>]>;
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Clamp a `'records'` call's criteria to a row cap, and build the PROBE criteria the caller reads
|
|
309
|
-
* with — the pure leaf {@link import('./factories.js').createDatabaseTool}'s `'records'` operation
|
|
310
|
-
* uses to detect truncation without a separate `count` round trip.
|
|
311
|
-
*
|
|
312
|
-
* @remarks
|
|
313
|
-
* The effective limit is `min(criteria?.limit ?? cap, cap)`, floored at `0` (so a caller can never
|
|
314
|
-
* exceed the configured cap by supplying a larger `criteria.limit`). The returned probe criteria
|
|
315
|
-
* requests ONE MORE row than the effective limit (`limit: effective + 1`) — if storage returns
|
|
316
|
-
* that many, the caller knows the true result was truncated (`rows.length > effective`) and slices
|
|
317
|
-
* back down to `effective` before returning.
|
|
318
|
-
*
|
|
319
|
-
* @example
|
|
320
|
-
* ```ts
|
|
321
|
-
* import { clampCriteria } from '@src/core'
|
|
322
|
-
*
|
|
323
|
-
* const { criteria, limit } = clampCriteria(undefined, 100)
|
|
324
|
-
* // limit === 100, criteria.limit === 101 — a probe fetching one extra row
|
|
325
|
-
* const rows = await table.records(criteria)
|
|
326
|
-
* const truncated = rows.length > limit // true when storage had more than `limit` rows
|
|
327
|
-
* ```
|
|
328
|
-
*
|
|
329
|
-
* @param criteria - The live criteria to clamp (or `undefined`)
|
|
330
|
-
* @param cap - The row-count ceiling
|
|
331
|
-
* @returns The PROBE criteria (`limit` bumped by one) and the effective `limit`
|
|
332
|
-
*/
|
|
333
|
-
export declare function clampCriteria(criteria: Criteria | undefined, cap: number): Readonly<{
|
|
334
|
-
criteria: Criteria;
|
|
335
|
-
limit: number;
|
|
336
|
-
}>;
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Normalize an LLM-supplied answer `value` to the type {@link PromptType} `form` expects, so a
|
|
340
|
-
* caller that only ever emits strings can still answer a typed prompt.
|
|
341
|
-
*
|
|
342
|
-
* @remarks
|
|
343
|
-
* `'confirm'` coerces to a `boolean` — a `boolean` passes through, and the strings `'true'` /
|
|
344
|
-
* `'false'` (case-insensitively) map to it; any other string is truthy-coerced via
|
|
345
|
-
* `Boolean(value)`. `'checkbox'` coerces to `readonly string[]` — an array passes through
|
|
346
|
-
* (stringifying each entry), a comma-separated string splits + trims into one, and any other
|
|
347
|
-
* single (non-comma) string becomes a one-item array. Every other form (`'input'` / `'password'`
|
|
348
|
-
* / `'select'` / `'editor'`) coerces to a plain `string` — a string passes through verbatim; a
|
|
349
|
-
* non-string, non-object scalar (`number` / `boolean`) stringifies via `String(value)`; an
|
|
350
|
-
* object or array (no lossless string form) falls back to `''` rather than serializing garbage.
|
|
351
|
-
* Pure and total — never throws.
|
|
352
|
-
*
|
|
353
|
-
* @param form - The {@link PromptType} the answer is being coerced FOR
|
|
354
|
-
* @param value - The raw, LLM-supplied answer value
|
|
355
|
-
* @returns The coerced answer — `boolean` for `'confirm'`, `readonly string[]` for `'checkbox'`,
|
|
356
|
-
* `string` otherwise
|
|
357
|
-
*/
|
|
358
|
-
export declare function coerceAnswer(form: PromptType, value: unknown): string | boolean | readonly string[];
|
|
359
|
-
|
|
360
|
-
/** One column's declared type — a primitive shorthand, or `integer` for a whole-number `number`. */
|
|
361
|
-
export declare type ColumnKind = 'string' | 'integer' | 'number' | 'boolean';
|
|
362
|
-
|
|
363
|
-
/** A {@link import('./types.js').ColumnKind} literal — the leaf {@link columnSpecShape} wraps. */
|
|
364
|
-
export declare const columnKindShape: LiteralShape<readonly ["string", "integer", "number", "boolean"]>;
|
|
365
|
-
|
|
366
|
-
/** Map a column NAME + its live `@orkestrel/database` `ContractShape` to a {@link ColumnSchema} — the leaf {@link tableSchema} maps over. */
|
|
367
|
-
export declare function columnSchema(name: string, shape: ContractShape): ColumnSchema;
|
|
368
|
-
|
|
369
|
-
/** Compile one {@link ColumnSpec} into its `@orkestrel/database` column shape — the per-column leaf {@link expandTables} maps over. */
|
|
370
|
-
export declare function columnShape(spec: ColumnSpec): ContractShape;
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* One table column's spec — either a bare {@link ColumnKind} shorthand, or `{ type, optional }`
|
|
374
|
-
* when the column may be absent from a row.
|
|
375
|
-
*/
|
|
376
|
-
export declare type ColumnSpec = ColumnKind | Readonly<{
|
|
377
|
-
type: ColumnKind;
|
|
378
|
-
optional?: boolean;
|
|
379
|
-
}>;
|
|
380
|
-
|
|
381
|
-
/** A {@link import('./types.js').ColumnSpec} — a bare {@link columnKindShape}, or `{ type, optional }`. */
|
|
382
|
-
export declare const columnSpecShape: UnionShape<readonly [ LiteralShape<readonly ["string", "integer", "number", "boolean"]>, ObjectShape<{
|
|
383
|
-
type: LiteralShape<readonly ["string", "integer", "number", "boolean"]>;
|
|
384
|
-
optional: OptionalShape<BooleanShape>;
|
|
385
|
-
}, false>]>;
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* Complete a {@link WorkflowDraft} into a strict {@link WorkflowDefinition} — synthesize any
|
|
389
|
-
* MISSING `id` deterministically + positionally, and default any MISSING `name` to its
|
|
390
|
-
* (now-resolved) `id`.
|
|
391
|
-
*
|
|
392
|
-
* @remarks
|
|
393
|
-
* The positional id scheme is stable and human-legible: the workflow is `wf`, phase `i` is
|
|
394
|
-
* `phase-<i>`, and task `j` of that phase is `<phaseId>-task-<j>` (so a provided phase id flows
|
|
395
|
-
* into its tasks' synthesized ids). A PROVIDED `id` / `name` at any level is kept VERBATIM —
|
|
396
|
-
* synthesis touches only the omitted ones. A missing `name` defaults to the resolved `id` (never
|
|
397
|
-
* the other way round), so the result always has both. `run`, `description`, the per-phase
|
|
398
|
-
* `concurrency` / `bail`, the per-task `retries` / `timeout`, and the workflow `bail` carry over
|
|
399
|
-
* unchanged. The result is a complete {@link WorkflowDefinition}; the caller still validates it
|
|
400
|
-
* against the STRICT contract.
|
|
401
|
-
*
|
|
402
|
-
* @param draft - The draft workflow (id/name optional at all three levels)
|
|
403
|
-
* @returns A complete {@link WorkflowDefinition} with every id/name filled
|
|
404
|
-
*/
|
|
405
|
-
export declare function completeDraft(draft: WorkflowDraft): WorkflowDefinition;
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Complete one {@link PhaseDraft} into a strict phase definition — the per-phase step of
|
|
409
|
-
* {@link completeDraft} (phase `index` → `phase-<index>` when its id is omitted).
|
|
410
|
-
*
|
|
411
|
-
* @param phase - The draft phase
|
|
412
|
-
* @param index - The phase's positional index in the workflow
|
|
413
|
-
* @returns A complete phase definition
|
|
414
|
-
*/
|
|
415
|
-
export declare function completePhaseDraft(phase: PhaseDraft, index: number): WorkflowDefinition['phases'][number];
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* Complete one {@link TaskDraft} into a strict task definition — the per-task leaf step of
|
|
419
|
-
* {@link completeDraft} (task `index` of phase `<phaseId>` → `<phaseId>-task-<index>` when its id
|
|
420
|
-
* is omitted).
|
|
421
|
-
*
|
|
422
|
-
* @param task - The draft task
|
|
423
|
-
* @param phaseId - The (resolved) parent phase id, so the synthesized task id nests under it
|
|
424
|
-
* @param index - The task's positional index within its phase
|
|
425
|
-
* @returns A complete task definition
|
|
426
|
-
*/
|
|
427
|
-
export declare function completeTaskDraft(task: TaskDraft, phaseId: string, index: number): WorkflowDefinition['phases'][number]['tasks'][number];
|
|
428
|
-
|
|
429
|
-
/** One SERIALIZED WHERE condition — `values` is ALWAYS an array, even for a single-value operator. */
|
|
430
|
-
export declare const conditionShape: ObjectShape<{
|
|
431
|
-
column: StringShape;
|
|
432
|
-
operator: LiteralShape<readonly ["equals", "not", "above", "below", "from", "to", "between", "like", "glob", "starts", "ends", "any", "none", "absent", "present"]>;
|
|
433
|
-
values: ArrayShape<JSONShape>;
|
|
434
|
-
connector: OptionalShape<LiteralShape<readonly ["and", "or"]>>;
|
|
435
|
-
}, false>;
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Wrap a live `AgentInterface` (`@orkestrel/agent`) as a {@link WorkflowFunction}
|
|
439
|
-
* (`@orkestrel/workflow`) — the OPT-IN adapter that runs the agent to a settled result, folding
|
|
440
|
-
* a nested workflow-authoring depth / cycle guard into its own closure.
|
|
441
|
-
*
|
|
442
|
-
* @remarks
|
|
443
|
-
* OWNED here now (ported from `@orkestrel/workflow`). Composes into a caller's
|
|
444
|
-
* `WorkflowOptions.functions` registry like any other behavior; the pure workflow runner has no
|
|
445
|
-
* knowledge of agents itself. Before running the agent, the depth/cycle guard REJECTS the call
|
|
446
|
-
* (a THROWN typed `DEPTH` `WorkflowError`, which the leaf `fail`s) when running it would push a
|
|
447
|
-
* nested chain past {@link import('./constants.js').MAX_WORKFLOW_DEPTH}, OR when this agent is
|
|
448
|
-
* already an ancestor (a cycle). When {@link import('./types.js').AgentFunctionOptions.runner}
|
|
449
|
-
* is supplied, the adapter BINDS a depth/cycle-aware {@link createWorkflowTool} onto the agent's
|
|
450
|
-
* `context.tools` (the propagation seam) — closed over `depth` and the extended ancestry (the
|
|
451
|
-
* tool itself computes `depth + 1` internally) — so the agent can author + run a NESTED workflow
|
|
452
|
-
* through it; the wrapped default is the CURRENT task's own workflow id (used only on a no-args
|
|
453
|
-
* tool call). The task's cancellation folds into the agent run: an already-aborted
|
|
454
|
-
* `controller.signal` cancels the agent up front; otherwise a one-shot listener fires
|
|
455
|
-
* `agent.abort(reason)` when the task cancels, removed in `finally`. `agent.generate()` resolves
|
|
456
|
-
* a partial `AgentResult` on a cancel (never rejects), returned as the task's completed value.
|
|
457
|
-
*
|
|
458
|
-
* A bound agent is effectively SINGLE-RUN: `context.tools.add` binds one `ToolInterface` under
|
|
459
|
-
* the fixed {@link import('./constants.js').WORKFLOW_TOOL_NAME}, and `agent.generate()` /
|
|
460
|
-
* `agent.abort()` are per-agent state. Two CONCURRENT tasks sharing the SAME `agent` instance
|
|
461
|
-
* race on that one tool binding (last-write-wins) and on generate/abort — give each concurrent
|
|
462
|
-
* task its OWN agent instance.
|
|
2
|
+
* Create an executable tool.
|
|
463
3
|
*
|
|
464
|
-
* @param
|
|
465
|
-
* @
|
|
466
|
-
* @returns A {@link WorkflowFunction} that runs `agent` to its settled result
|
|
4
|
+
* @param options - The advertised definition and execution handler
|
|
5
|
+
* @returns A tool bound to the supplied handler
|
|
467
6
|
*
|
|
468
7
|
* @example
|
|
469
8
|
* ```ts
|
|
470
|
-
* import {
|
|
471
|
-
* import { createWorkflowRunner } from '@orkestrel/workflow'
|
|
9
|
+
* import { createTool } from '@orkestrel/tool'
|
|
472
10
|
*
|
|
473
|
-
* const
|
|
474
|
-
*
|
|
475
|
-
*
|
|
11
|
+
* const add = createTool({
|
|
12
|
+
* name: 'add',
|
|
13
|
+
* description: 'Add two numbers',
|
|
14
|
+
* execute: (args) => Number(args.a) + Number(args.b),
|
|
15
|
+
* })
|
|
476
16
|
* ```
|
|
477
17
|
*/
|
|
478
|
-
export declare function
|
|
18
|
+
export declare function createTool(options: ToolOptions): ToolInterface;
|
|
479
19
|
|
|
480
20
|
/**
|
|
481
|
-
*
|
|
482
|
-
* from `registry` and runs it to completion for ONE delegated `task`.
|
|
483
|
-
*
|
|
484
|
-
* @remarks
|
|
485
|
-
* The universal tool-handler contract (AGENTS §14): validates the call args against
|
|
486
|
-
* {@link import('./shapers.js').agentToolShape}, assembles an `AgentJobInput` (`task` seeds the
|
|
487
|
-
* sub-agent's conversation as a single `user` message; `provider` / `tools` / `system` fall
|
|
488
|
-
* back to the tool's own {@link import('./types.js').AgentToolOptions} defaults), rehydrates the sub-agent via
|
|
489
|
-
* `registry.build`, runs it with `agent.generate()`, and returns the settled
|
|
490
|
-
* `AgentResult.content` string (the sub-agent's final text). A missing / unresolvable `provider`, or a malformed call, THROWS a typed `TOOL`
|
|
491
|
-
* {@link import('./errors.js').AgentToolError}; a delegation that would exceed
|
|
492
|
-
* {@link import('./constants.js').AGENT_TOOL_DEPTH}, or re-enter an already-delegated agent (a
|
|
493
|
-
* cycle), THROWS a typed `DEPTH` {@link import('./errors.js').AgentToolError} — both isolated
|
|
494
|
-
* by the `ToolManagerInterface` into the canonical tool result's top-level `error`.
|
|
495
|
-
*
|
|
496
|
-
* `AgentInterface` (`@orkestrel/agent`) exposes no teardown method — a bound sub-agent's
|
|
497
|
-
* lifetime is the single `generate()` call this handler awaits; there is nothing to release
|
|
498
|
-
* afterwards (unlike a store-backed resource, its state lives entirely in the resolved
|
|
499
|
-
* `AgentContextInterface`, owned by the caller's registry).
|
|
21
|
+
* Create an empty tool registry.
|
|
500
22
|
*
|
|
501
|
-
* @
|
|
502
|
-
*
|
|
503
|
-
* @param options - Delegation defaults, depth/ancestry bookkeeping, and advertised overrides
|
|
504
|
-
* (see {@link import('./types.js').AgentToolOptions})
|
|
505
|
-
* @returns A `ToolInterface` (named {@link import('./constants.js').AGENT_TOOL_NAME} by default)
|
|
23
|
+
* @returns A registry that advertises definitions and executes calls with per-call
|
|
24
|
+
* error isolation
|
|
506
25
|
*
|
|
507
26
|
* @example
|
|
508
27
|
* ```ts
|
|
509
|
-
* import {
|
|
510
|
-
* import { createAgentRegistry, createToolManager } from '@orkestrel/agent'
|
|
28
|
+
* import { createTool, createToolManager } from '@orkestrel/tool'
|
|
511
29
|
*
|
|
512
|
-
* const registry = createAgentRegistry({ providers: { openai: myProvider } })
|
|
513
|
-
* const tool = createAgentTool(registry, { provider: 'openai' })
|
|
514
30
|
* const tools = createToolManager()
|
|
515
|
-
* tools.add(
|
|
31
|
+
* tools.add(createTool({ name: 'echo', execute: (args) => args.value }))
|
|
32
|
+
* const result = await tools.execute({
|
|
33
|
+
* id: '1',
|
|
34
|
+
* name: 'echo',
|
|
35
|
+
* arguments: { value: 'hello' },
|
|
36
|
+
* })
|
|
516
37
|
* ```
|
|
517
38
|
*/
|
|
518
|
-
export declare function
|
|
39
|
+
export declare function createToolManager(): ToolManagerInterface;
|
|
519
40
|
|
|
520
41
|
/**
|
|
521
|
-
*
|
|
522
|
-
* currently addressed to {@link import('./types.js').AnswerToolOptions.to}, or answers one of
|
|
523
|
-
* them by id.
|
|
42
|
+
* Determine whether an unknown value is structurally a {@link ToolCall}.
|
|
524
43
|
*
|
|
525
44
|
* @remarks
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
* returns a compact list (`{ id, from, form, message }`) of every prompt currently addressed to
|
|
529
|
-
* `to` (`TerminalManagerInterface.pending`, `@orkestrel/terminal`). `'answer'` looks the prompt
|
|
530
|
-
* up by `id` (an unknown id throws a typed `ANSWER` {@link import('./errors.js').AgentToolError}),
|
|
531
|
-
* normalizes the model-supplied `value` to the prompt's own form
|
|
532
|
-
* ({@link import('./helpers.js').coerceAnswer}), and applies it via
|
|
533
|
-
* `TerminalManagerInterface.answer` — a rejected / unknown / unresolvable outcome
|
|
534
|
-
* (`TerminalAnswerResult.error`) re-surfaces as a typed `ANSWER` `AgentToolError`; success returns
|
|
535
|
-
* `{ answered: id }`. `to` is FIXED at construction
|
|
536
|
-
* ({@link import('./types.js').AnswerToolOptions.to}) — never read from the model-supplied args —
|
|
537
|
-
* so a model cannot spoof which terminal it is answering for. Concurrent answerers racing on one
|
|
538
|
-
* endpoint are FIRST-WRITE-WINS — a late answer to an already-settled prompt returns a typed
|
|
539
|
-
* `ANSWER` `AgentToolError` (surfaced as a 422 over HTTP).
|
|
45
|
+
* This total guard accepts a plain record with string `id` and `name` fields and a
|
|
46
|
+
* plain-record `arguments` field. Adversarial values return `false`.
|
|
540
47
|
*
|
|
541
|
-
* @param
|
|
542
|
-
*
|
|
543
|
-
* @returns A `ToolInterface` (named {@link import('./constants.js').ANSWER_TOOL_NAME} by default)
|
|
48
|
+
* @param value - The value to test
|
|
49
|
+
* @returns `true` when the value has the complete tool-call shape
|
|
544
50
|
*
|
|
545
51
|
* @example
|
|
546
52
|
* ```ts
|
|
547
|
-
* import {
|
|
548
|
-
* import { createTerminalManager, createToolManager } from '@orkestrel/terminal'
|
|
53
|
+
* import { isToolCall } from '@orkestrel/tool'
|
|
549
54
|
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
* const tool = createAnswerTool({ manager, to: 'reviewer' })
|
|
553
|
-
* const tools = createToolManager()
|
|
554
|
-
* tools.add(tool) // the reviewer terminal can now list/answer prompts addressed to it
|
|
55
|
+
* isToolCall({ id: '1', name: 'search', arguments: { query: 'birds' } }) // true
|
|
56
|
+
* isToolCall({ id: '1', name: 'search', arguments: [] }) // false
|
|
555
57
|
* ```
|
|
556
58
|
*/
|
|
557
|
-
export declare function
|
|
59
|
+
export declare function isToolCall(value: unknown): value is ToolCall;
|
|
558
60
|
|
|
559
61
|
/**
|
|
560
|
-
*
|
|
561
|
-
* layer — the driver-pluggable twin of {@link createMemoryDefinitionStore}, storing each
|
|
562
|
-
* database's definition as one opaque JSON column.
|
|
62
|
+
* An executable tool definition bound to a handler.
|
|
563
63
|
*
|
|
564
|
-
* @
|
|
565
|
-
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* Schema fields and arguments are forwarded by reference. Handler failures are not
|
|
66
|
+
* caught here; {@link ToolManager} owns per-call error isolation.
|
|
566
67
|
*
|
|
567
68
|
* @example
|
|
568
69
|
* ```ts
|
|
569
|
-
* import {
|
|
570
|
-
*
|
|
571
|
-
* const
|
|
70
|
+
* import { Tool } from '@orkestrel/tool'
|
|
71
|
+
*
|
|
72
|
+
* const tool = new Tool({
|
|
73
|
+
* name: 'add',
|
|
74
|
+
* description: 'Add two numbers',
|
|
75
|
+
* parameters: {
|
|
76
|
+
* type: 'object',
|
|
77
|
+
* properties: { a: { type: 'number' }, b: { type: 'number' } },
|
|
78
|
+
* },
|
|
79
|
+
* execute: (args) => Number(args.a) + Number(args.b),
|
|
80
|
+
* })
|
|
572
81
|
* ```
|
|
573
82
|
*/
|
|
574
|
-
export declare
|
|
83
|
+
export declare class Tool implements ToolInterface {
|
|
84
|
+
#private;
|
|
85
|
+
readonly name: string;
|
|
86
|
+
readonly description?: string;
|
|
87
|
+
readonly summary?: string;
|
|
88
|
+
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
89
|
+
constructor(options: ToolOptions);
|
|
90
|
+
execute(args: Readonly<Record<string, unknown>>): Promise<unknown> | unknown;
|
|
91
|
+
}
|
|
575
92
|
|
|
576
93
|
/**
|
|
577
|
-
*
|
|
578
|
-
* databases through one `operation`-discriminated call (AGENTS §14, matching
|
|
579
|
-
* {@link createWorkspaceTool}'s single-tool-many-operations shape).
|
|
94
|
+
* A tool call issued by a caller.
|
|
580
95
|
*
|
|
581
96
|
* @remarks
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
* RETURNS a plain result on success. A database is resolved lazily and cached for the tool's
|
|
585
|
-
* lifetime — `'create'` mints one from `tables` ({@link import('./helpers.js').expandTables}) and
|
|
586
|
-
* a registered `driver` key ({@link import('./types.js').DatabaseToolOptions.drivers}, default
|
|
587
|
-
* `{ memory: () => createMemoryDriver() }`); any other operation addressing an uncached id falls
|
|
588
|
-
* back to {@link import('./types.js').DatabaseToolOptions.store} (an unknown id throws a typed
|
|
589
|
-
* `TOOL` {@link import('./errors.js').AgentToolError}). When a `store` is configured, `'create'`
|
|
590
|
-
* persists the new {@link import('./types.js').DatabaseDefinition} and `'destroy'` deletes it.
|
|
591
|
-
*
|
|
592
|
-
* `'migrate'` re-declares a LIVE handle's tables via `DatabaseInterface.import` (the SAME driver
|
|
593
|
-
* and storage, a NEW typed view) and calls its `migrate` against the OLD deployed schema —
|
|
594
|
-
* derived from the handle's OWN `export()` (via {@link import('./helpers.js').tableSchema}), so it
|
|
595
|
-
* works for any handle, config-tracked or caller-supplied via
|
|
596
|
-
* {@link import('./types.js').DatabaseToolOptions.databases}. `'records'` clamps its `criteria` to
|
|
597
|
-
* {@link import('./types.js').DatabaseToolOptions.limit} (default
|
|
598
|
-
* {@link import('./constants.js').DATABASE_TOOL_LIMIT}) via
|
|
599
|
-
* {@link import('./helpers.js').clampCriteria}, reporting `truncated` when storage held more rows
|
|
600
|
-
* than the cap. Every operation's `criteria` is normalized via
|
|
601
|
-
* {@link import('./helpers.js').criteriaOf} (defaults an omitted condition `connector` to `'and'`).
|
|
602
|
-
* When {@link import('./types.js').DatabaseToolOptions.readonly} is `true`, every mutating
|
|
603
|
-
* operation throws a typed `TOOL` `AgentToolError` before doing anything. When
|
|
604
|
-
* {@link import('./types.js').DatabaseToolOptions.timeout} is set, every `@orkestrel/database` call
|
|
605
|
-
* this tool makes is given a fresh `AbortSignal.timeout(timeout)`. A typed `@orkestrel/database`
|
|
606
|
-
* failure (`DatabaseError`) re-surfaces as a typed `DATABASE` `AgentToolError` carrying the
|
|
607
|
-
* original {@link import('@orkestrel/database').DatabaseErrorCode} in `context.code`
|
|
608
|
-
* ({@link import('./helpers.js').databaseToolCode}); an `AgentToolError` thrown by this tool's own
|
|
609
|
-
* guards passes through unwrapped.
|
|
610
|
-
*
|
|
611
|
-
* A lazily re-minted database over the DEFAULT in-memory driver yields an EMPTY database — only
|
|
612
|
-
* the {@link import('./types.js').DatabaseDefinition} schema persists in `store`, never rows;
|
|
613
|
-
* durable rows need a persistent driver factory registered in
|
|
614
|
-
* {@link import('./types.js').DatabaseToolOptions.drivers}. `'destroy'` closes whatever handle is
|
|
615
|
-
* cached for the id, including an embedder-supplied
|
|
616
|
-
* {@link import('./types.js').DatabaseToolOptions.databases} handle — the embedder relinquishes
|
|
617
|
-
* that handle's lifecycle to this tool for any id it wires in. This tool assumes the
|
|
618
|
-
* single-writer, non-reentrant model `@orkestrel/database` itself assumes — concurrent calls
|
|
619
|
-
* against one id are NOT serialized by this tool. `'get'` is uncapped by
|
|
620
|
-
* {@link import('./types.js').DatabaseToolOptions.limit} (bounded only by the caller's `key` array
|
|
621
|
-
* size), unlike `'records'` / `'find'` / `'links'`.
|
|
622
|
-
*
|
|
623
|
-
* @param options - The tool's configuration (see {@link import('./types.js').DatabaseToolOptions})
|
|
624
|
-
* @returns A `ToolInterface` (named {@link import('./constants.js').DATABASE_TOOL_NAME} by default)
|
|
625
|
-
*
|
|
626
|
-
* @example
|
|
627
|
-
* ```ts
|
|
628
|
-
* import { createDatabaseTool } from '@src/core'
|
|
629
|
-
*
|
|
630
|
-
* const tool = createDatabaseTool()
|
|
631
|
-
* await tool.execute({
|
|
632
|
-
* operation: 'create',
|
|
633
|
-
* id: 'shop',
|
|
634
|
-
* tables: { products: { columns: { name: 'string', price: 'number' } } },
|
|
635
|
-
* })
|
|
636
|
-
* ```
|
|
97
|
+
* `id` correlates the call with its later {@link ToolResult}. `arguments` is the
|
|
98
|
+
* caller-supplied arguments record.
|
|
637
99
|
*/
|
|
638
|
-
export declare
|
|
100
|
+
export declare interface ToolCall {
|
|
101
|
+
/** The identifier that correlates this call with its result. */
|
|
102
|
+
readonly id: string;
|
|
103
|
+
/** The name of the tool to execute. */
|
|
104
|
+
readonly name: string;
|
|
105
|
+
/** The caller-supplied arguments record. */
|
|
106
|
+
readonly arguments: Readonly<Record<string, unknown>>;
|
|
107
|
+
}
|
|
639
108
|
|
|
640
109
|
/**
|
|
641
|
-
*
|
|
642
|
-
* name — the counterpart to the lean `summary` the other tools in this package advertise
|
|
643
|
-
* (`AGENT_TOOL_SUMMARY` / `WORKFLOW_TOOL_SUMMARY` / `WORKSPACE_TOOL_SUMMARY`).
|
|
110
|
+
* A tool definition advertised to a caller.
|
|
644
111
|
*
|
|
645
112
|
* @remarks
|
|
646
|
-
* `
|
|
647
|
-
* tool.description` — a lean one-sentence summary stands in for a tool's full teaching
|
|
648
|
-
* description when `summary` is set, keeping the advertised tool list compact for a small model.
|
|
649
|
-
* This tool is the on-demand expansion seam: given a registered tool's `name`, it looks the tool
|
|
650
|
-
* up via `tools.tool(name)` and returns its full `description` (falling back to `summary` when a
|
|
651
|
-
* tool has no `description` of its own, then a placeholder when it has neither).
|
|
652
|
-
*
|
|
653
|
-
* The universal tool-handler contract (AGENTS §14): validates the call args against
|
|
654
|
-
* {@link import('./shapers.js').describeToolShape}, RETURNS the plain description string on
|
|
655
|
-
* success, THROWS a typed `TOOL` {@link import('./errors.js').AgentToolError} on a malformed call
|
|
656
|
-
* or an unknown tool name.
|
|
657
|
-
*
|
|
658
|
-
* @param tools - The `ToolManagerInterface` (`@orkestrel/agent`) whose registered tools this
|
|
659
|
-
* tool can describe
|
|
660
|
-
* @returns A `ToolInterface` (named {@link import('./constants.js').DESCRIBE_TOOL_NAME})
|
|
661
|
-
*
|
|
662
|
-
* @example
|
|
663
|
-
* ```ts
|
|
664
|
-
* import { createDescribeTool, createWorkflowTool } from '@src/core'
|
|
665
|
-
* import { createToolManager } from '@orkestrel/agent'
|
|
666
|
-
*
|
|
667
|
-
* const tools = createToolManager()
|
|
668
|
-
* tools.add(createWorkflowTool(definition, runner))
|
|
669
|
-
* tools.add(createDescribeTool(tools))
|
|
670
|
-
* const full = await tools.execute({ id: '1', name: 'describe', arguments: { name: 'workflow' } })
|
|
671
|
-
* full.value // the workflow tool's full teaching description
|
|
672
|
-
* ```
|
|
113
|
+
* `parameters` is an open JSON Schema record describing the arguments the tool accepts.
|
|
673
114
|
*/
|
|
674
|
-
export declare
|
|
115
|
+
export declare interface ToolDefinition {
|
|
116
|
+
/** The name a caller uses to select the tool. */
|
|
117
|
+
readonly name: string;
|
|
118
|
+
/** A description of the tool's behavior. */
|
|
119
|
+
readonly description?: string;
|
|
120
|
+
/** The JSON Schema for the tool's arguments. */
|
|
121
|
+
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
122
|
+
}
|
|
675
123
|
|
|
676
124
|
/**
|
|
677
|
-
*
|
|
678
|
-
* `ToolInterface` — the endpoint half of the "existing API/DB → MCP tool" bridge (the other half,
|
|
679
|
-
* {@link createInferTool}, is a standalone inference utility).
|
|
125
|
+
* An executable tool: its advertised definition plus its local handler.
|
|
680
126
|
*
|
|
681
127
|
* @remarks
|
|
682
|
-
* `
|
|
683
|
-
*
|
|
684
|
-
* `format` / `enum`), wrapping a non-object root as `{ value: <schema> }` via `schemaToObject` —
|
|
685
|
-
* the SAME object-rooted schema is both the ADVERTISED `parameters` and, by default
|
|
686
|
-
* ({@link import('./types.js').EndpointToolOptions.validate} `true`), the ENFORCED contract:
|
|
687
|
-
* `@orkestrel/contract` 0.0.7's `schemaToShape` compiles it ONCE (via `createContract`) into a
|
|
688
|
-
* `ContractInterface` whose `.parse` runs on every call's `args` before `definition.invoke` — a
|
|
689
|
-
* NORMALIZING parse, not a strict type check: a scalar is COERCED to its inferred type where the
|
|
690
|
-
* house parsers coerce (a number to/from a numeric string, a boolean from `'1'`/`'0'`/`'true'`/
|
|
691
|
-
* `'false'`/`1`/`0`), so `definition.invoke` receives the COERCED value (e.g. `7` sent for a
|
|
692
|
-
* string slot arrives as `'7'`), not the raw call value. A call whose `args` fails to parse into
|
|
693
|
-
* a record — a required key missing, or a value not coercible to its slot's type — THROWS a
|
|
694
|
-
* typed `TOOL` {@link import('./errors.js').AgentToolError} carrying the compiled contract's
|
|
695
|
-
* structured `explain` faults, and `definition.invoke` is never called. `format` annotations are
|
|
696
|
-
* NEVER asserted, and a key outside the closed inferred schema is SILENTLY DROPPED rather than
|
|
697
|
-
* rejected (see {@link import('./types.js').EndpointToolOptions.validate}). With
|
|
698
|
-
* `validate: false`, `execute` PASSES THROUGH the model-supplied `args` to `definition.invoke`
|
|
699
|
-
* WITHOUT re-validation — the pre-0.0.7 behavior, preserved as an explicit opt-out. Either way,
|
|
700
|
-
* `invoke`'s return flows back as the tool call's plain result; a throw PROPAGATES uncaught,
|
|
701
|
-
* isolated by the `ToolManagerInterface` (`@orkestrel/agent`) into the canonical error envelope
|
|
702
|
-
* (AGENTS §14) — never caught or re-wrapped here.
|
|
703
|
-
*
|
|
704
|
-
* @param definition - The endpoint's identity, non-empty samples, and local handler (see
|
|
705
|
-
* {@link import('./types.js').EndpointDefinition})
|
|
706
|
-
* @param options - Construction-time inference tuning + the validate opt-out (see
|
|
707
|
-
* {@link import('./types.js').EndpointToolOptions})
|
|
708
|
-
* @returns A `ToolInterface` named `definition.name`
|
|
709
|
-
*
|
|
710
|
-
* @example
|
|
711
|
-
* ```ts
|
|
712
|
-
* import { createEndpointTool } from '@src/core'
|
|
713
|
-
* import { createToolManager } from '@orkestrel/agent'
|
|
714
|
-
*
|
|
715
|
-
* const tool = createEndpointTool({
|
|
716
|
-
* name: 'lookupUser',
|
|
717
|
-
* description: 'Look up a user by id.',
|
|
718
|
-
* samples: [{ id: '1', name: 'Ada' }, { id: '2', name: 'Bob' }],
|
|
719
|
-
* invoke: (args) => ({ id: args.id, name: 'Ada' }),
|
|
720
|
-
* })
|
|
721
|
-
* const tools = createToolManager()
|
|
722
|
-
* tools.add(tool)
|
|
723
|
-
*
|
|
724
|
-
* // conforming args (all required keys present) parse and reach `invoke`
|
|
725
|
-
* const result = await tools.execute({
|
|
726
|
-
* id: 'call-1',
|
|
727
|
-
* name: 'lookupUser',
|
|
728
|
-
* arguments: { id: '1', name: 'Ada' },
|
|
729
|
-
* })
|
|
730
|
-
* // result.value -> { id: '1', name: 'Ada' }
|
|
731
|
-
*
|
|
732
|
-
* // a nonconforming call (id is not coercible to the required string) is rejected before
|
|
733
|
-
* // `invoke` runs
|
|
734
|
-
* const rejected = await tools.execute({
|
|
735
|
-
* id: 'call-2',
|
|
736
|
-
* name: 'lookupUser',
|
|
737
|
-
* arguments: { id: true, name: 'Ada' },
|
|
738
|
-
* })
|
|
739
|
-
* // rejected.error -> the TOOL AgentToolError message
|
|
740
|
-
* ```
|
|
128
|
+
* `summary`, when present, is advertised in place of the full `description` by a
|
|
129
|
+
* {@link ToolManagerInterface}. The full description remains available on the tool.
|
|
741
130
|
*/
|
|
742
|
-
export declare
|
|
131
|
+
export declare interface ToolInterface extends ToolDefinition {
|
|
132
|
+
/** A concise description to advertise in place of the full description. */
|
|
133
|
+
readonly summary?: string;
|
|
134
|
+
/**
|
|
135
|
+
* Execute the tool.
|
|
136
|
+
*
|
|
137
|
+
* @param args - The caller-supplied arguments record
|
|
138
|
+
* @returns The tool's synchronous or asynchronous result
|
|
139
|
+
*/
|
|
140
|
+
execute(args: Readonly<Record<string, unknown>>): Promise<unknown> | unknown;
|
|
141
|
+
}
|
|
743
142
|
|
|
744
143
|
/**
|
|
745
|
-
*
|
|
746
|
-
* utility half of the "existing API/DB → MCP tool" bridge (the other half,
|
|
747
|
-
* {@link createEndpointTool}, wraps one CONCRETE endpoint).
|
|
144
|
+
* An insertion-ordered tool registry with per-call error isolation.
|
|
748
145
|
*
|
|
749
146
|
* @remarks
|
|
750
|
-
*
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
-
*
|
|
754
|
-
* the tool-parameters convention every other `create*Tool` factory advertises), and RETURNS the
|
|
755
|
-
* resulting parameters record. An empty `samples` array fails `inferToolShape`'s `min: 1` bound —
|
|
756
|
-
* `contract.parse` returns `undefined` and the handler throws a typed `TOOL`
|
|
757
|
-
* {@link import('./errors.js').AgentToolError}.
|
|
758
|
-
*
|
|
759
|
-
* When `candidates` is ABSENT, the return is the bare parameters record — unchanged from before
|
|
760
|
-
* this array existed. When `candidates` is PRESENT (any array, including empty), the handler
|
|
761
|
-
* compiles a SEPARATE per-call contract from the RAW inferred schema (via `@orkestrel/contract`'s
|
|
762
|
-
* `schemaToShape`, NOT the `schemaToObject`-wrapped parameters — a bare-value sample checks a
|
|
763
|
-
* bare-value candidate) and returns `{ parameters, checks }`, one check per candidate at the same
|
|
764
|
-
* index. Every entry has a UNIFORM shape — `{ index, valid, coercible }`, with `faults` added ONLY
|
|
765
|
-
* when `valid` is `false`: `valid` is the STRICT guard verdict (`checker.is(candidate)`), the
|
|
766
|
-
* OPPOSITE of {@link createEndpointTool}'s enforcement, which coerces (`7` becomes `'7'` for a
|
|
767
|
-
* string slot) — here a conformance report answers "does this value conform AS-IS": `7` against a
|
|
768
|
-
* string slot is `valid: false`, full stop. `coercible` answers a SEPARATE question — "would the
|
|
769
|
-
* NORMALIZING parse accept this value", i.e. would {@link createEndpointTool}'s default enforcement
|
|
770
|
-
* admit it (`checker.parse(candidate) !== undefined`) — computed for every candidate regardless of
|
|
771
|
-
* `valid`; by the house parse/guard round-trip guarantee (AGENTS §14), a `valid: true` entry is
|
|
772
|
-
* ALWAYS also `coercible: true`. `@orkestrel/contract` 0.0.7's `explain` mirrors the normalizing
|
|
773
|
-
* `parse`'s leniency, not `is`'s strictness — so a strictly-invalid but coercible candidate (`7`
|
|
774
|
-
* against a string slot) yields `{ valid: false, coercible: true, faults: [] }`: EMPTY faults, since
|
|
775
|
-
* the mismatch the normalizing parse would silently fix is not one `explain` reports. `faults`
|
|
776
|
-
* therefore only ever populates for a NON-coercible mismatch — a wrong type the parse can't coerce
|
|
777
|
-
* (a boolean in a string slot), a missing required key, or an out-of-enum value — where
|
|
778
|
-
* `coercible: false`. `checker.is` / `.parse` / `.explain` are all total over JSON-safe input — a
|
|
779
|
-
* JSON-safe hostile candidate (a `__proto__`-carrying object, deeply nested data) reaches all three
|
|
780
|
-
* and yields a bounded, non-throwing per-candidate verdict; a NON-JSON-safe candidate (e.g. a
|
|
781
|
-
* throwing-getter `Proxy`) never reaches the checker at all — it fails the OUTER `args` parse
|
|
782
|
-
* against {@link import('./shapers.js').inferToolShape} and rejects the WHOLE call with the same
|
|
783
|
-
* `TOOL` {@link import('./errors.js').AgentToolError} a malformed `samples`/`format`/`enum` throws,
|
|
784
|
-
* with no per-candidate verdict produced.
|
|
785
|
-
*
|
|
786
|
-
* @param options - Advertised `name` / `description` overrides (see
|
|
787
|
-
* {@link import('./types.js').InferToolOptions})
|
|
788
|
-
* @returns A `ToolInterface` (named {@link import('./constants.js').INFER_TOOL_NAME} by default)
|
|
147
|
+
* A repeated name overwrites the registered tool without changing its insertion
|
|
148
|
+
* position. Definitions advertise `summary` in place of `description` when present.
|
|
149
|
+
* Unknown names and handler throws resolve to error results; batch execution preserves
|
|
150
|
+
* input order and never fails as a whole because of an individual call.
|
|
789
151
|
*
|
|
790
152
|
* @example
|
|
791
153
|
* ```ts
|
|
792
|
-
* import {
|
|
793
|
-
* import { createToolManager } from '@orkestrel/agent'
|
|
794
|
-
*
|
|
795
|
-
* const tool = createInferTool()
|
|
796
|
-
* const tools = createToolManager()
|
|
797
|
-
* tools.add(tool)
|
|
154
|
+
* import { Tool, ToolManager } from '@orkestrel/tool'
|
|
798
155
|
*
|
|
156
|
+
* const tools = new ToolManager()
|
|
157
|
+
* tools.add(new Tool({ name: 'add', execute: (args) => Number(args.x) + Number(args.y) }))
|
|
799
158
|
* const result = await tools.execute({
|
|
800
|
-
* id: '
|
|
801
|
-
* name: '
|
|
802
|
-
* arguments: {
|
|
803
|
-
* })
|
|
804
|
-
* // result.value -> { type: 'object', properties: { id: {...}, name: {...} }, ... }
|
|
805
|
-
*
|
|
806
|
-
* // with candidates, the result is wrapped with per-candidate verdicts
|
|
807
|
-
* const checked = await tools.execute({
|
|
808
|
-
* id: 'call-2',
|
|
809
|
-
* name: 'infer',
|
|
810
|
-
* arguments: {
|
|
811
|
-
* samples: [{ id: 1, name: 'Ada' }],
|
|
812
|
-
* candidates: [{ id: 2, name: 'Bob' }, { id: 'x', name: 'Cy' }],
|
|
813
|
-
* },
|
|
159
|
+
* id: '1',
|
|
160
|
+
* name: 'add',
|
|
161
|
+
* arguments: { x: 1, y: 2 },
|
|
814
162
|
* })
|
|
815
|
-
* // checked.value -> { parameters: {...}, checks: [
|
|
816
|
-
* // { index: 0, valid: true, coercible: true },
|
|
817
|
-
* // { index: 1, valid: false, coercible: false, faults: [...] },
|
|
818
|
-
* // ] }
|
|
819
|
-
* ```
|
|
820
|
-
*/
|
|
821
|
-
export declare function createInferTool(options?: InferToolOptions): ToolInterface;
|
|
822
|
-
|
|
823
|
-
/**
|
|
824
|
-
* Create the in-memory {@link DefinitionStoreInterface} — a process-lifetime `Map` of database
|
|
825
|
-
* definitions, the DEFAULT store the upcoming database / relation tools will persist their
|
|
826
|
-
* `DatabaseDefinition` configs through.
|
|
827
|
-
*
|
|
828
|
-
* @returns A {@link DefinitionStoreInterface}
|
|
829
|
-
*
|
|
830
|
-
* @example
|
|
831
|
-
* ```ts
|
|
832
|
-
* import { createMemoryDefinitionStore } from '@src/core'
|
|
833
|
-
*
|
|
834
|
-
* const store = createMemoryDefinitionStore()
|
|
835
163
|
* ```
|
|
836
164
|
*/
|
|
837
|
-
export declare
|
|
165
|
+
export declare class ToolManager implements ToolManagerInterface {
|
|
166
|
+
#private;
|
|
167
|
+
get count(): number;
|
|
168
|
+
add(tool: ToolInterface): void;
|
|
169
|
+
add(tools: readonly ToolInterface[]): void;
|
|
170
|
+
tool(name: string): ToolInterface | undefined;
|
|
171
|
+
tools(): readonly ToolInterface[];
|
|
172
|
+
definitions(): readonly ToolDefinition[];
|
|
173
|
+
execute(call: ToolCall): Promise<ToolResult>;
|
|
174
|
+
execute(calls: readonly ToolCall[]): Promise<readonly ToolResult[]>;
|
|
175
|
+
remove(name: string): boolean;
|
|
176
|
+
remove(names: readonly string[]): boolean;
|
|
177
|
+
clear(): void;
|
|
178
|
+
}
|
|
838
179
|
|
|
839
180
|
/**
|
|
840
|
-
*
|
|
841
|
-
* {@link import('./types.js').PromptToolOptions.to} a question and BLOCKS until it answers,
|
|
842
|
-
* returning the resolved answer value.
|
|
181
|
+
* A registry of executable tools with per-call error isolation.
|
|
843
182
|
*
|
|
844
183
|
* @remarks
|
|
845
|
-
*
|
|
846
|
-
*
|
|
847
|
-
*
|
|
848
|
-
*
|
|
849
|
-
* ({@link import('./types.js').PromptToolOptions.from}) — never read from the model-supplied
|
|
850
|
-
* args — so a model cannot spoof which terminal is asking. A prompt CYCLE rejects with
|
|
851
|
-
* `TerminalError('DEADLOCK')`, re-surfaced as a typed `DEADLOCK`
|
|
852
|
-
* {@link import('./errors.js').AgentToolError}; an expired prompt re-surfaces as `EXPIRE`; an
|
|
853
|
-
* unknown `to` (or any other `TerminalError`) re-surfaces as `TOOL`, naming the unknown terminal
|
|
854
|
-
* plus the known ones (`manager.terminals()`).
|
|
855
|
-
*
|
|
856
|
-
* @param options - The live manager, the fixed `from` identity, and advertised overrides (see
|
|
857
|
-
* {@link import('./types.js').PromptToolOptions})
|
|
858
|
-
* @returns A `ToolInterface` (named {@link import('./constants.js').PROMPT_TOOL_NAME} by default)
|
|
859
|
-
*
|
|
860
|
-
* @example
|
|
861
|
-
* ```ts
|
|
862
|
-
* import { createPromptTool } from '@src/core'
|
|
863
|
-
* import { createTerminalManager, createToolManager } from '@orkestrel/terminal'
|
|
864
|
-
*
|
|
865
|
-
* const manager = createTerminalManager()
|
|
866
|
-
* manager.add('agent')
|
|
867
|
-
* manager.add('reviewer')
|
|
868
|
-
* const tool = createPromptTool({ manager, from: 'agent' })
|
|
869
|
-
* const tools = createToolManager()
|
|
870
|
-
* tools.add(tool) // the agent can now ask 'reviewer' and block for the answer
|
|
871
|
-
* ```
|
|
184
|
+
* Tools are keyed by name in insertion order. Adding an existing name overwrites its
|
|
185
|
+
* value without changing its position. Every call resolves to a {@link ToolResult};
|
|
186
|
+
* missing tools and thrown handlers become error results. Batch execution preserves
|
|
187
|
+
* input order and isolates each call.
|
|
872
188
|
*/
|
|
873
|
-
export declare
|
|
189
|
+
export declare interface ToolManagerInterface {
|
|
190
|
+
/** The number of registered tools. */
|
|
191
|
+
readonly count: number;
|
|
192
|
+
/**
|
|
193
|
+
* Register one tool.
|
|
194
|
+
*
|
|
195
|
+
* @param tool - The tool to register
|
|
196
|
+
* @returns Nothing
|
|
197
|
+
*/
|
|
198
|
+
add(tool: ToolInterface): void;
|
|
199
|
+
/**
|
|
200
|
+
* Register a batch of tools.
|
|
201
|
+
*
|
|
202
|
+
* @param tools - The tools to register
|
|
203
|
+
* @returns Nothing
|
|
204
|
+
*/
|
|
205
|
+
add(tools: readonly ToolInterface[]): void;
|
|
206
|
+
/**
|
|
207
|
+
* Find one registered tool by name.
|
|
208
|
+
*
|
|
209
|
+
* @param name - The registered tool name
|
|
210
|
+
* @returns The tool when found, otherwise `undefined`
|
|
211
|
+
*/
|
|
212
|
+
tool(name: string): ToolInterface | undefined;
|
|
213
|
+
/**
|
|
214
|
+
* List the registered tools in insertion order.
|
|
215
|
+
*
|
|
216
|
+
* @returns A new readonly array of registered tools
|
|
217
|
+
*/
|
|
218
|
+
tools(): readonly ToolInterface[];
|
|
219
|
+
/**
|
|
220
|
+
* List the definitions advertised to a caller.
|
|
221
|
+
*
|
|
222
|
+
* @returns A new readonly array of tool definitions
|
|
223
|
+
*/
|
|
224
|
+
definitions(): readonly ToolDefinition[];
|
|
225
|
+
/**
|
|
226
|
+
* Execute one call with error isolation.
|
|
227
|
+
*
|
|
228
|
+
* @param call - The tool call to execute
|
|
229
|
+
* @returns The correlated result
|
|
230
|
+
*/
|
|
231
|
+
execute(call: ToolCall): Promise<ToolResult>;
|
|
232
|
+
/**
|
|
233
|
+
* Execute a batch of calls with per-call error isolation.
|
|
234
|
+
*
|
|
235
|
+
* @param calls - The tool calls to execute
|
|
236
|
+
* @returns The correlated results in input order
|
|
237
|
+
*/
|
|
238
|
+
execute(calls: readonly ToolCall[]): Promise<readonly ToolResult[]>;
|
|
239
|
+
/**
|
|
240
|
+
* Remove one registered tool.
|
|
241
|
+
*
|
|
242
|
+
* @param name - The tool name to remove
|
|
243
|
+
* @returns Whether the tool was present
|
|
244
|
+
*/
|
|
245
|
+
remove(name: string): boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Remove a batch of registered tools.
|
|
248
|
+
*
|
|
249
|
+
* @param names - The tool names to remove
|
|
250
|
+
* @returns Whether any named tool was present
|
|
251
|
+
*/
|
|
252
|
+
remove(names: readonly string[]): boolean;
|
|
253
|
+
/**
|
|
254
|
+
* Remove every registered tool.
|
|
255
|
+
*
|
|
256
|
+
* @returns Nothing
|
|
257
|
+
*/
|
|
258
|
+
clear(): void;
|
|
259
|
+
}
|
|
874
260
|
|
|
875
261
|
/**
|
|
876
|
-
*
|
|
877
|
-
* through one `operation`-discriminated call (AGENTS §14, matching {@link createDatabaseTool}'s
|
|
878
|
-
* single-tool-many-operations shape).
|
|
262
|
+
* Options for creating an executable tool.
|
|
879
263
|
*
|
|
880
264
|
* @remarks
|
|
881
|
-
*
|
|
882
|
-
*
|
|
883
|
-
*
|
|
884
|
-
* must match a key of {@link import('./types.js').RelationToolOptions.managers}, an OMITTED one
|
|
885
|
-
* resolves to the SOLE registered manager, either miss throwing a typed `TOOL`
|
|
886
|
-
* {@link import('./errors.js').AgentToolError}
|
|
887
|
-
* ({@link import('./helpers.js').relationManagerOf}) — then resolves `model` against it
|
|
888
|
-
* ({@link import('./helpers.js').relationModelOf}, same typed-`TOOL`-on-miss shape), and
|
|
889
|
-
* dispatches to the matched operation, RETURNING a plain result on success.
|
|
890
|
-
*
|
|
891
|
-
* `'load'` / `'find'` expand the call's FLAT dot-path `include` list into a live
|
|
892
|
-
* `@orkestrel/relation` `Include` tree via {@link import('./helpers.js').expandInclude}, capped
|
|
893
|
-
* at {@link import('./types.js').RelationToolOptions.depth} (default
|
|
894
|
-
* {@link import('./constants.js').RELATION_TOOL_DEPTH}) — a path exceeding the cap, or carrying an
|
|
895
|
-
* empty segment, throws a typed `TOOL` error. `'load'` dispatches on whether `key` is an array
|
|
896
|
-
* (positional many-key form, AGENTS §9.2) or a single key. `'find'` and `'links'` clamp their
|
|
897
|
-
* result to {@link import('./types.js').RelationToolOptions.limit} (default
|
|
898
|
-
* {@link import('./constants.js').RELATION_TOOL_LIMIT}) — `'find'` probes one row past the
|
|
899
|
-
* effective limit (mirroring {@link import('./helpers.js').clampCriteria}'s idiom) to report
|
|
900
|
-
* `truncated`; `'links'` (which has no upstream pagination) fetches the FULL linked-key list and
|
|
901
|
-
* slices/truncates it the same way. `'link'` / `'unlink'` write / remove one `through` junction
|
|
902
|
-
* row.
|
|
903
|
-
*
|
|
904
|
-
* A typed `@orkestrel/relation` failure (`RelationError`) re-surfaces as a typed `RELATION`
|
|
905
|
-
* `AgentToolError` carrying the original {@link import('@orkestrel/relation').RelationErrorCode}
|
|
906
|
-
* in `context.code`; a typed `@orkestrel/database` failure underneath it (`DatabaseError`)
|
|
907
|
-
* re-surfaces as a typed `DATABASE` `AgentToolError`, mirroring {@link createDatabaseTool}'s error
|
|
908
|
-
* mapping; an `AgentToolError` thrown by this tool's own guards (malformed args, an unknown
|
|
909
|
-
* manager/model) passes through unwrapped.
|
|
910
|
-
*
|
|
911
|
-
* @param options - The tool's configuration (see {@link import('./types.js').RelationToolOptions})
|
|
912
|
-
* @returns A `ToolInterface` (named {@link import('./constants.js').RELATION_TOOL_NAME} by default)
|
|
913
|
-
*
|
|
914
|
-
* @example
|
|
915
|
-
* ```ts
|
|
916
|
-
* import { createRelationTool } from '@src/core'
|
|
917
|
-
*
|
|
918
|
-
* const tool = createRelationTool({ managers: { shop: manager } })
|
|
919
|
-
* await tool.execute({ operation: 'load', model: 'accounts', key: 'acc1', include: ['contacts'] })
|
|
920
|
-
* ```
|
|
265
|
+
* `name` identifies the tool, `description` and `parameters` define what is advertised
|
|
266
|
+
* to a caller, `summary` optionally replaces the advertised description, and `execute`
|
|
267
|
+
* handles the caller-supplied arguments record.
|
|
921
268
|
*/
|
|
922
|
-
export declare
|
|
269
|
+
export declare interface ToolOptions {
|
|
270
|
+
/** The name a caller uses to select the tool. */
|
|
271
|
+
readonly name: string;
|
|
272
|
+
/** The full description of the tool's behavior. */
|
|
273
|
+
readonly description?: string;
|
|
274
|
+
/** A concise description to advertise in place of the full description. */
|
|
275
|
+
readonly summary?: string;
|
|
276
|
+
/** The JSON Schema for the tool's arguments. */
|
|
277
|
+
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
278
|
+
/** The handler that executes the tool. */
|
|
279
|
+
readonly execute: (args: Readonly<Record<string, unknown>>) => Promise<unknown> | unknown;
|
|
280
|
+
}
|
|
923
281
|
|
|
924
282
|
/**
|
|
925
|
-
*
|
|
926
|
-
* adapter that lets a `function`-form task run a `@orkestrel/agent` tool BY NAME.
|
|
283
|
+
* The outcome of executing a {@link ToolCall}.
|
|
927
284
|
*
|
|
928
285
|
* @remarks
|
|
929
|
-
*
|
|
930
|
-
* `WorkflowOptions.functions` registry like any other behavior
|
|
931
|
-
* (`{ publish: createToolFunction(tools, 'publish') }`); the pure workflow runner has no
|
|
932
|
-
* knowledge of tools itself. The returned function executes `name` against `tools` with the
|
|
933
|
-
* task's `controller.input` as the call arguments, id-correlated to the task's own id. A
|
|
934
|
-
* `ToolManagerInterface.execute` (`@orkestrel/agent`) NEVER throws (a handler throw is isolated
|
|
935
|
-
* into `result.error`), so a failing tool is surfaced here as a THROWN `Error` carrying the
|
|
936
|
-
* original message as `cause` — the leaf `fail`s, honouring `bail`. An UNREGISTERED tool name is
|
|
937
|
-
* a programmer error (an explicit binding to a name that doesn't exist) — unlike the engine's
|
|
938
|
-
* own silent auto-complete of an unresolved task handler, this THROWS a typed `TOOL`
|
|
939
|
-
* `WorkflowError` (`@orkestrel/workflow`).
|
|
940
|
-
*
|
|
941
|
-
* @param tools - The `ToolManagerInterface` (`@orkestrel/agent`) the named tool is registered on
|
|
942
|
-
* @param name - The registered tool's name
|
|
943
|
-
* @returns A {@link WorkflowFunction} that runs the named tool
|
|
944
|
-
*
|
|
945
|
-
* @example
|
|
946
|
-
* ```ts
|
|
947
|
-
* import { createToolFunction } from '@src/core'
|
|
948
|
-
* import { createToolManager } from '@orkestrel/agent'
|
|
949
|
-
* import { createWorkflowRunner } from '@orkestrel/workflow'
|
|
950
|
-
*
|
|
951
|
-
* const tools = createToolManager()
|
|
952
|
-
* tools.add(myPublishTool)
|
|
953
|
-
* const runner = createWorkflowRunner()
|
|
954
|
-
* await runner.execute(definition, { functions: { publish: createToolFunction(tools, 'publish') } })
|
|
955
|
-
* ```
|
|
286
|
+
* A successful result carries `value`; a failed result carries `error`.
|
|
956
287
|
*/
|
|
957
|
-
export declare
|
|
958
|
-
|
|
959
|
-
/**
|
|
960
|
-
* Compile the LENIENT workflow DRAFT contract — identical to `createWorkflowContract`
|
|
961
|
-
* (`@orkestrel/workflow`) EXCEPT `id` and `name` are OPTIONAL at all three levels (workflow /
|
|
962
|
-
* phase / task), so a small model can omit the six identity strings.
|
|
963
|
-
*
|
|
964
|
-
* @remarks
|
|
965
|
-
* The widened authoring surface {@link createWorkflowTool} parses an authored blob through
|
|
966
|
-
* before {@link import('./helpers.js').completeDraft} fills the missing ids/names. It does NOT
|
|
967
|
-
* relax the canonical contract — `createWorkflowContract` (`@orkestrel/workflow`) stays
|
|
968
|
-
* byte-for-byte unchanged and STRICT, and the completed draft is re-validated against THAT
|
|
969
|
-
* strict gate before running (soundness preserved). A PROVIDED `id` / `name` still carries
|
|
970
|
-
* `minLength: 1`, so an explicitly-empty `id: ''` is REJECTED (parses to `undefined`), never
|
|
971
|
-
* auto-filled — keeping "garbage" distinct from "omitted". `run` stays optional (a plain name
|
|
972
|
-
* string).
|
|
973
|
-
*
|
|
974
|
-
* @returns The compiled {@link import('./types.js').WorkflowDraft} contract
|
|
975
|
-
*
|
|
976
|
-
* @example
|
|
977
|
-
* ```ts
|
|
978
|
-
* import { createWorkflowDraftContract, completeDraft } from '@src/core'
|
|
979
|
-
*
|
|
980
|
-
* const draft = createWorkflowDraftContract()
|
|
981
|
-
* const parsed = draft.parse({ phases: [{ tasks: [{ run: 'compile' }] }] })
|
|
982
|
-
* const definition = parsed && completeDraft(parsed) // ids/names filled positionally
|
|
983
|
-
* draft.parse({ id: '', phases: [] }) // undefined — an explicit empty id is rejected
|
|
984
|
-
* ```
|
|
985
|
-
*/
|
|
986
|
-
export declare function createWorkflowDraftContract(): ContractInterface<WorkflowDraft>;
|
|
987
|
-
|
|
988
|
-
/**
|
|
989
|
-
* Wrap a {@link WorkflowDefinition} as an LLM-callable tool — it ADVERTISES the SIMPLE flat
|
|
990
|
-
* authoring shape (`{ name?, steps: [{ name }] }`) as its `parameters` so even a small model can
|
|
991
|
-
* author a complete tree, and its handler EXPANDS / COMPLETES the authored blob, validates it
|
|
992
|
-
* against the STRICT contract, runs it through `runner`, and, when
|
|
993
|
-
* {@link import('./types.js').WorkflowToolOptions.store} is supplied, PERSISTS each executed
|
|
994
|
-
* workflow's final snapshot after the run settles.
|
|
995
|
-
*
|
|
996
|
-
* @remarks
|
|
997
|
-
* A plain `ToolManagerInterface`-compatible tool (`@orkestrel/agent`), reproducing
|
|
998
|
-
* `@orkestrel/workflow`'s former call contract exactly (flat / draft / full authoring forms, the
|
|
999
|
-
* strict soundness gate, the depth/cycle guard). It is ALSO the propagation carrier
|
|
1000
|
-
* {@link createAgentFunction} binds onto a wrapped agent's `context.tools`: because a tool
|
|
1001
|
-
* handler receives ONLY the model-supplied `args` (no ambient context, no signal), the run's
|
|
1002
|
-
* depth + ancestry are CLOSED OVER at bind time via {@link import('./types.js').WorkflowToolOptions},
|
|
1003
|
-
* and the handler enforces the SAME depth / cycle guard itself before running the nested
|
|
1004
|
-
* workflow at `depth + 1` with the extended ancestry.
|
|
1005
|
-
*
|
|
1006
|
-
* **Widened authoring surface (additive — the canonical contract + runner stay STRICT and
|
|
1007
|
-
* unchanged).** A 2B model reliably CALLS the tool but cannot reliably emit the full four-level
|
|
1008
|
-
* nested {@link WorkflowDefinition} (six required `id`/`name` strings, an all-or-nothing tree).
|
|
1009
|
-
* So the tool ACCEPTS three authoring forms and converges them on the SAME strict
|
|
1010
|
-
* `createWorkflowContract` gate before running (soundness preserved):
|
|
1011
|
-
* - the FLAT shape `{ name?, steps: [{ name }] }` — the ADVERTISED `parameters` (the simplest
|
|
1012
|
-
* form, {@link import('./helpers.js').expandSteps}'d into one one-task phase per step);
|
|
1013
|
-
* - a nested DRAFT with any `id`/`name` OMITTED — {@link createWorkflowDraftContract}-parsed then
|
|
1014
|
-
* {@link import('./helpers.js').completeDraft}'d (missing ids synthesized positionally);
|
|
1015
|
-
* - the full nested {@link WorkflowDefinition} — the advanced escape-hatch, accepted as the draft
|
|
1016
|
-
* super-set.
|
|
1017
|
-
*
|
|
1018
|
-
* The universal tool-handler contract (AGENTS §14): returns the plain run summary
|
|
1019
|
-
* (`{ status, count }`) on success, THROWS a typed `WorkflowError` (`@orkestrel/workflow`) on
|
|
1020
|
-
* every failure path — malformed authored args (`TOOL`), or an over-deep / cyclic nested run
|
|
1021
|
-
* (`DEPTH`). The `ToolManagerInterface` isolates every throw into the canonical tool result's
|
|
1022
|
-
* top-level `error`, so nothing escapes the run. `options.depth` / `options.ancestry` are the
|
|
1023
|
-
* propagation carrier across a workflow → agent → workflow chain; `options.store` is this
|
|
1024
|
-
* package's ADDITION — the persisted snapshot is retrievable via the store afterwards (a caller
|
|
1025
|
-
* restores it through `@orkestrel/workflow`'s own `Workflow.restore` / store-backed factories).
|
|
1026
|
-
*
|
|
1027
|
-
* @param definition - The workflow the tool runs when called with no authored args
|
|
1028
|
-
* @param runner - The `WorkflowRunnerInterface` (`@orkestrel/workflow`) that executes the (nested) workflow
|
|
1029
|
-
* @param options - Depth/ancestry bookkeeping plus the optional durable store (see {@link import('./types.js').WorkflowToolOptions})
|
|
1030
|
-
* @returns A `ToolInterface` (named {@link import('./constants.js').WORKFLOW_TOOL_NAME}) whose
|
|
1031
|
-
* `parameters` advertise the flat authoring schema
|
|
1032
|
-
*
|
|
1033
|
-
* @example
|
|
1034
|
-
* ```ts
|
|
1035
|
-
* import { createWorkflowTool } from '@src/core'
|
|
1036
|
-
* import { createWorkflowRunner, createMemoryWorkflowStore } from '@orkestrel/workflow'
|
|
1037
|
-
* import { createToolManager } from '@orkestrel/agent'
|
|
1038
|
-
*
|
|
1039
|
-
* const runner = createWorkflowRunner()
|
|
1040
|
-
* const store = createMemoryWorkflowStore()
|
|
1041
|
-
* const tool = createWorkflowTool(definition, runner, { store })
|
|
1042
|
-
* const tools = createToolManager()
|
|
1043
|
-
* tools.add(tool) // authored runs are now persisted to `store` on settle
|
|
1044
|
-
* ```
|
|
1045
|
-
*/
|
|
1046
|
-
export declare function createWorkflowTool(definition: WorkflowDefinition, runner: WorkflowRunnerInterface, options?: WorkflowToolOptions): ToolInterface;
|
|
1047
|
-
|
|
1048
|
-
/**
|
|
1049
|
-
* Build an LLM-callable workspace-editing tool — it ADVERTISES the `operation`-discriminated
|
|
1050
|
-
* 13-op union ({@link import('./shapers.js').workspaceToolShape}) as its `parameters`, and its
|
|
1051
|
-
* handler PARSES the model-supplied args against that contract and DISPATCHES the matched
|
|
1052
|
-
* operation against the manager's ACTIVE workspace (the registry ops drive the manager itself),
|
|
1053
|
-
* returning the plain result (throwing a typed `WorkspaceError`, `@orkestrel/agent`, on
|
|
1054
|
-
* failure). EITHER drives a caller-supplied {@link WorkspaceToolOptions.manager} directly, OR
|
|
1055
|
-
* constructs a fresh `WorkspaceManagerInterface` (`@orkestrel/agent`) over
|
|
1056
|
-
* {@link import('./types.js').WorkspaceToolOptions.store} (via `@orkestrel/agent`'s
|
|
1057
|
-
* `createWorkspaceManager`); neither given constructs a manager backed by `@orkestrel/agent`'s
|
|
1058
|
-
* in-memory store default.
|
|
1059
|
-
*
|
|
1060
|
-
* @remarks
|
|
1061
|
-
* MANAGER-DRIVEN: every edit / read op (read / list / has / search / replace / write / splice /
|
|
1062
|
-
* prepend / append / move / remove) targets `manager.active`, so the model edits whichever
|
|
1063
|
-
* workspace is active and a host can re-point it (`WorkspaceManagerInterface.switch`) between
|
|
1064
|
-
* turns. Two REGISTRY ops make the model self-sufficient: `workspaces` LISTS the registered
|
|
1065
|
-
* workspaces (each `{ id, files, active }`) so it can discover an id, and `switch` re-points the
|
|
1066
|
-
* active workspace by id (lenient — an unknown id is a no-op reporting `switched: false`, never a
|
|
1067
|
-
* throw).
|
|
1068
|
-
*
|
|
1069
|
-
* NO-ACTIVE RULE (the ergonomic seam): a WRITING op (write / splice / prepend / append / move /
|
|
1070
|
-
* remove / replace) run when `manager.active` is `undefined` AUTO-CREATES + activates a default
|
|
1071
|
-
* workspace (`manager.add()`) so the model can just start writing; a pure-READ op (read / list /
|
|
1072
|
-
* has / search) against no active workspace returns the EMPTY result (`undefined` / `[]` /
|
|
1073
|
-
* `false`), never creating one and never throwing.
|
|
1074
|
-
*
|
|
1075
|
-
* The handler conforms to the universal tool-handler contract (AGENTS §14): it `contract.parse`s
|
|
1076
|
-
* the args, THROWS a `TOOL` `WorkspaceError` when no operation arm matched (a malformed / unknown
|
|
1077
|
-
* operation), else `switch`es on `op.operation` and RETURNS the plain result — letting a
|
|
1078
|
-
* `WorkspaceError` raised by the live workspace (`MODALITY` / `PATTERN` / `RANGE`) PROPAGATE
|
|
1079
|
-
* uncaught. The range edit is the FLAT `'splice'` op: its four flat caret integers are
|
|
1080
|
-
* reassembled into a `Range` (`@orkestrel/agent`) by `rangeOf` and fed to the workspace's ranged
|
|
1081
|
-
* `write`.
|
|
1082
|
-
*
|
|
1083
|
-
* @param options - `manager` (drive directly) OR `store` (build a manager over it); neither ⇒
|
|
1084
|
-
* an in-memory-backed manager (see {@link import('./types.js').WorkspaceToolOptions})
|
|
1085
|
-
* @returns A `ToolInterface` (named {@link import('./constants.js').WORKSPACE_TOOL_NAME} by default)
|
|
1086
|
-
*
|
|
1087
|
-
* @example
|
|
1088
|
-
* ```ts
|
|
1089
|
-
* import { createWorkspaceTool } from '@src/core'
|
|
1090
|
-
* import { createToolManager } from '@orkestrel/agent'
|
|
1091
|
-
*
|
|
1092
|
-
* const tool = createWorkspaceTool() // in-memory workspace, no persistence
|
|
1093
|
-
* const tools = createToolManager()
|
|
1094
|
-
* tools.add(tool)
|
|
1095
|
-
* ```
|
|
1096
|
-
*/
|
|
1097
|
-
export declare function createWorkspaceTool(options?: WorkspaceToolOptions): ToolInterface;
|
|
1098
|
-
|
|
1099
|
-
/**
|
|
1100
|
-
* Normalize the database tool's parsed SERIALIZED criteria into a live `@orkestrel/database`
|
|
1101
|
-
* {@link Criteria} — default each condition's OMITTED `connector` to `'and'`.
|
|
1102
|
-
*
|
|
1103
|
-
* @remarks
|
|
1104
|
-
* The wire form ({@link import('./shapers.js').databaseToolShape}) lets a caller drop `connector`
|
|
1105
|
-
* on the last condition (it has nothing to join FORWARD to); the compiled `Condition` a live
|
|
1106
|
-
* `@orkestrel/database` table call accepts always carries one, so this fills the gap. `order` /
|
|
1107
|
-
* `limit` / `offset` pass through unchanged. Pure and total.
|
|
1108
|
-
*
|
|
1109
|
-
* @param criteria - The parsed criteria (or `undefined`)
|
|
1110
|
-
* @returns The equivalent live `Criteria`, or `undefined` when `criteria` is `undefined`
|
|
1111
|
-
*/
|
|
1112
|
-
export declare function criteriaOf(criteria: Readonly<{
|
|
1113
|
-
conditions?: readonly Readonly<{
|
|
1114
|
-
column: string;
|
|
1115
|
-
operator: Condition['operator'];
|
|
1116
|
-
values: readonly unknown[];
|
|
1117
|
-
connector?: Connector;
|
|
1118
|
-
}>[];
|
|
1119
|
-
order?: readonly Readonly<{
|
|
1120
|
-
column: string;
|
|
1121
|
-
direction: Direction;
|
|
1122
|
-
}>[];
|
|
1123
|
-
limit?: number;
|
|
1124
|
-
offset?: number;
|
|
1125
|
-
}> | undefined): Criteria | undefined;
|
|
1126
|
-
|
|
1127
|
-
/** The SERIALIZED criteria form — conditions, order, and pagination. */
|
|
1128
|
-
export declare const criteriaShape: ObjectShape<{
|
|
1129
|
-
conditions: OptionalShape<ArrayShape<ObjectShape<{
|
|
1130
|
-
column: StringShape;
|
|
1131
|
-
operator: LiteralShape<readonly ["equals", "not", "above", "below", "from", "to", "between", "like", "glob", "starts", "ends", "any", "none", "absent", "present"]>;
|
|
1132
|
-
values: ArrayShape<JSONShape>;
|
|
1133
|
-
connector: OptionalShape<LiteralShape<readonly ["and", "or"]>>;
|
|
1134
|
-
}, false>>>;
|
|
1135
|
-
order: OptionalShape<ArrayShape<ObjectShape<{
|
|
1136
|
-
column: StringShape;
|
|
1137
|
-
direction: LiteralShape<readonly ["ascending", "descending"]>;
|
|
1138
|
-
}, false>>>;
|
|
1139
|
-
limit: OptionalShape<NumberShape>;
|
|
1140
|
-
offset: OptionalShape<NumberShape>;
|
|
1141
|
-
}, false>;
|
|
1142
|
-
|
|
1143
|
-
/**
|
|
1144
|
-
* The DESCRIPTION the upcoming database tool will advertise — a multi-line guide that teaches a
|
|
1145
|
-
* small model the operation list, the SERIALIZED criteria form, and the {@link import('./types.js').TableSpec}
|
|
1146
|
-
* column DSL.
|
|
1147
|
-
*
|
|
1148
|
-
* @remarks
|
|
1149
|
-
* The criteria form is deliberately SERIALIZED (never fluent) — every condition is a flat object
|
|
1150
|
-
* `{ column, operator, values, connector? }` where `values` is ALWAYS an array, even for a
|
|
1151
|
-
* single-value operator (`{ column: 'age', operator: 'from', values: [18] }`), so a small model
|
|
1152
|
-
* never has to chain method calls or guess whether a value is scalar or a list.
|
|
1153
|
-
*/
|
|
1154
|
-
export declare const DATABASE_TOOL_DESCRIPTION: string;
|
|
1155
|
-
|
|
1156
|
-
/** The default cap on rows a `records` / `remove` call returns (or acts on) when the caller omits `criteria.limit` — the upcoming database tool's default row ceiling. */
|
|
1157
|
-
export declare const DATABASE_TOOL_LIMIT = 1000;
|
|
1158
|
-
|
|
1159
|
-
/** The database tool's mutating operations — disabled by `DatabaseToolOptions.readonly`. */
|
|
1160
|
-
export declare const DATABASE_TOOL_MUTATIONS: Set<string>;
|
|
1161
|
-
|
|
1162
|
-
/**
|
|
1163
|
-
* The name the upcoming `createDatabaseTool` factory will advertise by default — the key a model
|
|
1164
|
-
* calls and the `ToolManagerInterface` (`@orkestrel/agent`) registers under.
|
|
1165
|
-
*
|
|
1166
|
-
* @remarks
|
|
1167
|
-
* SRC-1 of a 3-unit spine: this unit lands the persistence + schema foundation
|
|
1168
|
-
* ({@link import('./types.js').DatabaseDefinition}, {@link import('./types.js').DefinitionStoreInterface},
|
|
1169
|
-
* {@link import('./helpers.js').expandTables}); `createDatabaseTool` itself is built in a later unit.
|
|
1170
|
-
*/
|
|
1171
|
-
export declare const DATABASE_TOOL_NAME = "database";
|
|
1172
|
-
|
|
1173
|
-
/**
|
|
1174
|
-
* The lean {@link import('@orkestrel/agent').ToolInterface.summary} the upcoming database tool
|
|
1175
|
-
* will advertise in place of {@link DATABASE_TOOL_DESCRIPTION}.
|
|
1176
|
-
*/
|
|
1177
|
-
export declare const DATABASE_TOOL_SUMMARY = "Create and query a database \u2014 one operation per call (create, tables, get, records, count, aggregate, add, set, update, remove, migrate, destroy), chosen by the 'operation' field. Call describe('database') for the full operation list, the criteria form, and the column DSL.";
|
|
1178
|
-
|
|
1179
|
-
/**
|
|
1180
|
-
* One database's CONFIG-ONLY definition — `id` + `driver` + {@link TableSpec} (+ optional `keys`),
|
|
1181
|
-
* the pure-JSON blueprint the upcoming database / relation tools build a live database from.
|
|
1182
|
-
*
|
|
1183
|
-
* @remarks
|
|
1184
|
-
* A `DatabaseDefinition` is NEVER a live handle — it is the durable, serializable config a
|
|
1185
|
-
* {@link DefinitionStoreInterface} persists and a tool factory turns into a real
|
|
1186
|
-
* `@orkestrel/database` `DatabaseInterface` (via `createDatabase` + {@link import('./helpers.js').expandTables})
|
|
1187
|
-
* on demand. `keys`, when present, maps a table name to its primary-key column (omitted ⇒ the
|
|
1188
|
-
* driver's default primary key).
|
|
1189
|
-
*/
|
|
1190
|
-
export declare interface DatabaseDefinition {
|
|
288
|
+
export declare interface ToolResult {
|
|
289
|
+
/** The identifier of the corresponding call. */
|
|
1191
290
|
readonly id: string;
|
|
1192
|
-
|
|
1193
|
-
readonly tables: TableSpec;
|
|
1194
|
-
readonly keys?: Readonly<Record<string, string>>;
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
/** One opaque persisted row — the shape a `TableInterface<DatabaseDefinitionRow>`-backed store reads/writes; `definition` is narrowed with {@link import('./helpers.js').isDatabaseDefinition} on read. */
|
|
1198
|
-
export declare interface DatabaseDefinitionRow {
|
|
1199
|
-
readonly id: string;
|
|
1200
|
-
readonly definition: unknown;
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
/**
|
|
1204
|
-
* A {@link DefinitionStoreInterface} backed by one table of the `@orkestrel/database` layer — a
|
|
1205
|
-
* database's durable CONFIG state IS a row, so persistence reduces to keyed point-access
|
|
1206
|
-
* (`get` / `set` / `delete`) over a {@link TableInterface}, the driver-pluggable twin of the
|
|
1207
|
-
* plain-`Map` {@link import('./MemoryDefinitionStore.js').MemoryDefinitionStore}.
|
|
1208
|
-
*
|
|
1209
|
-
* @remarks
|
|
1210
|
-
* The store is driver-agnostic: it holds a single {@link TableInterface} whose backend (memory,
|
|
1211
|
-
* JSON, SQLite, IndexedDB) is chosen by whoever builds it (the factories), so a JSON / SQLite /
|
|
1212
|
-
* IndexedDB backend swaps in WITHOUT touching a consumer — the same seam as
|
|
1213
|
-
* {@link import('./MemoryDefinitionStore.js').MemoryDefinitionStore}. The driver defaults to
|
|
1214
|
-
* memory ({@link import('../factories.js').createDatabaseDefinitionStore} passes
|
|
1215
|
-
* `createMemoryDriver()`), so it ALSO works in memory out of the box; you opt into the durable
|
|
1216
|
-
* plumbing by passing a JSON / SQLite / IndexedDB driver.
|
|
1217
|
-
*
|
|
1218
|
-
* The {@link DatabaseDefinition} is stored as ONE OPAQUE JSON COLUMN — the table is a row of
|
|
1219
|
-
* `{ id; definition }` ({@link DatabaseDefinitionRow}). The definition is already a COMPLETE,
|
|
1220
|
-
* self-contained, pure-JSON CONFIG payload (never a live handle), so storing it whole is lossless
|
|
1221
|
-
* AND keeps the row type flat (`definition` reads back as `unknown`).
|
|
1222
|
-
*
|
|
1223
|
-
* - **`set(definition)` upserts under the definition's OWN `id`** (no separate id param) — it
|
|
1224
|
-
* writes the row `{ id: definition.id, definition }`.
|
|
1225
|
-
* - **`get(id)` resolves the stored definition for an id**, narrowing the opaque JSON column back
|
|
1226
|
-
* to a {@link DatabaseDefinition} ({@link import('../helpers.js').isDatabaseDefinition} — the
|
|
1227
|
-
* AGENTS §14 boundary narrow for an untrusted storage read), or `undefined` if none is stored
|
|
1228
|
-
* or the stored blob is malformed.
|
|
1229
|
-
* - **`delete(id)` drops a definition by id**; an absent id is a no-op (no throw).
|
|
1230
|
-
*
|
|
1231
|
-
* The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the §22 method
|
|
1232
|
-
* bijection with {@link DefinitionStoreInterface}).
|
|
1233
|
-
*
|
|
1234
|
-
* @example
|
|
1235
|
-
* ```ts
|
|
1236
|
-
* import { createDatabaseDefinitionStore, createMemoryDriver } from '@src/core'
|
|
1237
|
-
*
|
|
1238
|
-
* const store = createDatabaseDefinitionStore(createMemoryDriver()) // a durable driver swaps in here
|
|
1239
|
-
* await store.set({ id: 'shop', driver: 'memory', tables: {} }) // persist the config (one JSON column)
|
|
1240
|
-
* const definition = await store.get('shop')
|
|
1241
|
-
* await store.delete('shop')
|
|
1242
|
-
* ```
|
|
1243
|
-
*/
|
|
1244
|
-
export declare class DatabaseDefinitionStore implements DefinitionStoreInterface {
|
|
1245
|
-
#private;
|
|
1246
|
-
/**
|
|
1247
|
-
* Wrap a table as a definition store.
|
|
1248
|
-
*
|
|
1249
|
-
* @param table - The {@link TableInterface} holding the definitions — its row is the
|
|
1250
|
-
* {@link DatabaseDefinitionRow} `{ id; definition }` shape (the definition one opaque JSON column)
|
|
1251
|
-
*/
|
|
1252
|
-
constructor(table: TableInterface<DatabaseDefinitionRow>);
|
|
1253
|
-
/** Resolve the persisted definition for `id`, narrowing the opaque JSON column back to a `DatabaseDefinition`. */
|
|
1254
|
-
get(id: string): Promise<DatabaseDefinition | undefined>;
|
|
1255
|
-
/** Insert or replace under the definition's OWN `id` (no separate id param) — the row is `{ id, definition }`. */
|
|
1256
|
-
set(definition: DatabaseDefinition): Promise<void>;
|
|
1257
|
-
/** Drop a definition by id; an absent id is a no-op (no throw). */
|
|
1258
|
-
delete(id: string): Promise<void>;
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
/**
|
|
1262
|
-
* Resolve database definitions into cached live handles for database tools.
|
|
1263
|
-
*
|
|
1264
|
-
* @example
|
|
1265
|
-
* ```ts
|
|
1266
|
-
* import { DatabaseResolver } from '@orkestrel/tool'
|
|
1267
|
-
*
|
|
1268
|
-
* const resolver = new DatabaseResolver(handles, drivers, key, store)
|
|
1269
|
-
* const database = await resolver.resolve('shop')
|
|
1270
|
-
* ```
|
|
1271
|
-
*/
|
|
1272
|
-
export declare class DatabaseResolver {
|
|
1273
|
-
#private;
|
|
1274
|
-
/**
|
|
1275
|
-
* Create a database resolver over the tool's live state and optional definition store.
|
|
1276
|
-
*
|
|
1277
|
-
* @param handles - Initial live database handles cached by id
|
|
1278
|
-
* @param drivers - Driver factories keyed by definition driver name
|
|
1279
|
-
* @param key - Key generator supplied to newly created databases
|
|
1280
|
-
* @param store - Optional persistent definition store
|
|
1281
|
-
*/
|
|
1282
|
-
constructor(handles: ReadonlyMap<string, DatabaseInterface>, drivers: Readonly<Record<string, () => DriverInterface>>, key: KeyFunction, store?: DefinitionStoreInterface);
|
|
1283
|
-
/**
|
|
1284
|
-
* Determine whether a live database is cached by id.
|
|
1285
|
-
*
|
|
1286
|
-
* @param id - Database id
|
|
1287
|
-
* @returns Whether a live handle is cached
|
|
1288
|
-
*/
|
|
1289
|
-
has(id: string): boolean;
|
|
1290
|
-
/**
|
|
1291
|
-
* Read a cached database without consulting the definition store.
|
|
1292
|
-
*
|
|
1293
|
-
* @param id - Database id
|
|
1294
|
-
* @returns The cached live database, or `undefined`
|
|
1295
|
-
*/
|
|
1296
|
-
get(id: string): DatabaseInterface | undefined;
|
|
1297
|
-
/**
|
|
1298
|
-
* Cache a live database by id.
|
|
1299
|
-
*
|
|
1300
|
-
* @param id - Database id
|
|
1301
|
-
* @param database - Live database handle
|
|
1302
|
-
* @returns Nothing
|
|
1303
|
-
*/
|
|
1304
|
-
set(id: string, database: DatabaseInterface): void;
|
|
1305
|
-
/**
|
|
1306
|
-
* Remove a cached live database by id.
|
|
1307
|
-
*
|
|
1308
|
-
* @param id - Database id
|
|
1309
|
-
* @returns Nothing
|
|
1310
|
-
*/
|
|
1311
|
-
delete(id: string): void;
|
|
1312
|
-
/**
|
|
1313
|
-
* Resolve a cached or stored database by id.
|
|
1314
|
-
*
|
|
1315
|
-
* @param id - Database definition id
|
|
1316
|
-
* @returns The cached or newly constructed live database
|
|
1317
|
-
*/
|
|
1318
|
-
resolve(id: string): Promise<DatabaseInterface>;
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
/**
|
|
1322
|
-
* Map a caught error to the {@link AgentToolErrorCode} the upcoming database tool should throw
|
|
1323
|
-
* with — the pure classification step of that factory's error handling, mirroring
|
|
1324
|
-
* {@link terminalToolCode}'s idiom for `@orkestrel/database`.
|
|
1325
|
-
*
|
|
1326
|
-
* @param error - The value caught from a `@orkestrel/database` table operation
|
|
1327
|
-
* @returns The granular {@link DatabaseErrorCode}, or `undefined` if `error` is not a `DatabaseError`
|
|
1328
|
-
*/
|
|
1329
|
-
export declare function databaseToolCode(error: unknown): DatabaseErrorCode | undefined;
|
|
1330
|
-
|
|
1331
|
-
/**
|
|
1332
|
-
* Options for {@link import('./factories.js').createDatabaseTool} — SRC-2 of the 3-unit database
|
|
1333
|
-
* / relation spine, built over the SRC-1 foundation ({@link DatabaseDefinition},
|
|
1334
|
-
* {@link DefinitionStoreInterface}, {@link import('./helpers.js').expandTables}).
|
|
1335
|
-
*
|
|
1336
|
-
* @remarks
|
|
1337
|
-
* - `databases` — live `DatabaseInterface` handles to seed the tool's cache with (e.g. a
|
|
1338
|
-
* caller-constructed database it should manage alongside store-backed ones); keyed by the id a
|
|
1339
|
-
* call's `id` field addresses.
|
|
1340
|
-
* - `store` — the {@link DefinitionStoreInterface} the `'create'` / `'migrate'` operations persist
|
|
1341
|
-
* their {@link DatabaseDefinition} CONFIG through, and `'destroy'` deletes from; also the source
|
|
1342
|
-
* `'get'`/every other operation resolves an id from when it isn't already cached. Omitted means
|
|
1343
|
-
* no persistence — a database created without a store lives only for the tool's lifetime.
|
|
1344
|
-
* - `drivers` — registry of driver-name to `() => DriverInterface` factories a `'create'` call's
|
|
1345
|
-
* `driver` field (or a persisted definition's `driver`) resolves against. Defaults to
|
|
1346
|
-
* `{ memory: () => createMemoryDriver() }` (`@orkestrel/database`).
|
|
1347
|
-
* - `key` — the `KeyFunction` (`@orkestrel/database`) every minted database is constructed with,
|
|
1348
|
-
* used when a written row lacks its primary key. Defaults to `generateUUID`.
|
|
1349
|
-
* - `limit` — the row cap `'records'` / `'remove'` — via {@link import('./helpers.js').clampCriteria}
|
|
1350
|
-
* — enforce when a call's `criteria.limit` is omitted or exceeds it. Defaults to
|
|
1351
|
-
* {@link import('./constants.js').DATABASE_TOOL_LIMIT}.
|
|
1352
|
-
* - `timeout` — milliseconds; when set, every `@orkestrel/database` call this tool makes is given
|
|
1353
|
-
* a fresh `AbortSignal.timeout(timeout)` per tool call.
|
|
1354
|
-
* - `readonly` — when `true`, every mutating operation (`'create'` / `'add'` / `'set'` /
|
|
1355
|
-
* `'update'` / `'remove'` / `'migrate'` / `'destroy'`) throws a typed `TOOL`
|
|
1356
|
-
* {@link import('./errors.js').AgentToolError} before doing anything.
|
|
1357
|
-
* - `name` / `description` — advertised tool overrides; default to
|
|
1358
|
-
* {@link import('./constants.js').DATABASE_TOOL_NAME} / {@link import('./constants.js').DATABASE_TOOL_DESCRIPTION}.
|
|
1359
|
-
*/
|
|
1360
|
-
export declare interface DatabaseToolOptions {
|
|
1361
|
-
readonly name?: string;
|
|
1362
|
-
readonly description?: string;
|
|
1363
|
-
readonly databases?: Readonly<Record<string, DatabaseInterface>>;
|
|
1364
|
-
readonly store?: DefinitionStoreInterface;
|
|
1365
|
-
readonly drivers?: Readonly<Record<string, () => DriverInterface>>;
|
|
1366
|
-
readonly key?: KeyFunction;
|
|
1367
|
-
readonly limit?: number;
|
|
1368
|
-
readonly timeout?: number;
|
|
1369
|
-
readonly readonly?: boolean;
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
/**
|
|
1373
|
-
* The shape of {@link import('./factories.js').createDatabaseTool}'s call arguments —
|
|
1374
|
-
* discriminated by `operation` into the 12 database operations (`'create'` / `'tables'` /
|
|
1375
|
-
* `'get'` / `'records'` / `'count'` / `'aggregate'` / `'add'` / `'set'` / `'update'` /
|
|
1376
|
-
* `'remove'` / `'migrate'` / `'destroy'`).
|
|
1377
|
-
*
|
|
1378
|
-
* @remarks
|
|
1379
|
-
* Every arm carries `id` (the database id). `'create'` / `'migrate'` carry `tables` (the
|
|
1380
|
-
* {@link import('./types.js').TableSpec} column DSL, compiled via
|
|
1381
|
-
* {@link import('./helpers.js').expandTables}); `'get'` / `'update'` / `'remove'` carry `key`
|
|
1382
|
-
* (one key or an array of keys, positional); `'add'` / `'set'` carry `row` (one row or an array of
|
|
1383
|
-
* rows); `'update'` also carries `changes` (a loose partial row); `'records'` / `'count'` /
|
|
1384
|
-
* `'aggregate'` carry an optional `criteria` (the SERIALIZED form — `values` is ALWAYS an array,
|
|
1385
|
-
* even for a single-value operator, so a caller never chains method calls or guesses arity).
|
|
1386
|
-
*/
|
|
1387
|
-
export declare const databaseToolShape: UnionShape<readonly [ ObjectShape<{
|
|
1388
|
-
operation: LiteralShape<readonly ["create"]>;
|
|
1389
|
-
id: StringShape;
|
|
1390
|
-
tables: ObjectShape<Record<never, never>, ObjectShape<{
|
|
1391
|
-
columns: ObjectShape<Record<never, never>, UnionShape<readonly [ LiteralShape<readonly ["string", "integer", "number", "boolean"]>, ObjectShape<{
|
|
1392
|
-
type: LiteralShape<readonly ["string", "integer", "number", "boolean"]>;
|
|
1393
|
-
optional: OptionalShape<BooleanShape>;
|
|
1394
|
-
}, false>]>>;
|
|
1395
|
-
}, false>>;
|
|
1396
|
-
driver: OptionalShape<StringShape>;
|
|
1397
|
-
keys: OptionalShape<ObjectShape<Record<never, never>, StringShape>>;
|
|
1398
|
-
}, false>, ObjectShape<{
|
|
1399
|
-
operation: LiteralShape<readonly ["tables"]>;
|
|
1400
|
-
id: StringShape;
|
|
1401
|
-
}, false>, ObjectShape<{
|
|
1402
|
-
operation: LiteralShape<readonly ["get"]>;
|
|
1403
|
-
id: StringShape;
|
|
1404
|
-
table: StringShape;
|
|
1405
|
-
key: UnionShape<readonly [ ArrayShape<UnionShape<readonly [ StringShape, NumberShape]>>, StringShape, NumberShape]>;
|
|
1406
|
-
}, false>, ObjectShape<{
|
|
1407
|
-
operation: LiteralShape<readonly ["records"]>;
|
|
1408
|
-
id: StringShape;
|
|
1409
|
-
table: StringShape;
|
|
1410
|
-
criteria: OptionalShape<ObjectShape<{
|
|
1411
|
-
conditions: OptionalShape<ArrayShape<ObjectShape<{
|
|
1412
|
-
column: StringShape;
|
|
1413
|
-
operator: LiteralShape<readonly ["equals", "not", "above", "below", "from", "to", "between", "like", "glob", "starts", "ends", "any", "none", "absent", "present"]>;
|
|
1414
|
-
values: ArrayShape<JSONShape>;
|
|
1415
|
-
connector: OptionalShape<LiteralShape<readonly ["and", "or"]>>;
|
|
1416
|
-
}, false>>>;
|
|
1417
|
-
order: OptionalShape<ArrayShape<ObjectShape<{
|
|
1418
|
-
column: StringShape;
|
|
1419
|
-
direction: LiteralShape<readonly ["ascending", "descending"]>;
|
|
1420
|
-
}, false>>>;
|
|
1421
|
-
limit: OptionalShape<NumberShape>;
|
|
1422
|
-
offset: OptionalShape<NumberShape>;
|
|
1423
|
-
}, false>>;
|
|
1424
|
-
}, false>, ObjectShape<{
|
|
1425
|
-
operation: LiteralShape<readonly ["count"]>;
|
|
1426
|
-
id: StringShape;
|
|
1427
|
-
table: StringShape;
|
|
1428
|
-
criteria: OptionalShape<ObjectShape<{
|
|
1429
|
-
conditions: OptionalShape<ArrayShape<ObjectShape<{
|
|
1430
|
-
column: StringShape;
|
|
1431
|
-
operator: LiteralShape<readonly ["equals", "not", "above", "below", "from", "to", "between", "like", "glob", "starts", "ends", "any", "none", "absent", "present"]>;
|
|
1432
|
-
values: ArrayShape<JSONShape>;
|
|
1433
|
-
connector: OptionalShape<LiteralShape<readonly ["and", "or"]>>;
|
|
1434
|
-
}, false>>>;
|
|
1435
|
-
order: OptionalShape<ArrayShape<ObjectShape<{
|
|
1436
|
-
column: StringShape;
|
|
1437
|
-
direction: LiteralShape<readonly ["ascending", "descending"]>;
|
|
1438
|
-
}, false>>>;
|
|
1439
|
-
limit: OptionalShape<NumberShape>;
|
|
1440
|
-
offset: OptionalShape<NumberShape>;
|
|
1441
|
-
}, false>>;
|
|
1442
|
-
}, false>, ObjectShape<{
|
|
1443
|
-
operation: LiteralShape<readonly ["aggregate"]>;
|
|
1444
|
-
id: StringShape;
|
|
1445
|
-
table: StringShape;
|
|
1446
|
-
function: LiteralShape<readonly ["count", "sum", "average", "minimum", "maximum"]>;
|
|
1447
|
-
column: StringShape;
|
|
1448
|
-
criteria: OptionalShape<ObjectShape<{
|
|
1449
|
-
conditions: OptionalShape<ArrayShape<ObjectShape<{
|
|
1450
|
-
column: StringShape;
|
|
1451
|
-
operator: LiteralShape<readonly ["equals", "not", "above", "below", "from", "to", "between", "like", "glob", "starts", "ends", "any", "none", "absent", "present"]>;
|
|
1452
|
-
values: ArrayShape<JSONShape>;
|
|
1453
|
-
connector: OptionalShape<LiteralShape<readonly ["and", "or"]>>;
|
|
1454
|
-
}, false>>>;
|
|
1455
|
-
order: OptionalShape<ArrayShape<ObjectShape<{
|
|
1456
|
-
column: StringShape;
|
|
1457
|
-
direction: LiteralShape<readonly ["ascending", "descending"]>;
|
|
1458
|
-
}, false>>>;
|
|
1459
|
-
limit: OptionalShape<NumberShape>;
|
|
1460
|
-
offset: OptionalShape<NumberShape>;
|
|
1461
|
-
}, false>>;
|
|
1462
|
-
}, false>, ObjectShape<{
|
|
1463
|
-
operation: LiteralShape<readonly ["add"]>;
|
|
1464
|
-
id: StringShape;
|
|
1465
|
-
table: StringShape;
|
|
1466
|
-
row: UnionShape<readonly [ ArrayShape<ObjectShape<Record<never, never>, JSONShape>>, ObjectShape<Record<never, never>, JSONShape>]>;
|
|
1467
|
-
}, false>, ObjectShape<{
|
|
1468
|
-
operation: LiteralShape<readonly ["set"]>;
|
|
1469
|
-
id: StringShape;
|
|
1470
|
-
table: StringShape;
|
|
1471
|
-
row: UnionShape<readonly [ ArrayShape<ObjectShape<Record<never, never>, JSONShape>>, ObjectShape<Record<never, never>, JSONShape>]>;
|
|
1472
|
-
}, false>, ObjectShape<{
|
|
1473
|
-
operation: LiteralShape<readonly ["update"]>;
|
|
1474
|
-
id: StringShape;
|
|
1475
|
-
table: StringShape;
|
|
1476
|
-
key: UnionShape<readonly [ ArrayShape<UnionShape<readonly [ StringShape, NumberShape]>>, StringShape, NumberShape]>;
|
|
1477
|
-
changes: ObjectShape<Record<never, never>, JSONShape>;
|
|
1478
|
-
}, false>, ObjectShape<{
|
|
1479
|
-
operation: LiteralShape<readonly ["remove"]>;
|
|
1480
|
-
id: StringShape;
|
|
1481
|
-
table: StringShape;
|
|
1482
|
-
key: UnionShape<readonly [ ArrayShape<UnionShape<readonly [ StringShape, NumberShape]>>, StringShape, NumberShape]>;
|
|
1483
|
-
}, false>, ObjectShape<{
|
|
1484
|
-
operation: LiteralShape<readonly ["migrate"]>;
|
|
1485
|
-
id: StringShape;
|
|
1486
|
-
tables: ObjectShape<Record<never, never>, ObjectShape<{
|
|
1487
|
-
columns: ObjectShape<Record<never, never>, UnionShape<readonly [ LiteralShape<readonly ["string", "integer", "number", "boolean"]>, ObjectShape<{
|
|
1488
|
-
type: LiteralShape<readonly ["string", "integer", "number", "boolean"]>;
|
|
1489
|
-
optional: OptionalShape<BooleanShape>;
|
|
1490
|
-
}, false>]>>;
|
|
1491
|
-
}, false>>;
|
|
1492
|
-
}, false>, ObjectShape<{
|
|
1493
|
-
operation: LiteralShape<readonly ["destroy"]>;
|
|
1494
|
-
id: StringShape;
|
|
1495
|
-
}, false>]>;
|
|
1496
|
-
|
|
1497
|
-
/**
|
|
1498
|
-
* The point-access persistence seam (AGENTS §5 — Stores) for {@link DatabaseDefinition} configs —
|
|
1499
|
-
* the twin of `@orkestrel/terminal`'s `TerminalStoreInterface`, storing a database's CONFIG-ONLY
|
|
1500
|
-
* blueprint (never a live handle). Every primitive is async; `delete` of an absent id is a no-op.
|
|
1501
|
-
*/
|
|
1502
|
-
export declare interface DefinitionStoreInterface {
|
|
1503
|
-
get(id: string): Promise<DatabaseDefinition | undefined>;
|
|
1504
|
-
set(definition: DatabaseDefinition): Promise<void>;
|
|
1505
|
-
delete(id: string): Promise<void>;
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
/**
|
|
1509
|
-
* The DESCRIPTION {@link import('./factories.js').createDescribeTool} advertises.
|
|
1510
|
-
*
|
|
1511
|
-
* @remarks
|
|
1512
|
-
* Deliberately short — unlike the workflow / workspace / agent tools, this one has no authoring
|
|
1513
|
-
* schema or multi-step protocol to teach.
|
|
1514
|
-
*/
|
|
1515
|
-
export declare const DESCRIBE_TOOL_DESCRIPTION = "Return the full description of a registered tool by its name. Required: name - the registered tool name (see another tool listing for available names).";
|
|
1516
|
-
|
|
1517
|
-
/**
|
|
1518
|
-
* The name {@link import('./factories.js').createDescribeTool} advertises by default — the key a
|
|
1519
|
-
* model calls and the `ToolManagerInterface` (`@orkestrel/agent`) registers under.
|
|
1520
|
-
*
|
|
1521
|
-
* @remarks
|
|
1522
|
-
* Net-new: pairs with the other three tools' lean {@link AGENT_TOOL_SUMMARY} /
|
|
1523
|
-
* {@link WORKFLOW_TOOL_SUMMARY} / {@link WORKSPACE_TOOL_SUMMARY} — a model that reads only the
|
|
1524
|
-
* advertised summary can call `describe` with that tool's registered name to get its full
|
|
1525
|
-
* teaching description back.
|
|
1526
|
-
*/
|
|
1527
|
-
export declare const DESCRIBE_TOOL_NAME = "describe";
|
|
1528
|
-
|
|
1529
|
-
/**
|
|
1530
|
-
* The lean {@link import('@orkestrel/agent').ToolInterface.summary} {@link import('./factories.js').createDescribeTool}
|
|
1531
|
-
* advertises — this tool needs no teaching of its own, so its summary and description are both
|
|
1532
|
-
* short.
|
|
1533
|
-
*/
|
|
1534
|
-
export declare const DESCRIBE_TOOL_SUMMARY = "Return the full description of a named registered tool.";
|
|
1535
|
-
|
|
1536
|
-
/**
|
|
1537
|
-
* The FLAT args {@link import('./factories.js').createDescribeTool} accepts — the registered
|
|
1538
|
-
* tool `name` whose full `description` a model wants back.
|
|
1539
|
-
*
|
|
1540
|
-
* @remarks
|
|
1541
|
-
* `name` must match a tool registered on the {@link import('@orkestrel/agent').ToolManagerInterface}
|
|
1542
|
-
* the describe tool was built over — it is looked up via `tools.tool(name)`.
|
|
1543
|
-
*/
|
|
1544
|
-
export declare interface DescribeToolArguments {
|
|
291
|
+
/** The name of the called tool. */
|
|
1545
292
|
readonly name: string;
|
|
293
|
+
/** The successful return value. */
|
|
294
|
+
readonly value?: unknown;
|
|
295
|
+
/** The failure message. */
|
|
296
|
+
readonly error?: string;
|
|
1546
297
|
}
|
|
1547
298
|
|
|
1548
|
-
/**
|
|
1549
|
-
* The shape of {@link import('./types.js').DescribeToolArguments} —
|
|
1550
|
-
* {@link import('./factories.js').createDescribeTool}'s advertised `parameters`.
|
|
1551
|
-
*
|
|
1552
|
-
* @remarks
|
|
1553
|
-
* `name` is the only field (a non-empty string) — the registered tool name to look up.
|
|
1554
|
-
*/
|
|
1555
|
-
export declare const describeToolShape: ObjectShape<{
|
|
1556
|
-
name: StringShape;
|
|
1557
|
-
}, false>;
|
|
1558
|
-
|
|
1559
|
-
/**
|
|
1560
|
-
* One concrete endpoint {@link import('./factories.js').createEndpointTool} wraps as an
|
|
1561
|
-
* LLM-callable `ToolInterface` — the advertised identity, a non-empty set of example values its
|
|
1562
|
-
* `parameters` are inferred from, and the local handler that runs a call.
|
|
1563
|
-
*
|
|
1564
|
-
* @remarks
|
|
1565
|
-
* `samples` MUST be non-empty — {@link import('./factories.js').createEndpointTool} throws a
|
|
1566
|
-
* typed `TOOL` {@link import('./errors.js').AgentToolError} at CONSTRUCTION when it is empty,
|
|
1567
|
-
* since an empty sample set cannot infer a schema. By DEFAULT ({@link EndpointToolOptions.validate}
|
|
1568
|
-
* `true`) `invoke` receives the PARSED, NORMALIZED args record — a copy of the model-supplied
|
|
1569
|
-
* `args` with each scalar coerced to its inferred type (e.g. a number sent for a string slot
|
|
1570
|
-
* arrives coerced to a string), checked against the same schema advertised as `parameters` — and
|
|
1571
|
-
* a call with a missing required key or a non-coercible value never reaches `invoke` at all (see
|
|
1572
|
-
* {@link EndpointToolOptions.validate}). With
|
|
1573
|
-
* `validate: false`, `invoke` receives the model-supplied `args` VERBATIM (raw passthrough, never
|
|
1574
|
-
* checked against the inferred schema). Either way `invoke`'s return flows back as the tool
|
|
1575
|
-
* call's result; a throw PROPAGATES uncaught, isolated by the `ToolManagerInterface`
|
|
1576
|
-
* (`@orkestrel/agent`) into the canonical error envelope. When `samples` are non-object values,
|
|
1577
|
-
* the advertised schema wraps them under a single required `value` property, so `invoke` receives
|
|
1578
|
-
* an `args` record of the shape `{ value: ... }` — never the bare value.
|
|
1579
|
-
*/
|
|
1580
|
-
export declare interface EndpointDefinition {
|
|
1581
|
-
readonly name: string;
|
|
1582
|
-
readonly description: string;
|
|
1583
|
-
readonly samples: readonly unknown[];
|
|
1584
|
-
readonly invoke: EndpointHandler;
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
/**
|
|
1588
|
-
* The handler {@link import('./types.js').EndpointDefinition.invoke} implements — mirrors
|
|
1589
|
-
* `@orkestrel/agent`'s `ToolOptions.execute` signature EXACTLY (same `Readonly<Record<string,
|
|
1590
|
-
* unknown>>` argument, same `Promise<unknown> | unknown` return) so
|
|
1591
|
-
* `execute: (args) => definition.invoke(args)` typechecks with zero assertions in
|
|
1592
|
-
* {@link import('./factories.js').createEndpointTool}.
|
|
1593
|
-
*/
|
|
1594
|
-
export declare type EndpointHandler = (args: Readonly<Record<string, unknown>>) => Promise<unknown> | unknown;
|
|
1595
|
-
|
|
1596
|
-
/**
|
|
1597
|
-
* Construction-time tuning for {@link import('./factories.js').createEndpointTool} — the
|
|
1598
|
-
* inferred `parameters` schema's `format` / `enum` constraints, and whether that same schema is
|
|
1599
|
-
* ENFORCED at `execute` time.
|
|
1600
|
-
*
|
|
1601
|
-
* @remarks
|
|
1602
|
-
* `format` / `enum` default to `false`, matching `@orkestrel/contract`'s own
|
|
1603
|
-
* `ValueToSchemaOptions` defaults. `validate` defaults to `true`: the schema
|
|
1604
|
-
* `createEndpointTool` advertises as `parameters` (`samplesToSchema` + `schemaToObject`) is
|
|
1605
|
-
* compiled ONCE at construction (via `@orkestrel/contract` 0.0.7's `schemaToShape`) into a
|
|
1606
|
-
* `ContractInterface` used to `parse` every call's `args` before `invoke` runs — a NORMALIZING
|
|
1607
|
-
* parse: a scalar value is COERCED to its inferred type where the house parsers coerce (a number
|
|
1608
|
-
* to/from a numeric string, a boolean from `'1'`/`'0'`/`'true'`/`'false'`/`1`/`0`), so `invoke`
|
|
1609
|
-
* receives the COERCED values (e.g. `7` sent for a string slot arrives at `invoke` as `'7'`), not
|
|
1610
|
-
* the raw call args. A call whose `args` fails to parse — a required key missing, or a value not
|
|
1611
|
-
* coercible to its slot's type — THROWS a typed `TOOL` {@link import('./errors.js').AgentToolError}
|
|
1612
|
-
* carrying the structured `explain` faults, and `invoke` is never called. Beyond that coercion,
|
|
1613
|
-
* enforcement is STRUCTURAL — required keys, `enum` membership, and numeric bounds — `format`
|
|
1614
|
-
* annotations (`email`, `date-time`, `uuid`, `uri`, ...) are NEVER asserted, mirroring
|
|
1615
|
-
* `@orkestrel/contract`'s own widening-only law for `schemaToShape`: a `format: true`-tuned
|
|
1616
|
-
* endpoint still ACCEPTS a non-conforming string in a format-tagged slot. A key NOT present in
|
|
1617
|
-
* the inferred (closed, `additionalProperties: false`) schema is NEVER a rejection either — it is
|
|
1618
|
-
* SILENTLY DROPPED before `invoke` runs (the same leniency `@orkestrel/contract`'s own `parse`
|
|
1619
|
-
* grants a closed object generally), so `invoke` may see fewer keys than the caller sent. Set
|
|
1620
|
-
* `validate: false` to restore the PRE-0.0.7 behavior exactly — `execute` passes the
|
|
1621
|
-
* model-supplied `args` straight to `invoke` UNCHANGED, unchecked and unstripped.
|
|
1622
|
-
*/
|
|
1623
|
-
export declare interface EndpointToolOptions {
|
|
1624
|
-
readonly format?: boolean;
|
|
1625
|
-
readonly enum?: boolean;
|
|
1626
|
-
readonly validate?: boolean;
|
|
1627
|
-
}
|
|
1628
|
-
|
|
1629
|
-
/**
|
|
1630
|
-
* Expand the relation tool's FLAT dot-path `include` list into a live `@orkestrel/relation`
|
|
1631
|
-
* {@link Include} tree — the pure leaf {@link import('./factories.js').createRelationTool} calls
|
|
1632
|
-
* before a `'load'` / `'find'` call.
|
|
1633
|
-
*
|
|
1634
|
-
* @remarks
|
|
1635
|
-
* Each path splits on `'.'` into a chain of relation names, deep-merged into one nested
|
|
1636
|
-
* `Include` object with a leaf `true`. A longer path SUBSUMES a shorter sibling's bare `true` —
|
|
1637
|
-
* `'contacts'` followed by `'contacts.account'` yields `{ contacts: { account: true } }`, never
|
|
1638
|
-
* overwriting the deeper chain. An EMPTY segment (`''`, from a leading/trailing/doubled `.`) or a
|
|
1639
|
-
* path whose segment count exceeds `depth` throws a typed `TOOL` {@link AgentToolError}.
|
|
1640
|
-
*
|
|
1641
|
-
* @param paths - The flat dot-path `include` list (or `undefined` — yields `{}`)
|
|
1642
|
-
* @param depth - The max segment count a single path may reach
|
|
1643
|
-
* @returns The equivalent nested {@link Include}
|
|
1644
|
-
*
|
|
1645
|
-
* @example
|
|
1646
|
-
* ```ts
|
|
1647
|
-
* import { expandInclude } from '@src/core'
|
|
1648
|
-
*
|
|
1649
|
-
* expandInclude(['contacts', 'contacts.account'], 3)
|
|
1650
|
-
* // { contacts: { account: true } }
|
|
1651
|
-
* ```
|
|
1652
|
-
*/
|
|
1653
|
-
export declare function expandInclude(paths: readonly string[] | undefined, depth: number): Include;
|
|
1654
|
-
|
|
1655
|
-
/**
|
|
1656
|
-
* Expand a flat {@link WorkflowSteps} blob into a strict {@link WorkflowDefinition} — each step
|
|
1657
|
-
* becomes a one-task phase, IN ORDER.
|
|
1658
|
-
*
|
|
1659
|
-
* @remarks
|
|
1660
|
-
* The expansion of the tool's ADVERTISED surface: the deliberately-reduced flat form. Each
|
|
1661
|
-
* {@link import('./types.js').WorkflowStep} maps to a phase holding exactly one task: the step's
|
|
1662
|
-
* `name` becomes the task's `run` (the behavior-registry key). Ids/names are auto-filled
|
|
1663
|
-
* positionally — it builds an ids-omitted {@link WorkflowDraft} and delegates to
|
|
1664
|
-
* {@link completeDraft}, so the two lenient surfaces share ONE synthesis path (step `i` → phase
|
|
1665
|
-
* `phase-<i>`, its task `phase-<i>-task-0`). The optional `name` becomes the workflow's `name`.
|
|
1666
|
-
* The result is a complete definition the caller validates against the STRICT contract before
|
|
1667
|
-
* running.
|
|
1668
|
-
*
|
|
1669
|
-
* @param flat - The flat steps blob (`{ name?, steps: [{ name }] }`)
|
|
1670
|
-
* @returns A complete {@link WorkflowDefinition} (one one-task phase per step)
|
|
1671
|
-
*/
|
|
1672
|
-
export declare function expandSteps(flat: WorkflowSteps): WorkflowDefinition;
|
|
1673
|
-
|
|
1674
|
-
/**
|
|
1675
|
-
* Compile a {@link TableSpec} into the `@orkestrel/database` {@link TablesShape} it configures —
|
|
1676
|
-
* each {@link ColumnSpec} maps to the matching primitive shaper (`'string'` → `stringShape()`,
|
|
1677
|
-
* `'integer'` → `integerShape()`, `'number'` → `numberShape()`, `'boolean'` → `booleanShape()`),
|
|
1678
|
-
* wrapped in `optionalShape` when the column declares `optional: true`. Total, pure.
|
|
1679
|
-
*
|
|
1680
|
-
* @param spec - The small-model-facing table layout
|
|
1681
|
-
* @returns The compiled `TablesShape` a `@orkestrel/database` `createDatabase` call accepts
|
|
1682
|
-
*/
|
|
1683
|
-
export declare function expandTables(spec: TableSpec): TablesShape;
|
|
1684
|
-
|
|
1685
|
-
/** Flat dot-path relation include list, expanded via {@link import('./helpers.js').expandInclude}. */
|
|
1686
|
-
export declare const includeShape: OptionalShape<ArrayShape<StringShape>>;
|
|
1687
|
-
|
|
1688
|
-
export declare const INFER_TOOL_DESCRIPTION: string;
|
|
1689
|
-
|
|
1690
|
-
/**
|
|
1691
|
-
* The name {@link import('./factories.js').createInferTool} advertises by default — the key a
|
|
1692
|
-
* model calls and the `ToolManagerInterface` (`@orkestrel/agent`) registers under.
|
|
1693
|
-
*/
|
|
1694
|
-
export declare const INFER_TOOL_NAME = "infer";
|
|
1695
|
-
|
|
1696
|
-
/**
|
|
1697
|
-
* The lean {@link import('@orkestrel/agent').ToolInterface.summary} {@link import('./factories.js').createInferTool}
|
|
1698
|
-
* advertises in place of {@link INFER_TOOL_DESCRIPTION} — a `ToolManagerInterface.definitions()`
|
|
1699
|
-
* (`@orkestrel/agent`) advertises `summary ?? description`, so this one-sentence text stands in
|
|
1700
|
-
* for the full teaching description; the full text stays retrievable via
|
|
1701
|
-
* {@link import('./factories.js').createDescribeTool}.
|
|
1702
|
-
*/
|
|
1703
|
-
export declare const INFER_TOOL_SUMMARY = "Infer a JSON Schema (as advertised tool parameters) from one or more example values. Call describe('infer') for the required fields.";
|
|
1704
|
-
|
|
1705
|
-
/**
|
|
1706
|
-
* Options for {@link import('./factories.js').createInferTool} — advertised name/description
|
|
1707
|
-
* overrides only; `format` / `enum` are RUNTIME call arguments (see
|
|
1708
|
-
* {@link import('./shapers.js').inferToolShape}), not construction-time options, since a model
|
|
1709
|
-
* chooses them per call.
|
|
1710
|
-
*/
|
|
1711
|
-
export declare interface InferToolOptions {
|
|
1712
|
-
readonly name?: string;
|
|
1713
|
-
readonly description?: string;
|
|
1714
|
-
}
|
|
1715
|
-
|
|
1716
|
-
/**
|
|
1717
|
-
* The shape of {@link import('./factories.js').createInferTool}'s call arguments — one or more
|
|
1718
|
-
* example `samples` to infer a JSON Schema from, plus per-call `format` / `enum` toggles and an
|
|
1719
|
-
* optional `candidates` array to check against the inferred schema.
|
|
1720
|
-
*
|
|
1721
|
-
* @remarks
|
|
1722
|
-
* `samples` requires at least one element (`min: 1`) — an empty array parses to `undefined`,
|
|
1723
|
-
* surfaced by the handler as a typed `TOOL` {@link import('./errors.js').AgentToolError}. When
|
|
1724
|
-
* `candidates` is present (any array, including empty), the handler compiles a contract from the
|
|
1725
|
-
* freshly inferred schema and checks each candidate against it with a STRICT guard (`.is`, no
|
|
1726
|
-
* coercion) — the opposite of {@link import('./factories.js').createEndpointTool}'s NORMALIZING
|
|
1727
|
-
* `.parse` enforcement.
|
|
1728
|
-
*/
|
|
1729
|
-
export declare const inferToolShape: ObjectShape<{
|
|
1730
|
-
samples: ArrayShape<JSONShape>;
|
|
1731
|
-
format: OptionalShape<BooleanShape>;
|
|
1732
|
-
enum: OptionalShape<BooleanShape>;
|
|
1733
|
-
candidates: OptionalShape<ArrayShape<JSONShape>>;
|
|
1734
|
-
}, false>;
|
|
1735
|
-
|
|
1736
|
-
/**
|
|
1737
|
-
* Type guard narrowing an unknown caught value to an {@link AgentToolError}.
|
|
1738
|
-
*
|
|
1739
|
-
* @param value - The value to test (typically a `catch` binding)
|
|
1740
|
-
* @returns `true` when `value` is an {@link AgentToolError}
|
|
1741
|
-
*
|
|
1742
|
-
* @example
|
|
1743
|
-
* ```ts
|
|
1744
|
-
* import { isAgentToolError } from '@src/core'
|
|
1745
|
-
*
|
|
1746
|
-
* try {
|
|
1747
|
-
* // ...
|
|
1748
|
-
* } catch (error) {
|
|
1749
|
-
* if (isAgentToolError(error)) console.log(error.code)
|
|
1750
|
-
* }
|
|
1751
|
-
* ```
|
|
1752
|
-
*/
|
|
1753
|
-
export declare function isAgentToolError(value: unknown): value is AgentToolError;
|
|
1754
|
-
|
|
1755
|
-
/** Narrow an unknown value to a {@link import('./types.js').ColumnKind}. */
|
|
1756
|
-
export declare function isColumnKind(value: unknown): value is ColumnKind;
|
|
1757
|
-
|
|
1758
|
-
/** Narrow an unknown value to a {@link ColumnSpec} — a valid {@link import('./types.js').ColumnKind} shorthand, or `{ type, optional }` with a valid `type`. */
|
|
1759
|
-
export declare function isColumnSpec(value: unknown): value is ColumnSpec;
|
|
1760
|
-
|
|
1761
|
-
/**
|
|
1762
|
-
* Narrow an unknown value to a {@link DatabaseDefinition} — a non-empty `id` + `driver`, a
|
|
1763
|
-
* `tables` record whose every value is `{ columns: record of valid ColumnSpec }`, and an optional
|
|
1764
|
-
* `keys` record of strings. The boundary guard a {@link import('./types.js').DefinitionStoreInterface}
|
|
1765
|
-
* applies to an untrusted persisted blob before trusting it as a definition (never an `as`).
|
|
1766
|
-
*/
|
|
1767
|
-
export declare function isDatabaseDefinition(value: unknown): value is DatabaseDefinition;
|
|
1768
|
-
|
|
1769
|
-
/** One key value — a string or number; the array form (multiple keys, positional) resolves FIRST per AGENTS §9.2. */
|
|
1770
|
-
export declare const keyShape: UnionShape<readonly [ ArrayShape<UnionShape<readonly [ StringShape, NumberShape]>>, StringShape, NumberShape]>;
|
|
1771
|
-
|
|
1772
|
-
/** Map one {@link import('./types.js').ColumnKind} to its primitive `@orkestrel/database` shape — the leaf {@link columnShape} wraps. */
|
|
1773
|
-
export declare function kindShape(kind: ColumnKind): ContractShape;
|
|
1774
|
-
|
|
1775
|
-
/** Which registered relation manager to address — omitted resolves to the sole registered manager. */
|
|
1776
|
-
export declare const managerShape: OptionalShape<StringShape>;
|
|
1777
|
-
|
|
1778
|
-
/**
|
|
1779
|
-
* The maximum nesting depth a workflow → agent → workflow chain may reach — the bound
|
|
1780
|
-
* {@link import('./factories.js').createAgentFunction} and
|
|
1781
|
-
* {@link import('./factories.js').createWorkflowTool}'s depth/cycle guards enforce.
|
|
1782
|
-
*
|
|
1783
|
-
* @remarks
|
|
1784
|
-
* OWNED here now (ported from `@orkestrel/workflow`, whose engine no longer uses it — only the
|
|
1785
|
-
* tool-authoring guards this package now owns consume it). The limit lives in ONE place: an
|
|
1786
|
-
* agent-function-wrapped agent running at this depth can no longer author + run a NESTED
|
|
1787
|
-
* workflow through its bound workflow tool (that would be depth `MAX_WORKFLOW_DEPTH + 1`), so
|
|
1788
|
-
* the over-deep invocation is REJECTED (a typed `DEPTH` `WorkflowError` throw, `@orkestrel/workflow`).
|
|
1789
|
-
*/
|
|
1790
|
-
export declare const MAX_WORKFLOW_DEPTH = 8;
|
|
1791
|
-
|
|
1792
|
-
/**
|
|
1793
|
-
* The in-memory {@link DefinitionStoreInterface} — a process-lifetime `Map` of
|
|
1794
|
-
* {@link DatabaseDefinition}s keyed by database id, the DEFAULT store
|
|
1795
|
-
* {@link import('../factories.js').createMemoryDefinitionStore} builds. The EXACT twin of
|
|
1796
|
-
* {@link import('./DatabaseDefinitionStore.js').DatabaseDefinitionStore}.
|
|
1797
|
-
*
|
|
1798
|
-
* @remarks
|
|
1799
|
-
* A plain `Map<string, DatabaseDefinition>` (AGENTS §21 — the definition is already pure,
|
|
1800
|
-
* self-contained CONFIG-only JSON, so no encoding is needed for the memory tier). There is NO
|
|
1801
|
-
* idle-TTL and NO eviction: a persisted definition lives until an explicit `delete`. A durable
|
|
1802
|
-
* backend (JSON / SQLite / IndexedDB) swaps in through the SAME interface without touching a
|
|
1803
|
-
* consumer — its driver-pluggable twin is
|
|
1804
|
-
* {@link import('./DatabaseDefinitionStore.js').DatabaseDefinitionStore} (the definition as one
|
|
1805
|
-
* opaque JSON column).
|
|
1806
|
-
*
|
|
1807
|
-
* - **`get` resolves the persisted definition for an id**, or `undefined` if none is stored.
|
|
1808
|
-
* - **`set` inserts / replaces under the definition's OWN `id`** (no separate id param).
|
|
1809
|
-
* - **`delete` drops a definition by id**; an absent id is a no-op (no throw).
|
|
1810
|
-
*
|
|
1811
|
-
* The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the §22 method
|
|
1812
|
-
* bijection with {@link DefinitionStoreInterface}).
|
|
1813
|
-
*
|
|
1814
|
-
* @example
|
|
1815
|
-
* ```ts
|
|
1816
|
-
* import { createMemoryDefinitionStore } from '@src/core'
|
|
1817
|
-
*
|
|
1818
|
-
* const store = createMemoryDefinitionStore()
|
|
1819
|
-
* await store.set({ id: 'shop', driver: 'memory', tables: {} })
|
|
1820
|
-
* const definition = await store.get('shop')
|
|
1821
|
-
* await store.delete('shop')
|
|
1822
|
-
* ```
|
|
1823
|
-
*/
|
|
1824
|
-
export declare class MemoryDefinitionStore implements DefinitionStoreInterface {
|
|
1825
|
-
#private;
|
|
1826
|
-
get(id: string): Promise<DatabaseDefinition | undefined>;
|
|
1827
|
-
set(definition: DatabaseDefinition): Promise<void>;
|
|
1828
|
-
delete(id: string): Promise<void>;
|
|
1829
|
-
}
|
|
1830
|
-
|
|
1831
|
-
/** One sort term. */
|
|
1832
|
-
export declare const orderShape: ObjectShape<{
|
|
1833
|
-
column: StringShape;
|
|
1834
|
-
direction: LiteralShape<readonly ["ascending", "descending"]>;
|
|
1835
|
-
}, false>;
|
|
1836
|
-
|
|
1837
|
-
/** A draft phase — a `PhaseDefinition` (`@orkestrel/workflow`) with OPTIONAL `id` / `name` and {@link TaskDraft} tasks. */
|
|
1838
|
-
export declare interface PhaseDraft {
|
|
1839
|
-
readonly id?: string;
|
|
1840
|
-
readonly name?: string;
|
|
1841
|
-
readonly description?: string;
|
|
1842
|
-
readonly tasks: readonly TaskDraft[];
|
|
1843
|
-
/** Max tasks in flight at once (a resource throttle); omitted ⇒ unbounded. */
|
|
1844
|
-
readonly concurrency?: number;
|
|
1845
|
-
/** The per-phase failure-policy OVERRIDE; omitted ⇒ inherits the workflow `bail`. */
|
|
1846
|
-
readonly bail?: boolean;
|
|
1847
|
-
}
|
|
1848
|
-
|
|
1849
|
-
/**
|
|
1850
|
-
* The shape of a PHASE in a draft workflow — identical to a strict phase shape EXCEPT `id` and
|
|
1851
|
-
* `name` are OPTIONAL, and its tasks are {@link taskDraftShape}s.
|
|
1852
|
-
*/
|
|
1853
|
-
export declare const phaseDraftShape: ObjectShape<{
|
|
1854
|
-
id: OptionalShape<StringShape>;
|
|
1855
|
-
name: OptionalShape<StringShape>;
|
|
1856
|
-
description: OptionalShape<StringShape>;
|
|
1857
|
-
tasks: ArrayShape<ObjectShape<{
|
|
1858
|
-
id: OptionalShape<StringShape>;
|
|
1859
|
-
name: OptionalShape<StringShape>;
|
|
1860
|
-
description: OptionalShape<StringShape>;
|
|
1861
|
-
run: OptionalShape<StringShape>;
|
|
1862
|
-
retries: OptionalShape<NumberShape>;
|
|
1863
|
-
timeout: OptionalShape<NumberShape>;
|
|
1864
|
-
}, false>>;
|
|
1865
|
-
concurrency: OptionalShape<NumberShape>;
|
|
1866
|
-
bail: OptionalShape<LiteralShape<readonly [true, false]>>;
|
|
1867
|
-
}, false>;
|
|
1868
|
-
|
|
1869
|
-
export declare const PROMPT_TOOL_DESCRIPTION: string;
|
|
1870
|
-
|
|
1871
|
-
/**
|
|
1872
|
-
* The name {@link import('./factories.js').createPromptTool} advertises by default — the key a
|
|
1873
|
-
* model calls and the `ToolManagerInterface` (`@orkestrel/agent`) registers under.
|
|
1874
|
-
*/
|
|
1875
|
-
export declare const PROMPT_TOOL_NAME = "ask";
|
|
1876
|
-
|
|
1877
|
-
/**
|
|
1878
|
-
* The lean {@link import('@orkestrel/agent').ToolInterface.summary} {@link import('./factories.js').createPromptTool}
|
|
1879
|
-
* advertises in place of {@link PROMPT_TOOL_DESCRIPTION} — a `ToolManagerInterface.definitions()`
|
|
1880
|
-
* (`@orkestrel/agent`) advertises `summary ?? description`, so this one-sentence text stands in
|
|
1881
|
-
* for the full teaching description; the full text stays retrievable via
|
|
1882
|
-
* {@link import('./factories.js').createDescribeTool}.
|
|
1883
|
-
*/
|
|
1884
|
-
export declare const PROMPT_TOOL_SUMMARY = "Ask another terminal a question and BLOCK until it answers; the call resolves with the answered value. Call describe('ask') for the required fields.";
|
|
1885
|
-
|
|
1886
|
-
/**
|
|
1887
|
-
* Options for {@link import('./factories.js').createPromptTool} — the live
|
|
1888
|
-
* {@link TerminalManagerInterface} (`@orkestrel/terminal`) to `ask` through, the terminal name
|
|
1889
|
-
* `from`, and the advertised tool overrides.
|
|
1890
|
-
*
|
|
1891
|
-
* @remarks
|
|
1892
|
-
* - `manager` — the terminal manager whose `ask(from, to, form, options)` the tool's handler
|
|
1893
|
-
* calls; BLOCKS the calling agent turn until the addressed terminal answers (or the ask
|
|
1894
|
-
* rejects — a cycle throws `TerminalError('DEADLOCK')`, re-surfaced as a typed `DEADLOCK`
|
|
1895
|
-
* {@link import('./errors.js').AgentToolError}; an expired prompt re-surfaces as `EXPIRE`).
|
|
1896
|
-
* - `from` — the terminal identity this tool asks AS; the model supplies the `to` target and the
|
|
1897
|
-
* prompt form per call.
|
|
1898
|
-
* - `name` / `description` — advertised tool overrides; default to
|
|
1899
|
-
* {@link import('./constants.js').PROMPT_TOOL_NAME} / {@link import('./constants.js').PROMPT_TOOL_DESCRIPTION}.
|
|
1900
|
-
*/
|
|
1901
|
-
export declare interface PromptToolOptions {
|
|
1902
|
-
readonly manager: TerminalManagerInterface;
|
|
1903
|
-
readonly from: string;
|
|
1904
|
-
readonly name?: string;
|
|
1905
|
-
readonly description?: string;
|
|
1906
|
-
}
|
|
1907
|
-
|
|
1908
|
-
/**
|
|
1909
|
-
* The shape of {@link import('./factories.js').createPromptTool}'s call arguments — `to` (the
|
|
1910
|
-
* terminal identity to address), `form` (which of the six {@link import('@orkestrel/terminal').PromptType}
|
|
1911
|
-
* forms to ask), `message`, an optional `timeout` override, and every per-form optional field
|
|
1912
|
-
* FLATTENED onto one object (mirrors `workspaceToolShape`'s flat-arm style, but a single shared
|
|
1913
|
-
* shape rather than a discriminated union — `form` alone does not vary the REQUIRED fields, only
|
|
1914
|
-
* which of the optional ones apply, so a flat shape stays faithful without duplicating `to` /
|
|
1915
|
-
* `message` / `timeout` across six near-identical arms).
|
|
1916
|
-
*
|
|
1917
|
-
* @remarks
|
|
1918
|
-
* `choices` backs `'select'` / `'checkbox'`; `default` backs `'input'` / `'confirm'` / `'select'`
|
|
1919
|
-
* (a string for the first two forms' text default, `'true'`/`'false'` string for confirm — the
|
|
1920
|
-
* contract layer cannot vary a field's type by a sibling field's value, so `default` stays a
|
|
1921
|
-
* string and the handler coerces per form); `mask` backs `'password'`; `min` / `max` backs
|
|
1922
|
-
* `'checkbox'`; `validate` (declarative only) backs the four text-shaped forms
|
|
1923
|
-
* (`'input'` / `'password'` / `'confirm'` / `'editor'`).
|
|
1924
|
-
*/
|
|
1925
|
-
export declare const promptToolShape: ObjectShape<{
|
|
1926
|
-
to: StringShape;
|
|
1927
|
-
form: LiteralShape<readonly ["input", "password", "confirm", "select", "checkbox", "editor"]>;
|
|
1928
|
-
message: StringShape;
|
|
1929
|
-
default: OptionalShape<StringShape>;
|
|
1930
|
-
choices: OptionalShape<ArrayShape<ObjectShape<{
|
|
1931
|
-
name: StringShape;
|
|
1932
|
-
value: StringShape;
|
|
1933
|
-
description: OptionalShape<StringShape>;
|
|
1934
|
-
}, boolean | ContractShape>>>;
|
|
1935
|
-
mask: OptionalShape<StringShape>;
|
|
1936
|
-
min: OptionalShape<NumberShape>;
|
|
1937
|
-
max: OptionalShape<NumberShape>;
|
|
1938
|
-
validate: OptionalShape<ObjectShape<{
|
|
1939
|
-
required: OptionalShape<BooleanShape>;
|
|
1940
|
-
minimum: OptionalShape<NumberShape>;
|
|
1941
|
-
maximum: OptionalShape<NumberShape>;
|
|
1942
|
-
pattern: OptionalShape<StringShape>;
|
|
1943
|
-
email: OptionalShape<BooleanShape>;
|
|
1944
|
-
url: OptionalShape<BooleanShape>;
|
|
1945
|
-
numeric: OptionalShape<BooleanShape>;
|
|
1946
|
-
integer: OptionalShape<BooleanShape>;
|
|
1947
|
-
alphanumeric: OptionalShape<BooleanShape>;
|
|
1948
|
-
}, boolean | ContractShape>>;
|
|
1949
|
-
timeout: OptionalShape<NumberShape>;
|
|
1950
|
-
}, false>;
|
|
1951
|
-
|
|
1952
|
-
/** The default cap on how many `include` path segments deep a `load` / `find` call may traverse — the relation tool's default include-depth ceiling. */
|
|
1953
|
-
export declare const RELATION_TOOL_DEPTH = 3;
|
|
1954
|
-
|
|
1955
|
-
/**
|
|
1956
|
-
* The DESCRIPTION the relation tool advertises — a multi-line guide that teaches a small model
|
|
1957
|
-
* the operation list and the flat dot-path `include` syntax.
|
|
1958
|
-
*
|
|
1959
|
-
* @remarks
|
|
1960
|
-
* An include path is a FLAT dot-separated string (`'contacts.account'`), never a nested object —
|
|
1961
|
-
* the same small-model ergonomic lever the other tools in this package use for flat args.
|
|
1962
|
-
*/
|
|
1963
|
-
export declare const RELATION_TOOL_DESCRIPTION: string;
|
|
1964
|
-
|
|
1965
|
-
/** The default cap on rows a `find` / `links` call returns when the caller omits `limit` — the relation tool's default row ceiling. */
|
|
1966
|
-
export declare const RELATION_TOOL_LIMIT = 1000;
|
|
1967
|
-
|
|
1968
|
-
/**
|
|
1969
|
-
* The name `createRelationTool` advertises by default — the key a model calls and the
|
|
1970
|
-
* `ToolManagerInterface` (`@orkestrel/agent`) registers under.
|
|
1971
|
-
*/
|
|
1972
|
-
export declare const RELATION_TOOL_NAME = "relation";
|
|
1973
|
-
|
|
1974
|
-
/**
|
|
1975
|
-
* The lean {@link import('@orkestrel/agent').ToolInterface.summary} the relation tool advertises
|
|
1976
|
-
* in place of {@link RELATION_TOOL_DESCRIPTION}.
|
|
1977
|
-
*/
|
|
1978
|
-
export declare const RELATION_TOOL_SUMMARY = "Traverse and edit relationships between database rows \u2014 one operation per call (load, find, link, unlink, links), chosen by the 'operation' field. Call describe('relation') for the include-path syntax.";
|
|
1979
|
-
|
|
1980
|
-
/** One key value — a string or number; the array form (multiple keys, positional) resolves FIRST per AGENTS §9.2. */
|
|
1981
|
-
export declare const relationKeyShape: UnionShape<readonly [ ArrayShape<UnionShape<readonly [ StringShape, NumberShape]>>, StringShape, NumberShape]>;
|
|
1982
|
-
|
|
1983
|
-
/**
|
|
1984
|
-
* Resolve which registered {@link RelationManagerInterface} a relation-tool call addresses — the
|
|
1985
|
-
* pure manager-resolution leaf {@link import('./factories.js').createRelationTool} calls on
|
|
1986
|
-
* every operation.
|
|
1987
|
-
*
|
|
1988
|
-
* @remarks
|
|
1989
|
-
* An explicit `name` must match a key of `managers` (a miss throws a typed `TOOL`
|
|
1990
|
-
* {@link AgentToolError} naming the registered managers). An OMITTED `name` resolves to the sole
|
|
1991
|
-
* registered manager when exactly one is registered, else throws the same typed error.
|
|
1992
|
-
*
|
|
1993
|
-
* @param managers - The tool's registered `RelationManagerInterface` map
|
|
1994
|
-
* @param name - The call's optional `manager` field
|
|
1995
|
-
* @returns The resolved {@link RelationManagerInterface}
|
|
1996
|
-
*/
|
|
1997
|
-
export declare function relationManagerOf(managers: Readonly<Record<string, RelationManagerInterface>>, name: string | undefined): RelationManagerInterface;
|
|
1998
|
-
|
|
1999
|
-
/**
|
|
2000
|
-
* Resolve a `model` name against a live {@link RelationManagerInterface} — the pure model-lookup
|
|
2001
|
-
* leaf {@link import('./factories.js').createRelationTool} calls on every operation, mirroring
|
|
2002
|
-
* {@link relationManagerOf}'s guard shape.
|
|
2003
|
-
*
|
|
2004
|
-
* @param manager - The resolved {@link RelationManagerInterface}
|
|
2005
|
-
* @param name - The call's `model` field
|
|
2006
|
-
* @returns The model's {@link ModelInterface}
|
|
2007
|
-
*/
|
|
2008
|
-
export declare function relationModelOf(manager: RelationManagerInterface, name: string): ModelInterface;
|
|
2009
|
-
|
|
2010
|
-
/**
|
|
2011
|
-
* Map a caught error to the {@link AgentToolErrorCode} the upcoming relation tool should throw
|
|
2012
|
-
* with — the pure classification step of that factory's error handling, mirroring
|
|
2013
|
-
* {@link terminalToolCode}'s idiom for `@orkestrel/relation`.
|
|
2014
|
-
*
|
|
2015
|
-
* @param error - The value caught from a `@orkestrel/relation` operation
|
|
2016
|
-
* @returns The granular {@link RelationErrorCode}, or `undefined` if `error` is not a `RelationError`
|
|
2017
|
-
*/
|
|
2018
|
-
export declare function relationToolCode(error: unknown): RelationErrorCode | undefined;
|
|
2019
|
-
|
|
2020
|
-
/**
|
|
2021
|
-
* Options for {@link import('./factories.js').createRelationTool} — SRC-3 (the final unit) of
|
|
2022
|
-
* the 3-unit database / relation spine.
|
|
2023
|
-
*
|
|
2024
|
-
* @remarks
|
|
2025
|
-
* - `managers` — the live `RelationManagerInterface` (`@orkestrel/relation`) registry a call's
|
|
2026
|
-
* optional `manager` field addresses by name; REQUIRED (unlike the database tool's lazily
|
|
2027
|
-
* resolved handles, a relation manager's relations are declared up front and cannot be minted
|
|
2028
|
-
* on demand from a tool call). A call that omits `manager` resolves to the SOLE registered
|
|
2029
|
-
* manager when exactly one is registered, else throws a typed `TOOL`
|
|
2030
|
-
* {@link import('./errors.js').AgentToolError} naming the registered manager keys.
|
|
2031
|
-
* - `limit` — the row cap `'find'` / `'links'` enforce when a call's `limit` is omitted or
|
|
2032
|
-
* exceeds it. Defaults to {@link import('./constants.js').RELATION_TOOL_LIMIT}.
|
|
2033
|
-
* - `depth` — the max dot-path segment count `'load'` / `'find'`'s `include` paths may reach
|
|
2034
|
-
* ({@link import('./helpers.js').expandInclude}). Defaults to
|
|
2035
|
-
* {@link import('./constants.js').RELATION_TOOL_DEPTH}.
|
|
2036
|
-
* - `name` / `description` — advertised tool overrides; default to
|
|
2037
|
-
* {@link import('./constants.js').RELATION_TOOL_NAME} / {@link import('./constants.js').RELATION_TOOL_DESCRIPTION}.
|
|
2038
|
-
*/
|
|
2039
|
-
export declare interface RelationToolOptions {
|
|
2040
|
-
readonly name?: string;
|
|
2041
|
-
readonly description?: string;
|
|
2042
|
-
readonly managers: Readonly<Record<string, RelationManagerInterface>>;
|
|
2043
|
-
readonly limit?: number;
|
|
2044
|
-
readonly depth?: number;
|
|
2045
|
-
}
|
|
2046
|
-
|
|
2047
|
-
/**
|
|
2048
|
-
* The shape of {@link import('./factories.js').createRelationTool}'s call arguments —
|
|
2049
|
-
* discriminated by `operation` into the 5 relation operations (`'load'` / `'find'` / `'link'` /
|
|
2050
|
-
* `'unlink'` / `'links'`).
|
|
2051
|
-
*
|
|
2052
|
-
* @remarks
|
|
2053
|
-
* `'load'` fetches one or more rows (positional key/array) with `include` attached. `'find'`
|
|
2054
|
-
* fetches rows (pagination / sort only) with `include` attached. `'link'` / `'unlink'` write /
|
|
2055
|
-
* remove a `through` junction row; `'links'` lists a `through` relation's linked keys.
|
|
2056
|
-
*/
|
|
2057
|
-
export declare const relationToolShape: UnionShape<readonly [ ObjectShape<{
|
|
2058
|
-
operation: LiteralShape<readonly ["load"]>;
|
|
2059
|
-
manager: OptionalShape<StringShape>;
|
|
2060
|
-
model: StringShape;
|
|
2061
|
-
key: UnionShape<readonly [ ArrayShape<UnionShape<readonly [ StringShape, NumberShape]>>, StringShape, NumberShape]>;
|
|
2062
|
-
include: OptionalShape<ArrayShape<StringShape>>;
|
|
2063
|
-
}, false>, ObjectShape<{
|
|
2064
|
-
operation: LiteralShape<readonly ["find"]>;
|
|
2065
|
-
manager: OptionalShape<StringShape>;
|
|
2066
|
-
model: StringShape;
|
|
2067
|
-
include: OptionalShape<ArrayShape<StringShape>>;
|
|
2068
|
-
limit: OptionalShape<NumberShape>;
|
|
2069
|
-
offset: OptionalShape<NumberShape>;
|
|
2070
|
-
sort: OptionalShape<StringShape>;
|
|
2071
|
-
direction: OptionalShape<LiteralShape<readonly ["ascending", "descending"]>>;
|
|
2072
|
-
}, false>, ObjectShape<{
|
|
2073
|
-
operation: LiteralShape<readonly ["link"]>;
|
|
2074
|
-
manager: OptionalShape<StringShape>;
|
|
2075
|
-
model: StringShape;
|
|
2076
|
-
key: UnionShape<readonly [ StringShape, NumberShape]>;
|
|
2077
|
-
relation: StringShape;
|
|
2078
|
-
target: UnionShape<readonly [ StringShape, NumberShape]>;
|
|
2079
|
-
}, false>, ObjectShape<{
|
|
2080
|
-
operation: LiteralShape<readonly ["unlink"]>;
|
|
2081
|
-
manager: OptionalShape<StringShape>;
|
|
2082
|
-
model: StringShape;
|
|
2083
|
-
key: UnionShape<readonly [ StringShape, NumberShape]>;
|
|
2084
|
-
relation: StringShape;
|
|
2085
|
-
target: UnionShape<readonly [ StringShape, NumberShape]>;
|
|
2086
|
-
}, false>, ObjectShape<{
|
|
2087
|
-
operation: LiteralShape<readonly ["links"]>;
|
|
2088
|
-
manager: OptionalShape<StringShape>;
|
|
2089
|
-
model: StringShape;
|
|
2090
|
-
key: UnionShape<readonly [ StringShape, NumberShape]>;
|
|
2091
|
-
relation: StringShape;
|
|
2092
|
-
}, false>]>;
|
|
2093
|
-
|
|
2094
|
-
/** A loose row — a flat object of column name to JSON value; the array form (multiple rows) resolves FIRST per AGENTS §9.2. */
|
|
2095
|
-
export declare const rowShape: ObjectShape<Record<never, never>, JSONShape>;
|
|
2096
|
-
|
|
2097
|
-
/** One or many loose rows — the array form resolves FIRST per AGENTS §9.2. */
|
|
2098
|
-
export declare const rowsShape: UnionShape<readonly [ ArrayShape<ObjectShape<Record<never, never>, JSONShape>>, ObjectShape<Record<never, never>, JSONShape>]>;
|
|
2099
|
-
|
|
2100
|
-
/** A single row key (not an array) — used by `'link'` / `'unlink'` / `'links'`, which address exactly one owning row. */
|
|
2101
|
-
export declare const singleKeyShape: UnionShape<readonly [ StringShape, NumberShape]>;
|
|
2102
|
-
|
|
2103
|
-
/**
|
|
2104
|
-
* The shape of ONE flat step — `{ name }` — the building block of {@link workflowStepsShape}.
|
|
2105
|
-
*
|
|
2106
|
-
* @remarks
|
|
2107
|
-
* `name` is the REGISTERED behavior name the step runs (it becomes the task's `run`). The tool
|
|
2108
|
-
* expands each step into a one-task phase, in order ({@link import('./helpers.js').expandSteps}).
|
|
2109
|
-
*/
|
|
2110
|
-
export declare const stepShape: ObjectShape<{
|
|
2111
|
-
name: StringShape;
|
|
2112
|
-
}, false>;
|
|
2113
|
-
|
|
2114
|
-
/**
|
|
2115
|
-
* Build one {@link TableSchema} from a table NAME and its `@orkestrel/database` `TableExport` —
|
|
2116
|
-
* the "deployed" schema shape `DatabaseInterface.migrate` diffs against, derived from a LIVE
|
|
2117
|
-
* handle's `export()` rather than a re-declared {@link TableSpec}, so it works for ANY handle
|
|
2118
|
-
* (config-tracked or caller-supplied).
|
|
2119
|
-
*
|
|
2120
|
-
* @param name - The table name
|
|
2121
|
-
* @param table - The table's `TableExport` (`{ key, columns }`, `@orkestrel/database`)
|
|
2122
|
-
* @returns The equivalent {@link TableSchema} (`indexes` empty — this package declares none)
|
|
2123
|
-
*/
|
|
2124
|
-
export declare function tableSchema(name: string, table: Readonly<{
|
|
2125
|
-
key: string;
|
|
2126
|
-
columns: Readonly<Record<string, ContractShape>>;
|
|
2127
|
-
}>): TableSchema;
|
|
2128
|
-
|
|
2129
|
-
/**
|
|
2130
|
-
* A database's table layout — one entry per table, each a flat map of column name to
|
|
2131
|
-
* {@link ColumnSpec}. The small-model-facing DSL {@link import('./helpers.js').expandTables}
|
|
2132
|
-
* compiles into an `@orkestrel/database` `TablesShape`.
|
|
2133
|
-
*/
|
|
2134
|
-
export declare type TableSpec = Readonly<Record<string, Readonly<{
|
|
2135
|
-
columns: Readonly<Record<string, ColumnSpec>>;
|
|
2136
|
-
}>>>;
|
|
2137
|
-
|
|
2138
|
-
/** A {@link import('./types.js').TableSpec} — table name to `{ columns }`, each column a {@link columnSpecShape}. */
|
|
2139
|
-
export declare const tableSpecShape: ObjectShape<Record<never, never>, ObjectShape<{
|
|
2140
|
-
columns: ObjectShape<Record<never, never>, UnionShape<readonly [ LiteralShape<readonly ["string", "integer", "number", "boolean"]>, ObjectShape<{
|
|
2141
|
-
type: LiteralShape<readonly ["string", "integer", "number", "boolean"]>;
|
|
2142
|
-
optional: OptionalShape<BooleanShape>;
|
|
2143
|
-
}, false>]>>;
|
|
2144
|
-
}, false>>;
|
|
2145
|
-
|
|
2146
|
-
/**
|
|
2147
|
-
* A draft task — a `TaskDefinition` (`@orkestrel/workflow`) with OPTIONAL `id` / `name`.
|
|
2148
|
-
*
|
|
2149
|
-
* @remarks
|
|
2150
|
-
* The tool synthesizes a missing `id` positionally and defaults a missing `name` to its `id`
|
|
2151
|
-
* ({@link import('./helpers.js').completeDraft}). A PROVIDED `id` / `name` is preserved verbatim
|
|
2152
|
-
* (and must be non-empty — the draft contract's `minLength: 1`).
|
|
2153
|
-
*/
|
|
2154
|
-
export declare interface TaskDraft {
|
|
2155
|
-
readonly id?: string;
|
|
2156
|
-
readonly name?: string;
|
|
2157
|
-
readonly description?: string;
|
|
2158
|
-
/** The behavior reference — a registry key resolved against a workflow's functions registry at construction; omitted ⇒ no handler. */
|
|
2159
|
-
readonly run?: string;
|
|
2160
|
-
/** Extra attempts after the first on failure (a non-negative integer); overrides the phase Runner default. Execution-only. */
|
|
2161
|
-
readonly retries?: number;
|
|
2162
|
-
/** The per-attempt deadline in milliseconds (a non-negative integer); overrides the phase Runner default. Execution-only. */
|
|
2163
|
-
readonly timeout?: number;
|
|
2164
|
-
}
|
|
2165
|
-
|
|
2166
|
-
/**
|
|
2167
|
-
* The shape of a {@link import('./types.js').TaskDraft} — identical to a strict task shape
|
|
2168
|
-
* EXCEPT `id` and `name` are OPTIONAL.
|
|
2169
|
-
*/
|
|
2170
|
-
export declare const taskDraftShape: ObjectShape<{
|
|
2171
|
-
id: OptionalShape<StringShape>;
|
|
2172
|
-
name: OptionalShape<StringShape>;
|
|
2173
|
-
description: OptionalShape<StringShape>;
|
|
2174
|
-
run: OptionalShape<StringShape>;
|
|
2175
|
-
retries: OptionalShape<NumberShape>;
|
|
2176
|
-
timeout: OptionalShape<NumberShape>;
|
|
2177
|
-
}, false>;
|
|
2178
|
-
|
|
2179
|
-
/**
|
|
2180
|
-
* Map a caught error to the {@link AgentToolErrorCode} the terminal-tool factory should throw
|
|
2181
|
-
* with — the pure classification step of that factory's error handling.
|
|
2182
|
-
*
|
|
2183
|
-
* @remarks
|
|
2184
|
-
* Narrows `error` with {@link isTerminalError} (`@orkestrel/terminal`) first: a non-`TerminalError`
|
|
2185
|
-
* value returns `undefined`, telling the caller this mapper does not apply (rethrow / handle
|
|
2186
|
-
* otherwise). For a genuine `TerminalError`, `'DEADLOCK'` maps to `'DEADLOCK'`, `'EXPIRE'` maps
|
|
2187
|
-
* to `'EXPIRE'`, and every other {@link import('@orkestrel/terminal').TerminalErrorCode}
|
|
2188
|
-
* (`'TARGET'`, `'CANCEL'`, `'DRIVER'`) maps to the generic `'TOOL'` code. The mapper only
|
|
2189
|
-
* classifies — the factory performs the actual throw.
|
|
2190
|
-
*
|
|
2191
|
-
* @param error - The value caught from a terminal-manager operation (`ask` / `answer` / …)
|
|
2192
|
-
* @returns The mapped {@link AgentToolErrorCode}, or `undefined` if `error` is not a `TerminalError`
|
|
2193
|
-
*/
|
|
2194
|
-
export declare function terminalToolCode(error: unknown): AgentToolErrorCode | undefined;
|
|
2195
|
-
|
|
2196
|
-
export declare const WORKFLOW_TOOL_DESCRIPTION: string;
|
|
2197
|
-
|
|
2198
|
-
/**
|
|
2199
|
-
* A complete FLAT authoring example — the PRIMARY way a small model authors a workflow through
|
|
2200
|
-
* {@link import('./factories.js').createWorkflowTool}: `{ name, steps: [{ name }] }`.
|
|
2201
|
-
*
|
|
2202
|
-
* @remarks
|
|
2203
|
-
* OWNED here now (ported from `@orkestrel/workflow`). Each step becomes a one-task phase, in
|
|
2204
|
-
* order; a step's `name` is a REGISTERED behavior name (not a label) — the registry key its
|
|
2205
|
-
* task's `run` resolves against. The tool expands this
|
|
2206
|
-
* ({@link import('./helpers.js').expandSteps}) into a valid `WorkflowDefinition`
|
|
2207
|
-
* (`@orkestrel/workflow`). It is embedded VERBATIM in {@link WORKFLOW_TOOL_DESCRIPTION}.
|
|
2208
|
-
*/
|
|
2209
|
-
export declare const WORKFLOW_TOOL_FLAT_EXAMPLE: WorkflowSteps;
|
|
2210
|
-
|
|
2211
|
-
/**
|
|
2212
|
-
* The name {@link import('./factories.js').createWorkflowTool} advertises by default — the key a
|
|
2213
|
-
* model calls and the `ToolManagerInterface` (`@orkestrel/agent`) registers under, and the name
|
|
2214
|
-
* {@link import('./factories.js').createAgentFunction} binds the depth/cycle-aware workflow tool
|
|
2215
|
-
* under onto a wrapped agent's `context.tools`.
|
|
2216
|
-
*
|
|
2217
|
-
* @remarks
|
|
2218
|
-
* OWNED here now (ported from `@orkestrel/workflow`). The propagation seam's well-known key: when
|
|
2219
|
-
* `createAgentFunction`'s `runner` option is supplied, it adds a `createWorkflowTool`-built tool
|
|
2220
|
-
* under this name to the agent's `context.tools`, so it can author + run a NESTED workflow
|
|
2221
|
-
* (bounded by {@link MAX_WORKFLOW_DEPTH}).
|
|
2222
|
-
*/
|
|
2223
|
-
export declare const WORKFLOW_TOOL_NAME = "workflow";
|
|
2224
|
-
|
|
2225
|
-
/**
|
|
2226
|
-
* A minimal NESTED authoring example — the ADVANCED escape-hatch form a model may use instead of
|
|
2227
|
-
* the flat shape: a full `WorkflowDefinition` (`@orkestrel/workflow`).
|
|
2228
|
-
*
|
|
2229
|
-
* @remarks
|
|
2230
|
-
* OWNED here now (ported from `@orkestrel/workflow`). The full four-level form, documented in
|
|
2231
|
-
* {@link WORKFLOW_TOOL_DESCRIPTION} as the advanced alternative. It is embedded VERBATIM.
|
|
2232
|
-
*/
|
|
2233
|
-
export declare const WORKFLOW_TOOL_NESTED_EXAMPLE: WorkflowDefinition;
|
|
2234
|
-
|
|
2235
|
-
/**
|
|
2236
|
-
* The lean {@link import('@orkestrel/agent').ToolInterface.summary} {@link import('./factories.js').createWorkflowTool}
|
|
2237
|
-
* advertises in place of {@link WORKFLOW_TOOL_DESCRIPTION} — a `ToolManagerInterface.definitions()`
|
|
2238
|
-
* (`@orkestrel/agent`) advertises `summary ?? description`, so this one-sentence text stands in
|
|
2239
|
-
* for the full teaching description; the full text stays retrievable via
|
|
2240
|
-
* {@link import('./factories.js').createDescribeTool}.
|
|
2241
|
-
*/
|
|
2242
|
-
export declare const WORKFLOW_TOOL_SUMMARY = "Author and run a multi-phase workflow in one call \u2014 phases run in sequence, tasks within a phase run concurrently. Call describe('workflow') for the full authoring schema and examples.";
|
|
2243
|
-
|
|
2244
|
-
/**
|
|
2245
|
-
* A draft workflow — a `WorkflowDefinition` (`@orkestrel/workflow`) with OPTIONAL `id` / `name`
|
|
2246
|
-
* at all three levels (workflow / phase / task).
|
|
2247
|
-
*
|
|
2248
|
-
* @remarks
|
|
2249
|
-
* The lenient authoring form {@link import('./factories.js').createWorkflowDraftContract}
|
|
2250
|
-
* validates and {@link import('./helpers.js').completeDraft} completes into a strict
|
|
2251
|
-
* `WorkflowDefinition`. `run` stays optional (a plain name string); the `bail` policy carries
|
|
2252
|
-
* over.
|
|
2253
|
-
*/
|
|
2254
|
-
export declare interface WorkflowDraft {
|
|
2255
|
-
readonly id?: string;
|
|
2256
|
-
readonly name?: string;
|
|
2257
|
-
readonly description?: string;
|
|
2258
|
-
readonly phases: readonly PhaseDraft[];
|
|
2259
|
-
/** Failure policy: `false` (default) continues gracefully, `true` halts on the first failure. */
|
|
2260
|
-
readonly bail?: boolean;
|
|
2261
|
-
}
|
|
2262
|
-
|
|
2263
|
-
/**
|
|
2264
|
-
* The shape of a DRAFT workflow — identical to a strict workflow shape EXCEPT `id` and `name`
|
|
2265
|
-
* are OPTIONAL at all three levels (workflow / phase / task), so a small model can omit the six
|
|
2266
|
-
* identity strings and let the tool synthesize them positionally.
|
|
2267
|
-
*
|
|
2268
|
-
* @remarks
|
|
2269
|
-
* The lenient counterpart {@link import('./factories.js').createWorkflowDraftContract} compiles.
|
|
2270
|
-
* `run` stays required on the strict form; a provided `id` / `name` still has `minLength: 1` (so
|
|
2271
|
-
* an explicitly-empty `id: ''` is REJECTED, not auto-filled). After
|
|
2272
|
-
* {@link import('./helpers.js').completeDraft} fills the missing ids/names, the result is
|
|
2273
|
-
* validated against the STRICT `createWorkflowContract` (`@orkestrel/workflow`) gate before
|
|
2274
|
-
* running.
|
|
2275
|
-
*/
|
|
2276
|
-
export declare const workflowDraftShape: ObjectShape<{
|
|
2277
|
-
id: OptionalShape<StringShape>;
|
|
2278
|
-
name: OptionalShape<StringShape>;
|
|
2279
|
-
description: OptionalShape<StringShape>;
|
|
2280
|
-
phases: ArrayShape<ObjectShape<{
|
|
2281
|
-
id: OptionalShape<StringShape>;
|
|
2282
|
-
name: OptionalShape<StringShape>;
|
|
2283
|
-
description: OptionalShape<StringShape>;
|
|
2284
|
-
tasks: ArrayShape<ObjectShape<{
|
|
2285
|
-
id: OptionalShape<StringShape>;
|
|
2286
|
-
name: OptionalShape<StringShape>;
|
|
2287
|
-
description: OptionalShape<StringShape>;
|
|
2288
|
-
run: OptionalShape<StringShape>;
|
|
2289
|
-
retries: OptionalShape<NumberShape>;
|
|
2290
|
-
timeout: OptionalShape<NumberShape>;
|
|
2291
|
-
}, false>>;
|
|
2292
|
-
concurrency: OptionalShape<NumberShape>;
|
|
2293
|
-
bail: OptionalShape<LiteralShape<readonly [true, false]>>;
|
|
2294
|
-
}, false>>;
|
|
2295
|
-
bail: OptionalShape<LiteralShape<readonly [true, false]>>;
|
|
2296
|
-
}, false>;
|
|
2297
|
-
|
|
2298
|
-
/**
|
|
2299
|
-
* One flat step — `{ name }` — the building block of a {@link WorkflowSteps} blob.
|
|
2300
|
-
*
|
|
2301
|
-
* @remarks
|
|
2302
|
-
* `name` is the REGISTERED behavior name the step runs (it becomes the task's `run`, NOT a
|
|
2303
|
-
* human label) — resolved against a workflow-level functions registry at construction.
|
|
2304
|
-
*/
|
|
2305
|
-
export declare interface WorkflowStep {
|
|
2306
|
-
/** The registered behavior name this step runs (becomes the task's `run`). */
|
|
2307
|
-
readonly name: string;
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
/**
|
|
2311
|
-
* The FLAT authoring blob {@link import('./factories.js').createWorkflowTool} advertises —
|
|
2312
|
-
* `{ name?, steps }` — the simplest surface a small model can fill.
|
|
2313
|
-
*
|
|
2314
|
-
* @remarks
|
|
2315
|
-
* Each {@link WorkflowStep} becomes a one-task phase, in order
|
|
2316
|
-
* ({@link import('./helpers.js').expandSteps}); `name` is the optional workflow name (defaulted
|
|
2317
|
-
* when omitted).
|
|
2318
|
-
*/
|
|
2319
|
-
export declare interface WorkflowSteps {
|
|
2320
|
-
readonly name?: string;
|
|
2321
|
-
readonly steps: readonly WorkflowStep[];
|
|
2322
|
-
}
|
|
2323
|
-
|
|
2324
|
-
/**
|
|
2325
|
-
* The FLAT authoring shape {@link import('./factories.js').createWorkflowTool} advertises as its
|
|
2326
|
-
* `parameters` — the simplest surface a small model can fill: `{ name?, steps: [{ name }] }`.
|
|
2327
|
-
*
|
|
2328
|
-
* @remarks
|
|
2329
|
-
* A deliberately-reduced surface: a flat ordered list of steps, each a `{ name }`. The tool
|
|
2330
|
-
* EXPANDS it ({@link import('./helpers.js').expandSteps}) into a full
|
|
2331
|
-
* {@link import('./types.js').WorkflowDefinition} — one one-task phase per step, in order —
|
|
2332
|
-
* then validates against the STRICT `createWorkflowContract` (`@orkestrel/workflow`) gate. The
|
|
2333
|
-
* full nested form is STILL accepted by the tool (it branches on the args' shape) and is
|
|
2334
|
-
* documented as the advanced escape-hatch in the tool's description — but THIS is what
|
|
2335
|
-
* `parameters` advertises.
|
|
2336
|
-
*/
|
|
2337
|
-
export declare const workflowStepsShape: ObjectShape<{
|
|
2338
|
-
name: OptionalShape<StringShape>;
|
|
2339
|
-
steps: ArrayShape<ObjectShape<{
|
|
2340
|
-
name: StringShape;
|
|
2341
|
-
}, false>>;
|
|
2342
|
-
}, false>;
|
|
2343
|
-
|
|
2344
|
-
/**
|
|
2345
|
-
* The ancestry identifier of a workflow in a run chain — `workflow:<id>`.
|
|
2346
|
-
*
|
|
2347
|
-
* @remarks
|
|
2348
|
-
* Namespacing keeps a workflow id and an {@link agentTag} agent name in ONE set without
|
|
2349
|
-
* collision, so re-entering a workflow OR an agent already in the chain is a single `includes`
|
|
2350
|
-
* check.
|
|
2351
|
-
*
|
|
2352
|
-
* @param id - The workflow definition's `id`
|
|
2353
|
-
* @returns The namespaced ancestry tag (`workflow:<id>`)
|
|
2354
|
-
*/
|
|
2355
|
-
export declare function workflowTag(id: string): string;
|
|
2356
|
-
|
|
2357
|
-
/**
|
|
2358
|
-
* Options for {@link import('./factories.js').createWorkflowTool} — the depth + ancestry a
|
|
2359
|
-
* nested workflow run is bound at, plus the optional durable {@link WorkflowStoreInterface}
|
|
2360
|
-
* (`@orkestrel/workflow`) this package layers on top of the ported handler logic.
|
|
2361
|
-
*
|
|
2362
|
-
* @remarks
|
|
2363
|
-
* This is the PROPAGATION carrier across the agent/tool boundary. A `Tool`'s handler receives
|
|
2364
|
-
* ONLY the model-supplied `args` (no ambient context, no signal — see `@orkestrel/agent`'s
|
|
2365
|
-
* `ToolOptions`), so the run's position in the workflow→agent→workflow chain CANNOT be threaded
|
|
2366
|
-
* through a tool call at runtime. Instead {@link import('./factories.js').createAgentFunction}
|
|
2367
|
-
* CLOSES `depth` / `ancestry` over the tool at BIND time. Both are OPTIONAL: a workflow tool
|
|
2368
|
-
* built for a TOP-LEVEL caller omits them — its nested run starts the chain at depth `1` with
|
|
2369
|
-
* the bare `workflow:<id>` ancestry.
|
|
2370
|
-
*
|
|
2371
|
-
* `store` is this package's ADDITION: when supplied, the tool's handler persists the run's final
|
|
2372
|
-
* snapshot (`store.set(result.workflow.snapshot())`) once the run settles, so a workflow
|
|
2373
|
-
* authored + run through the tool is retrievable / restorable afterwards. Omitted ⇒ no
|
|
2374
|
-
* persistence.
|
|
2375
|
-
*/
|
|
2376
|
-
export declare interface WorkflowToolOptions {
|
|
2377
|
-
/** The depth the INVOKING agent runs at; the nested workflow runs at `depth + 1`. Default `0`. */
|
|
2378
|
-
readonly depth?: number;
|
|
2379
|
-
/** The ancestry of the invoking run; the nested run extends it with its own `workflow:<id>`. Default empty. */
|
|
2380
|
-
readonly ancestry?: readonly string[];
|
|
2381
|
-
readonly store?: WorkflowStoreInterface;
|
|
2382
|
-
}
|
|
2383
|
-
|
|
2384
|
-
/**
|
|
2385
|
-
* Build the plain success summary {@link import('./factories.js').createWorkflowTool} returns on
|
|
2386
|
-
* a completed run — the universal tool-handler contract (AGENTS §14): return a plain value on
|
|
2387
|
-
* success, appearing identically over BOTH the agent loop and MCP.
|
|
2388
|
-
*
|
|
2389
|
-
* @remarks
|
|
2390
|
-
* The summary is LEAN: the workflow's terminal `status` and the COUNT of settled task results —
|
|
2391
|
-
* enough for a caller / model to react without serializing the whole live tree. (It carries no
|
|
2392
|
-
* synthetic `id` / `name`: a tool handler has no call id; the `ToolManagerInterface`
|
|
2393
|
-
* (`@orkestrel/agent`) supplies the canonical envelope's identity.)
|
|
2394
|
-
*
|
|
2395
|
-
* @param result - The terminal `WorkflowResult` (`@orkestrel/workflow`) the run produced
|
|
2396
|
-
* @returns The plain success summary — `{ status, count }`
|
|
2397
|
-
*/
|
|
2398
|
-
export declare function workflowToolSummary(result: WorkflowResult): Readonly<{
|
|
2399
|
-
status: WorkflowStatus;
|
|
2400
|
-
count: number;
|
|
2401
|
-
}>;
|
|
2402
|
-
|
|
2403
|
-
export declare const WORKSPACE_TOOL_DESCRIPTION: string;
|
|
2404
|
-
|
|
2405
|
-
/**
|
|
2406
|
-
* A valid `WorkspaceOperation` (`@orkestrel/agent`) object — the canonical example embedded
|
|
2407
|
-
* VERBATIM in {@link WORKSPACE_TOOL_DESCRIPTION}.
|
|
2408
|
-
*
|
|
2409
|
-
* @remarks
|
|
2410
|
-
* OWNED here now (ported from `@orkestrel/agent`). A `'write'` op (the most common authoring
|
|
2411
|
-
* action): create or overwrite `notes.txt` with `hello`. Frozen so it cannot be mutated in
|
|
2412
|
-
* place.
|
|
2413
|
-
*/
|
|
2414
|
-
export declare const WORKSPACE_TOOL_EXAMPLE: WorkspaceOperation;
|
|
2415
|
-
|
|
2416
|
-
/**
|
|
2417
|
-
* The name {@link import('./factories.js').createWorkspaceTool} advertises by default — the key a
|
|
2418
|
-
* model calls and the `ToolManagerInterface` (`@orkestrel/agent`) registers under.
|
|
2419
|
-
*
|
|
2420
|
-
* @remarks
|
|
2421
|
-
* OWNED here now (ported from `@orkestrel/agent`).
|
|
2422
|
-
*/
|
|
2423
|
-
export declare const WORKSPACE_TOOL_NAME = "workspace";
|
|
2424
|
-
|
|
2425
|
-
/**
|
|
2426
|
-
* The lean {@link import('@orkestrel/agent').ToolInterface.summary} {@link import('./factories.js').createWorkspaceTool}
|
|
2427
|
-
* advertises in place of {@link WORKSPACE_TOOL_DESCRIPTION} — a `ToolManagerInterface.definitions()`
|
|
2428
|
-
* (`@orkestrel/agent`) advertises `summary ?? description`, so this one-sentence text stands in
|
|
2429
|
-
* for the full teaching description; the full text stays retrievable via
|
|
2430
|
-
* {@link import('./factories.js').createDescribeTool}.
|
|
2431
|
-
*/
|
|
2432
|
-
export declare const WORKSPACE_TOOL_SUMMARY = "Read and edit files in a workspace \u2014 one operation per call (read, write, list, search, replace, splice, move, remove, plus workspace switching), chosen by the 'operation' field. Call describe('workspace') for the full operation list and fields.";
|
|
2433
|
-
|
|
2434
|
-
/**
|
|
2435
|
-
* One operation an agent invokes through {@link import('./factories.js').createWorkspaceTool} — a
|
|
2436
|
-
* FLAT, descriptive tagged union over the 13 workspace edit / read / navigation actions,
|
|
2437
|
-
* discriminated by the `operation` literal (AGENTS §4.8: a discriminant is named for its axis —
|
|
2438
|
-
* the action being performed — NEVER `kind`).
|
|
2439
|
-
*
|
|
2440
|
-
* @remarks
|
|
2441
|
-
* This is the SOURCE OF TRUTH the tool contract is typed to
|
|
2442
|
-
* ({@link import('./shapers.js').workspaceToolShape} compiles to a structurally-identical guard /
|
|
2443
|
-
* parser / JSON Schema). Every field is FLAT (no nested objects) — the small-model ergonomic
|
|
2444
|
-
* lever: a range edit is the four flat integers of the `'splice'` arm (`fromLine` /
|
|
2445
|
-
* `fromColumn` / `toLine` / `toColumn`), reassembled into a 1-based `Range` (`@orkestrel/agent`)
|
|
2446
|
-
* by `rangeOf`, never a nested `{ start, end }`. Each EDIT / READ arm maps onto exactly one
|
|
2447
|
-
* `WorkspaceInterface` call against the manager's ACTIVE workspace; the two REGISTRY arms
|
|
2448
|
-
* (`switch` / `workspaces`) drive the {@link WorkspaceManagerInterface} pointer instead —
|
|
2449
|
-
* `workspaces` LISTS the workspaces the model can move between, and `switch` re-points which one
|
|
2450
|
-
* the edit / read arms target.
|
|
2451
|
-
*/
|
|
2452
|
-
export declare type WorkspaceOperation =
|
|
2453
|
-
/** Read a whole text file's text by `path` from the ACTIVE workspace (a binary / absent path — or no active workspace — yields no content). */
|
|
2454
|
-
{
|
|
2455
|
-
readonly operation: 'read';
|
|
2456
|
-
readonly path: string;
|
|
2457
|
-
}
|
|
2458
|
-
/** List every file in the ACTIVE workspace (path / state / size / lines / kind summaries); `[]` when no workspace is active. */
|
|
2459
|
-
| {
|
|
2460
|
-
readonly operation: 'list';
|
|
2461
|
-
}
|
|
2462
|
-
/** Whether a file exists at `path` in the ACTIVE workspace (`false` when no workspace is active). */
|
|
2463
|
-
| {
|
|
2464
|
-
readonly operation: 'has';
|
|
2465
|
-
readonly path: string;
|
|
2466
|
-
}
|
|
2467
|
-
/**
|
|
2468
|
-
* Scan every text file for `query`, returning each hit (path + 1-based line / column + the line).
|
|
2469
|
-
*
|
|
2470
|
-
* @remarks
|
|
2471
|
-
* `regex` treats `query` as a regular-expression source (default `false` — a literal substring);
|
|
2472
|
-
* `exact` matches case-sensitively (default `true`); `limit` caps the total hits returned.
|
|
2473
|
-
*/
|
|
2474
|
-
| {
|
|
2475
|
-
readonly operation: 'search';
|
|
2476
|
-
readonly query: string;
|
|
2477
|
-
readonly regex?: boolean;
|
|
2478
|
-
readonly exact?: boolean;
|
|
2479
|
-
readonly limit?: number;
|
|
2480
|
-
}
|
|
2481
|
-
/**
|
|
2482
|
-
* Replace `query` with `replacement` across every text file, returning the tally.
|
|
2483
|
-
*
|
|
2484
|
-
* @remarks
|
|
2485
|
-
* Same matching axes as `search`: `regex` (default `false`), `exact` (default `true`), `limit`
|
|
2486
|
-
* (cap the total replacements).
|
|
2487
|
-
*/
|
|
2488
|
-
| {
|
|
2489
|
-
readonly operation: 'replace';
|
|
2490
|
-
readonly query: string;
|
|
2491
|
-
readonly replacement: string;
|
|
2492
|
-
readonly regex?: boolean;
|
|
2493
|
-
readonly exact?: boolean;
|
|
2494
|
-
readonly limit?: number;
|
|
2495
|
-
}
|
|
2496
|
-
/** Write (create or overwrite) the whole file at `path` with `content`. */
|
|
2497
|
-
| {
|
|
2498
|
-
readonly operation: 'write';
|
|
2499
|
-
readonly path: string;
|
|
2500
|
-
readonly content: string;
|
|
2501
|
-
}
|
|
2502
|
-
/**
|
|
2503
|
-
* Splice `content` into an existing text file, replacing the 1-based range
|
|
2504
|
-
* `(fromLine, fromColumn)` (INCLUSIVE) → `(toLine, toColumn)` (EXCLUSIVE).
|
|
2505
|
-
*
|
|
2506
|
-
* @remarks
|
|
2507
|
-
* The FLAT range edit — the four positive-integer caret components reassemble into a `Range`
|
|
2508
|
-
* (`@orkestrel/agent`) via `rangeOf`. An empty span (`from === to`) inserts; a span past the
|
|
2509
|
-
* end is clamped. An inverted / sub-1 range throws `RANGE`; a binary target throws
|
|
2510
|
-
* `MODALITY`.
|
|
2511
|
-
*/
|
|
2512
|
-
| {
|
|
2513
|
-
readonly operation: 'splice';
|
|
2514
|
-
readonly path: string;
|
|
2515
|
-
readonly content: string;
|
|
2516
|
-
readonly fromLine: number;
|
|
2517
|
-
readonly fromColumn: number;
|
|
2518
|
-
readonly toLine: number;
|
|
2519
|
-
readonly toColumn: number;
|
|
2520
|
-
}
|
|
2521
|
-
/** Prepend `content` to the start of the file at `path` (creating it when absent). */
|
|
2522
|
-
| {
|
|
2523
|
-
readonly operation: 'prepend';
|
|
2524
|
-
readonly path: string;
|
|
2525
|
-
readonly content: string;
|
|
2526
|
-
}
|
|
2527
|
-
/** Append `content` to the end of the file at `path` (creating it when absent). */
|
|
2528
|
-
| {
|
|
2529
|
-
readonly operation: 'append';
|
|
2530
|
-
readonly path: string;
|
|
2531
|
-
readonly content: string;
|
|
2532
|
-
}
|
|
2533
|
-
/** Re-key the file `from` → `to` (overwriting an occupied target). */
|
|
2534
|
-
| {
|
|
2535
|
-
readonly operation: 'move';
|
|
2536
|
-
readonly from: string;
|
|
2537
|
-
readonly to: string;
|
|
2538
|
-
}
|
|
2539
|
-
/** Remove the file at `path` from the workspace. */
|
|
2540
|
-
| {
|
|
2541
|
-
readonly operation: 'remove';
|
|
2542
|
-
readonly path: string;
|
|
2543
|
-
}
|
|
2544
|
-
/** List the workspaces the model can move between — each `{ id, files, active }` — so it can choose an `id` to `switch` to. */
|
|
2545
|
-
| {
|
|
2546
|
-
readonly operation: 'workspaces';
|
|
2547
|
-
}
|
|
2548
|
-
/** Re-point the manager's ACTIVE workspace to the one with `id` (an unknown `id` is a lenient no-op). The edit / read arms target the active workspace from then on. */
|
|
2549
|
-
| {
|
|
2550
|
-
readonly operation: 'switch';
|
|
2551
|
-
readonly id: string;
|
|
2552
|
-
};
|
|
2553
|
-
|
|
2554
|
-
/**
|
|
2555
|
-
* Options for {@link import('./factories.js').createWorkspaceTool} — EITHER a caller-built
|
|
2556
|
-
* {@link WorkspaceManagerInterface} to drive directly, OR a {@link WorkspaceStoreInterface} the
|
|
2557
|
-
* tool constructs a fresh manager over; neither given constructs a manager over
|
|
2558
|
-
* `@orkestrel/agent`'s in-memory store.
|
|
2559
|
-
*
|
|
2560
|
-
* @remarks
|
|
2561
|
-
* - `manager` — drive THIS manager directly (its `active` workspace is what every edit / read
|
|
2562
|
-
* operation targets). Takes priority over `store` when both are supplied.
|
|
2563
|
-
* - `store` — construct a manager over this durable {@link WorkspaceStoreInterface} (via
|
|
2564
|
-
* `@orkestrel/agent`'s `createWorkspaceManager`) — used only when `manager` is omitted.
|
|
2565
|
-
* The store only backs the manager's own `open` / `save` operations: the tool's edits are
|
|
2566
|
-
* NOT auto-persisted — durability requires an explicit caller `save` on the manager
|
|
2567
|
-
* (unlike the workflow tool's `store`, which persists each executed snapshot on settle).
|
|
2568
|
-
* - `name` / `description` — advertised tool overrides; default to
|
|
2569
|
-
* {@link import('./constants.js').WORKSPACE_TOOL_NAME} / {@link import('./constants.js').WORKSPACE_TOOL_DESCRIPTION}.
|
|
2570
|
-
*/
|
|
2571
|
-
export declare interface WorkspaceToolOptions {
|
|
2572
|
-
readonly name?: string;
|
|
2573
|
-
readonly description?: string;
|
|
2574
|
-
readonly manager?: WorkspaceManagerInterface;
|
|
2575
|
-
readonly store?: WorkspaceStoreInterface;
|
|
2576
|
-
}
|
|
2577
|
-
|
|
2578
|
-
/**
|
|
2579
|
-
* The shape of a {@link import('./types.js').WorkspaceOperation} — a descriptive tagged union
|
|
2580
|
-
* over the 13 workspace edit / read / navigation operations, discriminated by the `operation`
|
|
2581
|
-
* literal (never a bare `kind`; AGENTS §4.4). Each variant leads with its `operation`
|
|
2582
|
-
* discriminant then its FLAT fields, every field via `stringShape` / `optionalShape` /
|
|
2583
|
-
* `integerShape({ min: 1 })` / `booleanShape`, each carrying a strong field-level `description`.
|
|
2584
|
-
*
|
|
2585
|
-
* @remarks
|
|
2586
|
-
* The union compiles to an `anyOf` JSON Schema + a `unionOf` guard + a first-match parser
|
|
2587
|
-
* automatically ({@link import('./factories.js').createWorkspaceTool} types the result to the
|
|
2588
|
-
* hand-written {@link import('./types.js').WorkspaceOperation}). `limit` and the four `'splice'`
|
|
2589
|
-
* caret components are POSITIVE integers (`integerShape({ min: 1 })`); `regex` / `exact` are
|
|
2590
|
-
* `optionalShape(booleanShape(...))`. The two REGISTRY arms — `workspaces` (list the workspaces
|
|
2591
|
-
* the model can move between) and `switch` (re-point the active one by `id`) — let a model
|
|
2592
|
-
* DISCOVER then CHOOSE which workspace the edit / read arms target.
|
|
2593
|
-
*/
|
|
2594
|
-
export declare const workspaceToolShape: UnionShape<readonly [ ObjectShape<{
|
|
2595
|
-
operation: LiteralShape<readonly ["read"]>;
|
|
2596
|
-
path: StringShape;
|
|
2597
|
-
}, false>, ObjectShape<{
|
|
2598
|
-
operation: LiteralShape<readonly ["list"]>;
|
|
2599
|
-
}, false>, ObjectShape<{
|
|
2600
|
-
operation: LiteralShape<readonly ["has"]>;
|
|
2601
|
-
path: StringShape;
|
|
2602
|
-
}, false>, ObjectShape<{
|
|
2603
|
-
operation: LiteralShape<readonly ["search"]>;
|
|
2604
|
-
query: StringShape;
|
|
2605
|
-
regex: OptionalShape<BooleanShape>;
|
|
2606
|
-
exact: OptionalShape<BooleanShape>;
|
|
2607
|
-
limit: OptionalShape<NumberShape>;
|
|
2608
|
-
}, false>, ObjectShape<{
|
|
2609
|
-
operation: LiteralShape<readonly ["replace"]>;
|
|
2610
|
-
query: StringShape;
|
|
2611
|
-
replacement: StringShape;
|
|
2612
|
-
regex: OptionalShape<BooleanShape>;
|
|
2613
|
-
exact: OptionalShape<BooleanShape>;
|
|
2614
|
-
limit: OptionalShape<NumberShape>;
|
|
2615
|
-
}, false>, ObjectShape<{
|
|
2616
|
-
operation: LiteralShape<readonly ["write"]>;
|
|
2617
|
-
path: StringShape;
|
|
2618
|
-
content: StringShape;
|
|
2619
|
-
}, false>, ObjectShape<{
|
|
2620
|
-
operation: LiteralShape<readonly ["splice"]>;
|
|
2621
|
-
path: StringShape;
|
|
2622
|
-
content: StringShape;
|
|
2623
|
-
fromLine: NumberShape;
|
|
2624
|
-
fromColumn: NumberShape;
|
|
2625
|
-
toLine: NumberShape;
|
|
2626
|
-
toColumn: NumberShape;
|
|
2627
|
-
}, false>, ObjectShape<{
|
|
2628
|
-
operation: LiteralShape<readonly ["prepend"]>;
|
|
2629
|
-
path: StringShape;
|
|
2630
|
-
content: StringShape;
|
|
2631
|
-
}, false>, ObjectShape<{
|
|
2632
|
-
operation: LiteralShape<readonly ["append"]>;
|
|
2633
|
-
path: StringShape;
|
|
2634
|
-
content: StringShape;
|
|
2635
|
-
}, false>, ObjectShape<{
|
|
2636
|
-
operation: LiteralShape<readonly ["move"]>;
|
|
2637
|
-
from: StringShape;
|
|
2638
|
-
to: StringShape;
|
|
2639
|
-
}, false>, ObjectShape<{
|
|
2640
|
-
operation: LiteralShape<readonly ["remove"]>;
|
|
2641
|
-
path: StringShape;
|
|
2642
|
-
}, false>, ObjectShape<{
|
|
2643
|
-
operation: LiteralShape<readonly ["workspaces"]>;
|
|
2644
|
-
}, false>, ObjectShape<{
|
|
2645
|
-
operation: LiteralShape<readonly ["switch"]>;
|
|
2646
|
-
id: StringShape;
|
|
2647
|
-
}, false>]>;
|
|
2648
|
-
|
|
2649
299
|
export { }
|