@orkestrel/agent 0.0.11 → 0.0.13
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 +16 -9
- package/dist/src/core/index.cjs +127 -1614
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +108 -1716
- package/dist/src/core/index.d.ts +108 -1716
- package/dist/src/core/index.js +122 -1573
- package/dist/src/core/index.js.map +1 -1
- package/package.json +11 -9
package/dist/src/core/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { DriverInterface } from '@orkestrel/database';
|
|
|
4
4
|
import { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
5
5
|
import { EmitterHooks } from '@orkestrel/emitter';
|
|
6
6
|
import { EmitterInterface } from '@orkestrel/emitter';
|
|
7
|
+
import { JSONValue } from '@orkestrel/contract';
|
|
7
8
|
import { QueueExecution } from '@orkestrel/queue';
|
|
8
9
|
import { QueueInterface } from '@orkestrel/queue';
|
|
9
10
|
import { QueueStoreInterface } from '@orkestrel/queue';
|
|
@@ -11,6 +12,12 @@ import { RunnerInterface } from '@orkestrel/workflow';
|
|
|
11
12
|
import { SchedulerInterface } from '@orkestrel/workflow';
|
|
12
13
|
import { TableInterface } from '@orkestrel/database';
|
|
13
14
|
import { TokenUsage } from '@orkestrel/budget';
|
|
15
|
+
import { ToolCall } from '@orkestrel/tool';
|
|
16
|
+
import { ToolDefinition } from '@orkestrel/tool';
|
|
17
|
+
import { ToolInterface } from '@orkestrel/tool';
|
|
18
|
+
import { ToolManagerInterface } from '@orkestrel/tool';
|
|
19
|
+
import { ToolResult } from '@orkestrel/tool';
|
|
20
|
+
import { WorkspaceManagerInterface } from '@orkestrel/workspace';
|
|
14
21
|
|
|
15
22
|
/**
|
|
16
23
|
* The agent loop — composes a {@link ProviderInterface}, an {@link AgentContext}, and
|
|
@@ -182,8 +189,8 @@ export declare class AgentContext implements AgentContextInterface {
|
|
|
182
189
|
* the conversation, applying the active scope per category.
|
|
183
190
|
*
|
|
184
191
|
* @remarks
|
|
185
|
-
* The richer context — `system` (the optional system prompt), the context managers
|
|
186
|
-
* (`instructions` / `
|
|
192
|
+
* The richer context — `system` (the optional system prompt), the prompt context managers
|
|
193
|
+
* (`instructions` / `workspaces` / `conversations`), `messages` (the active
|
|
187
194
|
* conversation's live tail, satisfying {@link MessageManagerInterface}), and the current `scope`
|
|
188
195
|
* (the active {@link ScopeInterface} filter, or `undefined` for no filtering). `build()` folds the
|
|
189
196
|
* scoped instructions into ONE leading `system` message (under the manager's `description`,
|
|
@@ -225,9 +232,13 @@ export declare interface AgentContextInterface {
|
|
|
225
232
|
* `messages` is always defined. Switch the active conversation through
|
|
226
233
|
* `conversations.switch(id)` — so one agent can serve MANY conversations (set the active one per
|
|
227
234
|
* request). Switch BETWEEN runs, not during one; for CONCURRENT threads use separate agents (see
|
|
228
|
-
* clause
|
|
235
|
+
* clause 23).
|
|
229
236
|
*/
|
|
230
237
|
readonly conversations: ConversationManagerInterface;
|
|
238
|
+
/**
|
|
239
|
+
* The loop's tool registry for provider advertising and call dispatch. Tools are structural
|
|
240
|
+
* loop machinery and never render into `build()`'s prompt.
|
|
241
|
+
*/
|
|
231
242
|
readonly tools: ToolManagerInterface;
|
|
232
243
|
/** The active scope applied at `build()` time + the loop's tool-advertise step (`undefined` ⇒ no filtering). */
|
|
233
244
|
readonly scope: ScopeInterface | undefined;
|
|
@@ -252,12 +263,13 @@ export declare interface AgentContextInterface {
|
|
|
252
263
|
*
|
|
253
264
|
* @remarks
|
|
254
265
|
* **The active workspace (rendered by carrier) — the SOLE document/image context.** When
|
|
255
|
-
* `workspaces.active` is set, its
|
|
266
|
+
* `workspaces.active` is set, its
|
|
267
|
+
* {@link import('@orkestrel/workspace').WorkspaceInterface.files} are filtered by
|
|
256
268
|
* `scope.files` (a three-way allow-list; `undefined` ⇒ all active files), then split by
|
|
257
|
-
* carrier: TEXT files ({@link import('
|
|
269
|
+
* carrier: TEXT files ({@link import('@orkestrel/workspace').isText}) render into a dedicated
|
|
258
270
|
* `## Workspace` section in the system block — each a fenced
|
|
259
271
|
* `` File: <path>\n```<language>\n<text>\n``` `` block — placed just after the instructions
|
|
260
|
-
* section;
|
|
272
|
+
* section; binary files whose MIME starts with `image/` have their base64 `data`
|
|
261
273
|
* attached to the LAST user message (a vision provider reads images off a user turn).
|
|
262
274
|
* ACTIVE-ONLY — never the other registered workspaces; with NO active workspace nothing is
|
|
263
275
|
* rendered for workspaces.
|
|
@@ -303,9 +315,10 @@ export declare interface AgentContextInterface {
|
|
|
303
315
|
* Options for `createAgentContext` — the richer context's configuration.
|
|
304
316
|
*
|
|
305
317
|
* @remarks
|
|
306
|
-
* `system` is the optional system prompt prepended to the turn's input. `
|
|
307
|
-
* `
|
|
308
|
-
*
|
|
318
|
+
* `system` is the optional system prompt prepended to the turn's input. `instructions` /
|
|
319
|
+
* `workspaces` are optional pre-built context managers to reuse (bring your own registry);
|
|
320
|
+
* when one is omitted, the context creates a fresh empty one. `tools` supplies the loop's
|
|
321
|
+
* call-dispatch and provider-advertising registry; it never renders into the prompt. `scope` is the
|
|
309
322
|
* initial active filter applied at `build()` time (and at the loop's tool-advertise step); it
|
|
310
323
|
* defaults to `undefined` — no filtering — and can be changed through the context's `apply`
|
|
311
324
|
* method afterwards. `conversations` is the structural {@link ConversationManagerInterface} the
|
|
@@ -317,7 +330,10 @@ export declare interface AgentContextInterface {
|
|
|
317
330
|
*/
|
|
318
331
|
export declare interface AgentContextOptions {
|
|
319
332
|
readonly system?: string;
|
|
320
|
-
/**
|
|
333
|
+
/**
|
|
334
|
+
* The loop's pre-built tool registry for provider advertising and call dispatch; an empty one is
|
|
335
|
+
* created when omitted. Tools never render into `build()`'s prompt.
|
|
336
|
+
*/
|
|
321
337
|
readonly tools?: ToolManagerInterface;
|
|
322
338
|
/** A pre-built instruction registry to reuse; an empty one is created when omitted. */
|
|
323
339
|
readonly instructions?: InstructionManagerInterface;
|
|
@@ -833,6 +849,32 @@ export declare interface AgentResult {
|
|
|
833
849
|
readonly partial: boolean;
|
|
834
850
|
}
|
|
835
851
|
|
|
852
|
+
/**
|
|
853
|
+
* Project an unknown value onto the canonical JSON representation of an
|
|
854
|
+
* {@link AgentResult}.
|
|
855
|
+
*
|
|
856
|
+
* @remarks
|
|
857
|
+
* This is a total hostile-boundary projection. Each structural field is captured once
|
|
858
|
+
* through Contract's sanctioned exception boundary, so conforming accessors and inherited
|
|
859
|
+
* properties are supported while a throwing getter or revoked proxy returns `undefined`.
|
|
860
|
+
* Present usage counts must be finite numbers; negative and fractional values are preserved,
|
|
861
|
+
* not normalized. Extra input properties are dropped while a fresh exact plain object is rebuilt
|
|
862
|
+
* and deep-gated through
|
|
863
|
+
* {@link import('@orkestrel/contract').parseJSONValue}.
|
|
864
|
+
*
|
|
865
|
+
* @param value - The unknown value to project
|
|
866
|
+
* @returns A fresh JSON value containing only AgentResult fields, or `undefined` when invalid
|
|
867
|
+
*
|
|
868
|
+
* @example
|
|
869
|
+
* ```ts
|
|
870
|
+
* import { agentResultToJSON } from '@orkestrel/agent'
|
|
871
|
+
*
|
|
872
|
+
* agentResultToJSON({ content: 'done', usage: { prompt: 2, completion: 1, total: 3 }, partial: false })
|
|
873
|
+
* // { content: 'done', usage: { prompt: 2, completion: 1, total: 3 }, partial: false }
|
|
874
|
+
* ```
|
|
875
|
+
*/
|
|
876
|
+
export declare function agentResultToJSON(value: unknown): JSONValue | undefined;
|
|
877
|
+
|
|
836
878
|
/**
|
|
837
879
|
* Options for `createAgentRunner` — the registry that rehydrates jobs, the partial-result
|
|
838
880
|
* policy, and the substrate knobs threaded into the backing `createRunner`.
|
|
@@ -943,8 +985,8 @@ export declare type AgentStreamInterface = StreamInterface<AgentChunk, AgentResu
|
|
|
943
985
|
* (an ALLOWLIST — only matched rules that allow get through), pass an `allowed: false`
|
|
944
986
|
* `fallback`.
|
|
945
987
|
* - **Consulted before each tool call.** The agent loop calls `evaluate({ call })` for
|
|
946
|
-
* every {@link import('
|
|
947
|
-
* back to the model as a denial {@link import('
|
|
988
|
+
* every {@link import('@orkestrel/tool').ToolCall} the model emits; a denied call is fed
|
|
989
|
+
* back to the model as a denial {@link import('@orkestrel/tool').ToolResult} (a `tool`
|
|
948
990
|
* chunk + a tool message) instead of being executed — no tool run, no budget cost —
|
|
949
991
|
* so the model sees the denial and can react.
|
|
950
992
|
* - **Synchronous now.** The async human-approval handshake (request / grant / deny) is
|
|
@@ -1049,37 +1091,6 @@ export declare interface AuthorityRule {
|
|
|
1049
1091
|
readonly reason?: string;
|
|
1050
1092
|
}
|
|
1051
1093
|
|
|
1052
|
-
/**
|
|
1053
|
-
* The binary MIME types a {@link FileContent} binary arm carries — the labels for a
|
|
1054
|
-
* base64-encoded payload.
|
|
1055
|
-
*
|
|
1056
|
-
* @remarks
|
|
1057
|
-
* Initialized to the four image MIMEs a vision-capable provider accepts; the union is OPEN
|
|
1058
|
-
* by design — a future binary MIME (e.g. `'application/pdf'`) slots in purely additively (a
|
|
1059
|
-
* new member), with nothing above it changed. {@link import('./helpers.js').isImage}
|
|
1060
|
-
* narrows a binary arm to an image by the `image/` prefix, so an image is just a binary with
|
|
1061
|
-
* an image MIME.
|
|
1062
|
-
*/
|
|
1063
|
-
export declare type BinaryMIME = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';
|
|
1064
|
-
|
|
1065
|
-
/**
|
|
1066
|
-
* Project a {@link ToolResult} into the MCP `CallToolResult` shape — a top-level `error`
|
|
1067
|
-
* maps to a single `isError: true` text block (the failure reason), otherwise the `value`
|
|
1068
|
-
* is JSON-stringified into a single text block with no `isError`.
|
|
1069
|
-
*
|
|
1070
|
-
* @param result - The {@link ToolResult} to project (as returned by {@link import('./tools/ToolManager.js').ToolManager.execute})
|
|
1071
|
-
* @returns The equivalent {@link ToolCallResult}
|
|
1072
|
-
*
|
|
1073
|
-
* @example
|
|
1074
|
-
* ```ts
|
|
1075
|
-
* buildToolResult({ id: 'c1', name: 'search', error: 'max depth' })
|
|
1076
|
-
* // { content: [{ type: 'text', text: 'max depth' }], isError: true }
|
|
1077
|
-
* buildToolResult({ id: 'c1', name: 'search', value: { count: 1 } })
|
|
1078
|
-
* // { content: [{ type: 'text', text: '{"count":1}' }] }
|
|
1079
|
-
* ```
|
|
1080
|
-
*/
|
|
1081
|
-
export declare function buildToolResult(result: ToolResult): ToolCallResult;
|
|
1082
|
-
|
|
1083
1094
|
/**
|
|
1084
1095
|
* A minimal unbounded async channel — the eager pump WRITES chunks into it (`push`)
|
|
1085
1096
|
* and ends it (`close` / `fail`) regardless of consumption; a consumer READS them back
|
|
@@ -1100,47 +1111,6 @@ export declare class Channel<T> {
|
|
|
1100
1111
|
drain(): AsyncGenerator<T, void>;
|
|
1101
1112
|
}
|
|
1102
1113
|
|
|
1103
|
-
/**
|
|
1104
|
-
* Clamp a 1-based {@link Position} to the bounds of `text` — every component pinned into a
|
|
1105
|
-
* caret that actually exists in the content.
|
|
1106
|
-
*
|
|
1107
|
-
* @remarks
|
|
1108
|
-
* `line` is pinned to `[1, lineCount]` and `column` to `[1, lineLength + 1]` of the
|
|
1109
|
-
* resolved line (column `lineLength + 1` is the caret just past the line's last
|
|
1110
|
-
* character). So a position beyond the end of the text resolves to the end rather than
|
|
1111
|
-
* overflowing. Total — never throws.
|
|
1112
|
-
*
|
|
1113
|
-
* @param text - The text the position addresses
|
|
1114
|
-
* @param position - The 1-based position to clamp
|
|
1115
|
-
* @returns The clamped {@link Position}
|
|
1116
|
-
*
|
|
1117
|
-
* @example
|
|
1118
|
-
* ```ts
|
|
1119
|
-
* clampPosition('ab\ncd', { line: 9, column: 9 }) // { line: 2, column: 3 } (end of 'cd')
|
|
1120
|
-
* ```
|
|
1121
|
-
*/
|
|
1122
|
-
export declare function clampPosition(text: string, position: Position): Position;
|
|
1123
|
-
|
|
1124
|
-
/**
|
|
1125
|
-
* Clamp both ends of a {@link Range} to the bounds of `text` — the actual span a ranged
|
|
1126
|
-
* read / write applies (and the `range` a {@link import('./types.js').ReadResult} reports).
|
|
1127
|
-
*
|
|
1128
|
-
* @remarks
|
|
1129
|
-
* Clamps `start` and `end` independently via {@link clampPosition}, so a range reaching
|
|
1130
|
-
* past the end of the content is trimmed to the content's end. Total — never throws.
|
|
1131
|
-
*
|
|
1132
|
-
* @param text - The text the range addresses
|
|
1133
|
-
* @param range - The 1-based range to clamp
|
|
1134
|
-
* @returns The clamped {@link Range}
|
|
1135
|
-
*
|
|
1136
|
-
* @example
|
|
1137
|
-
* ```ts
|
|
1138
|
-
* clampRange('ab\ncd', { start: { line: 1, column: 1 }, end: { line: 9, column: 9 } })
|
|
1139
|
-
* // { start: { line: 1, column: 1 }, end: { line: 2, column: 3 } }
|
|
1140
|
-
* ```
|
|
1141
|
-
*/
|
|
1142
|
-
export declare function clampRange(text: string, range: Range): Range;
|
|
1143
|
-
|
|
1144
1114
|
/**
|
|
1145
1115
|
* The PER-RUN auto-compaction state threaded through an {@link AgentInterface}'s loop —
|
|
1146
1116
|
* a tiny immutable value replaced within a holder created fresh per run (so no state leaks across runs or a
|
|
@@ -1176,28 +1146,6 @@ export declare interface CompactOptions {
|
|
|
1176
1146
|
readonly sections?: number;
|
|
1177
1147
|
}
|
|
1178
1148
|
|
|
1179
|
-
/**
|
|
1180
|
-
* Compute the byte size of a {@link FileContent} — the `size` a {@link FileInterface} derives
|
|
1181
|
-
* once when built.
|
|
1182
|
-
*
|
|
1183
|
-
* @remarks
|
|
1184
|
-
* Dispatches on {@link isText}: a text arm is its UTF-8 byte length (via `new
|
|
1185
|
-
* TextEncoder().encode(text).length` — the standard Web/Node API, so a multi-byte
|
|
1186
|
-
* character like `'é'` or `'😀'` counts as its real encoded bytes, NOT its character
|
|
1187
|
-
* count); a binary arm is the decoded payload byte length of its base64 `data` (via
|
|
1188
|
-
* {@link decodedSize}, computed arithmetically — no `atob` / `Buffer`). Total — never throws.
|
|
1189
|
-
*
|
|
1190
|
-
* @param content - The file content to size
|
|
1191
|
-
* @returns The byte size (UTF-8 bytes for text; decoded payload bytes for binary)
|
|
1192
|
-
*
|
|
1193
|
-
* @example
|
|
1194
|
-
* ```ts
|
|
1195
|
-
* computeSize({ text: 'café', language: 'text' }) // 5 (é is two bytes)
|
|
1196
|
-
* computeSize({ data: 'AAAA', mime: 'image/png' }) // 3
|
|
1197
|
-
* ```
|
|
1198
|
-
*/
|
|
1199
|
-
export declare function computeSize(content: FileContent): number;
|
|
1200
|
-
|
|
1201
1149
|
/**
|
|
1202
1150
|
* A provider's OPTIONAL context-framing default, keyed by section kind — the framing a
|
|
1203
1151
|
* model prefers (e.g. XML tags vs. Markdown headers), declared by a
|
|
@@ -1408,7 +1356,8 @@ export declare type ConversationEventMap = {
|
|
|
1408
1356
|
* (initial {@link ConversationEventMap} listeners). `snapshot` is
|
|
1409
1357
|
* the construction-time hydration seam — a {@link ConversationSnapshot} whose `id` / `summary` /
|
|
1410
1358
|
* `sections` / live tail are RESTORED into the new conversation (the live `summarize` / `keep` /
|
|
1411
|
-
* `on` re-supplied alongside it), the conversation analogue of
|
|
1359
|
+
* `on` re-supplied alongside it), the conversation analogue of
|
|
1360
|
+
* {@link import('@orkestrel/workspace').WorkspaceOptions}'s `seed` that a
|
|
1412
1361
|
* {@link ConversationManagerInterface.open} reads a stored snapshot back through; hydration is
|
|
1413
1362
|
* silent (no events). When both `snapshot.id` and `id` are given, `snapshot.id` wins (the snapshot
|
|
1414
1363
|
* IS the conversation's identity).
|
|
@@ -1422,7 +1371,7 @@ export declare interface ConversationInput {
|
|
|
1422
1371
|
/** Overrides the manager's default `sections` cap for this conversation. */
|
|
1423
1372
|
readonly sections?: number;
|
|
1424
1373
|
readonly on?: EmitterHooks<ConversationEventMap>;
|
|
1425
|
-
/** A {@link ConversationSnapshot} to hydrate
|
|
1374
|
+
/** A {@link ConversationSnapshot} to hydrate from, analogous to the workspace package's seed input. */
|
|
1426
1375
|
readonly snapshot?: ConversationSnapshot;
|
|
1427
1376
|
}
|
|
1428
1377
|
|
|
@@ -1598,8 +1547,9 @@ export declare interface ConversationInterface {
|
|
|
1598
1547
|
*
|
|
1599
1548
|
* @remarks
|
|
1600
1549
|
* The container serializes ITSELF (`{ id, summary, sections, messages: this.messages() }`) — the
|
|
1601
|
-
* {@link ConversationStoreInterface} persistence seam's payload, the
|
|
1602
|
-
* {@link WorkspaceInterface
|
|
1550
|
+
* {@link ConversationStoreInterface} persistence seam's payload, the exact analogue of
|
|
1551
|
+
* {@link import('@orkestrel/workspace').WorkspaceInterface}'s `snapshot`. The summarizer /
|
|
1552
|
+
* `keep` are NOT serialized — they are live
|
|
1603
1553
|
* CONFIG re-supplied on hydrate (a `ConversationSummarizer` is a function, not data). The snapshot
|
|
1604
1554
|
* is the durable analogue of the constructor `seed`: a {@link ConversationManagerInterface}
|
|
1605
1555
|
* HYDRATES a conversation from it through that seam (see {@link ConversationManagerInterface.open}).
|
|
@@ -1615,7 +1565,7 @@ export declare interface ConversationInterface {
|
|
|
1615
1565
|
* The registry of {@link Conversation}s keyed by `id`, in insertion order, WITH an active pointer
|
|
1616
1566
|
* — the §9 store over the conversation layer PLUS the `active` / `switch` seam the
|
|
1617
1567
|
* {@link import('../AgentContext.js').AgentContext} renders. Event-free (a registry, like
|
|
1618
|
-
* {@link import('
|
|
1568
|
+
* {@link import('@orkestrel/workspace').WorkspaceManager}); the observability lives
|
|
1619
1569
|
* on each {@link Conversation}.
|
|
1620
1570
|
*
|
|
1621
1571
|
* @remarks
|
|
@@ -1665,7 +1615,7 @@ export declare class ConversationManager implements ConversationManagerInterface
|
|
|
1665
1615
|
* A registry of {@link ConversationInterface}s keyed by their `id`, in insertion order, WITH an
|
|
1666
1616
|
* active pointer — the §9 store over the conversation layer PLUS the `active` / `switch` seam the
|
|
1667
1617
|
* {@link AgentContextInterface} renders. Event-free (a registry, like
|
|
1668
|
-
* {@link WorkspaceManagerInterface}); the observability lives on each
|
|
1618
|
+
* {@link import('@orkestrel/workspace').WorkspaceManagerInterface}); the observability lives on each
|
|
1669
1619
|
* {@link ConversationInterface}.
|
|
1670
1620
|
*
|
|
1671
1621
|
* @remarks
|
|
@@ -1688,8 +1638,8 @@ export declare class ConversationManager implements ConversationManagerInterface
|
|
|
1688
1638
|
* miss (rebuilding it through the constructor `seed` from the snapshot, flowing the manager's
|
|
1689
1639
|
* default `summarize` / `keep` in) and `save(id)` PERSISTS a registered conversation's
|
|
1690
1640
|
* {@link ConversationInterface.snapshot}. Both are LENIENT without a store — `open` resolves only
|
|
1691
|
-
* registered ids, `save` is a no-op (`false`) — consistent with the lenient `switch`.
|
|
1692
|
-
*
|
|
1641
|
+
* registered ids, `save` is a no-op (`false`) — consistent with the lenient `switch`. It mirrors
|
|
1642
|
+
* the workspace package manager's `open` / `save` seam.
|
|
1693
1643
|
* - **Event-free.** A purely registry store — no Emitter, no events (each conversation owns
|
|
1694
1644
|
* its own).
|
|
1695
1645
|
*/
|
|
@@ -1760,8 +1710,8 @@ export declare interface ConversationManagerOptions {
|
|
|
1760
1710
|
* {@link ConversationManagerInterface.open} / {@link ConversationManagerInterface.save} — a memory
|
|
1761
1711
|
* / JSON / SQLite / IndexedDB store a conversation is HYDRATED from (`open` a registry-miss) and
|
|
1762
1712
|
* PERSISTED to (`save`). Omitted ⇒ the manager is registry-only: `open` resolves only what is
|
|
1763
|
-
* already registered, and `save` is a no-op (`false`). The
|
|
1764
|
-
* {@link WorkspaceManagerOptions
|
|
1713
|
+
* already registered, and `save` is a no-op (`false`). The exact analogue of
|
|
1714
|
+
* {@link import('@orkestrel/workspace').WorkspaceManagerOptions}'s `store`.
|
|
1765
1715
|
*/
|
|
1766
1716
|
readonly store?: ConversationStoreInterface;
|
|
1767
1717
|
}
|
|
@@ -1827,7 +1777,8 @@ export declare interface ConversationReferenceOptions {
|
|
|
1827
1777
|
/**
|
|
1828
1778
|
* A JSON-serializable snapshot of a conversation's state — its `id`, the rollup `summary`, the
|
|
1829
1779
|
* compacted `sections`, and the live tail `messages` — the durable payload the
|
|
1830
|
-
* {@link ConversationStoreInterface} persists. The
|
|
1780
|
+
* {@link ConversationStoreInterface} persists. The exact analogue of
|
|
1781
|
+
* {@link import('@orkestrel/workspace').WorkspaceSnapshot}.
|
|
1831
1782
|
*
|
|
1832
1783
|
* @remarks
|
|
1833
1784
|
* Pure JSON DATA (no class instances, no functions): each {@link SectionInterface} and
|
|
@@ -1856,12 +1807,13 @@ export declare interface ConversationSnapshot {
|
|
|
1856
1807
|
* One row of the table a
|
|
1857
1808
|
* {@link import('./conversations/stores/DatabaseConversationStore.js').DatabaseConversationStore}
|
|
1858
1809
|
* persists — a conversation `id` plus its {@link ConversationSnapshot} held as ONE OPAQUE JSON
|
|
1859
|
-
* column. The
|
|
1810
|
+
* column. The exact analogue of {@link import('@orkestrel/workspace').WorkspaceSnapshotRow}.
|
|
1860
1811
|
*
|
|
1861
1812
|
* @remarks
|
|
1862
1813
|
* The Database twin of {@link ConversationStoreInterface} stores the snapshot whole (the `snapshot`
|
|
1863
|
-
* column is a `rawShape`, an opaque JSON blob — exactly as
|
|
1864
|
-
* workspace snapshot), so the
|
|
1814
|
+
* column is a `rawShape`, an opaque JSON blob — exactly as
|
|
1815
|
+
* {@link import('@orkestrel/workspace').WorkspaceSnapshotRow} stores a workspace snapshot), so the
|
|
1816
|
+
* row type stays FLAT and the sections/messages snapshot shape never
|
|
1865
1817
|
* forces the contract to `Infer` it. The column therefore reads back as the broad `unknown`; the
|
|
1866
1818
|
* store narrows it to a {@link ConversationSnapshot} on `get`
|
|
1867
1819
|
* ({@link import('./helpers.js').isConversationSnapshot}, the AGENTS §14 boundary narrow). `id`
|
|
@@ -1876,8 +1828,8 @@ export declare interface ConversationSnapshotRow {
|
|
|
1876
1828
|
|
|
1877
1829
|
/**
|
|
1878
1830
|
* The durable persistence seam for a {@link ConversationSnapshot} — three async primitives
|
|
1879
|
-
* (`get` / `set` / `delete`) keyed by a conversation id, the
|
|
1880
|
-
* {@link WorkspaceStoreInterface}.
|
|
1831
|
+
* (`get` / `set` / `delete`) keyed by a conversation id, the exact analogue of
|
|
1832
|
+
* {@link import('@orkestrel/workspace').WorkspaceStoreInterface}.
|
|
1881
1833
|
*
|
|
1882
1834
|
* @remarks
|
|
1883
1835
|
* The store persists the {@link ConversationSnapshot} — the self-contained, pure-JSON conversation
|
|
@@ -1893,7 +1845,9 @@ export declare interface ConversationSnapshotRow {
|
|
|
1893
1845
|
*
|
|
1894
1846
|
* Every primitive is async (a `Promise`), so a durable backend (a database round-trip) fits the
|
|
1895
1847
|
* same shape as the memory one. The snapshot carries its OWN id, so `set` takes no separate id
|
|
1896
|
-
* param (mirroring
|
|
1848
|
+
* param (mirroring
|
|
1849
|
+
* {@link import('@orkestrel/workspace').WorkspaceStoreInterface}'s `set`). UNLIKE a session store
|
|
1850
|
+
* there is NO idle-TTL
|
|
1897
1851
|
* / eviction — a persisted conversation lives until an explicit `delete`. It is concrete over
|
|
1898
1852
|
* {@link ConversationSnapshot} — no generic parameter (AGENTS §21 minimal-interface), since the
|
|
1899
1853
|
* snapshot is the ONE payload a conversation store persists.
|
|
@@ -1908,7 +1862,7 @@ export declare interface ConversationStoreInterface {
|
|
|
1908
1862
|
get(id: string): Promise<ConversationSnapshot | undefined>;
|
|
1909
1863
|
/**
|
|
1910
1864
|
* Insert or replace a snapshot under its own `snapshot.id` (no separate id param —
|
|
1911
|
-
* mirroring {@link WorkspaceStoreInterface
|
|
1865
|
+
* mirroring {@link import('@orkestrel/workspace').WorkspaceStoreInterface}'s `set`).
|
|
1912
1866
|
*
|
|
1913
1867
|
* @param snapshot - The snapshot to store (keyed by its `id`)
|
|
1914
1868
|
*/
|
|
@@ -1939,28 +1893,6 @@ export declare interface ConversationStoreInterface {
|
|
|
1939
1893
|
*/
|
|
1940
1894
|
export declare type ConversationSummarizer = (messages: readonly MessageInterface[]) => Promise<string>;
|
|
1941
1895
|
|
|
1942
|
-
/**
|
|
1943
|
-
* Count the lines of a {@link FileContent} — the `lines` a {@link FileInterface} derives once
|
|
1944
|
-
* when built.
|
|
1945
|
-
*
|
|
1946
|
-
* @remarks
|
|
1947
|
-
* A text arm's line count is `0` for the empty string, otherwise one more than the
|
|
1948
|
-
* number of newline (`\n`) separators it contains — so `'a'` is one line, `'a\nb'` is two,
|
|
1949
|
-
* and a trailing newline `'a\n'` counts the empty final line as two. A binary arm has no
|
|
1950
|
-
* lines and returns `0`. Total — never throws.
|
|
1951
|
-
*
|
|
1952
|
-
* @param content - The file content to count lines for
|
|
1953
|
-
* @returns The line count (text line count; `0` for a binary arm or empty text)
|
|
1954
|
-
*
|
|
1955
|
-
* @example
|
|
1956
|
-
* ```ts
|
|
1957
|
-
* countLines({ text: '', language: 'text' }) // 0
|
|
1958
|
-
* countLines({ text: 'a\nb\nc', language: 'text' }) // 3
|
|
1959
|
-
* countLines({ data: 'AAAA', mime: 'image/png' }) // 0
|
|
1960
|
-
* ```
|
|
1961
|
-
*/
|
|
1962
|
-
export declare function countLines(content: FileContent): number;
|
|
1963
|
-
|
|
1964
1896
|
/**
|
|
1965
1897
|
* Create an agent loop — an {@link AgentInterface} composing a
|
|
1966
1898
|
* {@link ProviderInterface}, its {@link AgentContextInterface}, and a tool registry
|
|
@@ -2095,8 +2027,9 @@ export declare function createAgentQueue(options: AgentQueueOptions): QueueInter
|
|
|
2095
2027
|
*
|
|
2096
2028
|
* @example
|
|
2097
2029
|
* ```ts
|
|
2030
|
+
* import { createAgentRegistry } from '@src/core'
|
|
2098
2031
|
* import type { ProviderInterface } from '@src/core'
|
|
2099
|
-
* import {
|
|
2032
|
+
* import { createTool } from '@orkestrel/tool'
|
|
2100
2033
|
*
|
|
2101
2034
|
* declare const provider: ProviderInterface // any concrete implementation supplied by the host app
|
|
2102
2035
|
* const registry = createAgentRegistry({
|
|
@@ -2177,24 +2110,6 @@ export declare function createAgentRunner(options: AgentRunnerOptions): RunnerIn
|
|
|
2177
2110
|
*/
|
|
2178
2111
|
export declare function createAuthority(options?: AuthorityOptions): AuthorityInterface;
|
|
2179
2112
|
|
|
2180
|
-
/**
|
|
2181
|
-
* Build the BINARY {@link FileContent} arm — the §4.2.3 split constructor for binary (a
|
|
2182
|
-
* separate function per arm, not one constructor dispatching on a discriminator parameter).
|
|
2183
|
-
* An image is just a binary with an image {@link BinaryMIME}.
|
|
2184
|
-
*
|
|
2185
|
-
* @param data - The base64-encoded binary payload
|
|
2186
|
-
* @param mime - The {@link BinaryMIME} that labels the payload
|
|
2187
|
-
* @returns A `{ data; mime }` content arm
|
|
2188
|
-
*
|
|
2189
|
-
* @example
|
|
2190
|
-
* ```ts
|
|
2191
|
-
* import { createBinaryContent } from '@src/core'
|
|
2192
|
-
*
|
|
2193
|
-
* createBinaryContent('<base64>', 'image/png') // { data: '<base64>', mime: 'image/png' }
|
|
2194
|
-
* ```
|
|
2195
|
-
*/
|
|
2196
|
-
export declare function createBinaryContent(data: string, mime: BinaryMIME): FileContent;
|
|
2197
|
-
|
|
2198
2113
|
/**
|
|
2199
2114
|
* Create a conversation — a {@link ConversationInterface} grouping messages above a flat
|
|
2200
2115
|
* message store it OWNS DIRECTLY, with compaction into summarized sections, a regenerated
|
|
@@ -2266,12 +2181,14 @@ export declare function createConversationManager(options?: ConversationManagerO
|
|
|
2266
2181
|
/**
|
|
2267
2182
|
* Create a {@link DatabaseConversationStore} over any {@link DriverInterface} — the durable,
|
|
2268
2183
|
* driver-pluggable backing for the conversation persistence seam, the opt-in twin of
|
|
2269
|
-
* {@link createMemoryConversationStore}. The
|
|
2184
|
+
* {@link createMemoryConversationStore}. The exact twin of
|
|
2185
|
+
* {@link import('@orkestrel/workspace').createDatabaseWorkspaceStore}.
|
|
2270
2186
|
*
|
|
2271
2187
|
* @remarks
|
|
2272
2188
|
* Builds a one-table database (`conversations`, keyed by `id`) over the supplied driver, the snapshot
|
|
2273
2189
|
* held as ONE OPAQUE JSON COLUMN — the column map is `{ id; snapshot }` where `snapshot` is a
|
|
2274
|
-
* `rawShape` (a JSON blob), exactly as
|
|
2190
|
+
* `rawShape` (a JSON blob), exactly as
|
|
2191
|
+
* {@link import('@orkestrel/workspace').createDatabaseWorkspaceStore} stores its snapshot. The
|
|
2275
2192
|
* snapshot is already a COMPLETE, self-contained, pure-JSON payload, so storing it whole is lossless
|
|
2276
2193
|
* AND keeps the row type FLAT (the column reads back as `unknown`, narrowed on `get` by
|
|
2277
2194
|
* {@link import('./helpers.js').isConversationSnapshot}). The `driver` DEFAULTS to
|
|
@@ -2296,65 +2213,6 @@ export declare function createConversationManager(options?: ConversationManagerO
|
|
|
2296
2213
|
*/
|
|
2297
2214
|
export declare function createDatabaseConversationStore(driver?: DriverInterface): ConversationStoreInterface;
|
|
2298
2215
|
|
|
2299
|
-
/**
|
|
2300
|
-
* Create a {@link DatabaseWorkspaceStore} over any {@link DriverInterface} — the durable,
|
|
2301
|
-
* driver-pluggable backing for the workspace persistence seam, the opt-in twin of
|
|
2302
|
-
* {@link createMemoryWorkspaceStore}.
|
|
2303
|
-
*
|
|
2304
|
-
* @remarks
|
|
2305
|
-
* Builds a one-table database (`workspaces`, keyed by `id`) over the supplied driver, the snapshot
|
|
2306
|
-
* held as ONE OPAQUE JSON COLUMN — the column map is `{ id; snapshot }` where `snapshot` is a
|
|
2307
|
-
* `rawShape` (a JSON blob), exactly as
|
|
2308
|
-
* the analogous `createDatabaseWorkflowStore` in `@orkestrel/workflow` stores its snapshot. The
|
|
2309
|
-
* snapshot is already a COMPLETE, self-contained, pure-JSON payload, so storing it whole is lossless
|
|
2310
|
-
* AND keeps the row type FLAT (the column reads back as `unknown`, narrowed on `get` by
|
|
2311
|
-
* {@link import('./helpers.js').isWorkspaceSnapshot}). The `driver` DEFAULTS to
|
|
2312
|
-
* {@link createMemoryDriver}, so the store ALSO works in memory out of the box; pass a server
|
|
2313
|
-
* `createJSONDriver` / `createSQLiteDriver` (or a browser IndexedDB driver) for a persistent one —
|
|
2314
|
-
* the durability is the driver's job, the store engine is shared. It swaps in behind
|
|
2315
|
-
* {@link WorkspaceStoreInterface} WITHOUT touching the manager or the workspace.
|
|
2316
|
-
*
|
|
2317
|
-
* @param driver - The storage backend the snapshots persist to (defaults to {@link createMemoryDriver})
|
|
2318
|
-
* @returns A {@link WorkspaceStoreInterface} over the driver
|
|
2319
|
-
*
|
|
2320
|
-
* @example
|
|
2321
|
-
* ```ts
|
|
2322
|
-
* import { createDatabaseWorkspaceStore, createMemoryDriver, createWorkspaceManager } from '@src/core'
|
|
2323
|
-
*
|
|
2324
|
-
* const store = createDatabaseWorkspaceStore(createMemoryDriver()) // a durable driver swaps in here
|
|
2325
|
-
* const manager = createWorkspaceManager({ store })
|
|
2326
|
-
* const workspace = manager.add()
|
|
2327
|
-
* workspace.write('notes.txt', 'hello')
|
|
2328
|
-
* await manager.save(workspace.id) // persist the workspace (one JSON column)
|
|
2329
|
-
* ```
|
|
2330
|
-
*/
|
|
2331
|
-
export declare function createDatabaseWorkspaceStore(driver?: DriverInterface): WorkspaceStoreInterface;
|
|
2332
|
-
|
|
2333
|
-
/**
|
|
2334
|
-
* Create a file — an immutable {@link FileInterface} from its `path` + {@link FileContent}
|
|
2335
|
-
* and optional {@link import('./types.js').FileState}, with `size` / `lines` DERIVED from the
|
|
2336
|
-
* content.
|
|
2337
|
-
*
|
|
2338
|
-
* @remarks
|
|
2339
|
-
* Returns a PLAIN `Object.freeze`d record (NOT a class instance) — the `path` IS its identity
|
|
2340
|
-
* (there is no `id`). Only `path` / `content` are required; `state` defaults to `'created'`
|
|
2341
|
-
* when omitted. `size` (via {@link computeSize}) and `lines` (via {@link countLines}) are
|
|
2342
|
-
* computed from the content here (so they never drift from it). Frozen + plain, so it
|
|
2343
|
-
* `structuredClone`s losslessly and is never mutated after creation.
|
|
2344
|
-
*
|
|
2345
|
-
* @param input - `path` / `content` (required) and an optional `state` (see {@link FileInput})
|
|
2346
|
-
* @returns A frozen {@link FileInterface} record
|
|
2347
|
-
*
|
|
2348
|
-
* @example
|
|
2349
|
-
* ```ts
|
|
2350
|
-
* import { createFile, createTextContent } from '@src/core'
|
|
2351
|
-
*
|
|
2352
|
-
* const file = createFile({ path: 'src/main.ts', content: createTextContent('const x = 1', 'typescript') })
|
|
2353
|
-
* file.lines // 1
|
|
2354
|
-
* ```
|
|
2355
|
-
*/
|
|
2356
|
-
export declare function createFile(input: FileInput): FileInterface;
|
|
2357
|
-
|
|
2358
2216
|
/**
|
|
2359
2217
|
* Create an instruction — an immutable {@link InstructionInterface} (a named directive)
|
|
2360
2218
|
* from its `name` / `content` and optional `priority`, the `id` minted at construction.
|
|
@@ -2411,11 +2269,13 @@ export declare function createInstructionManager(options?: InstructionManagerOpt
|
|
|
2411
2269
|
* Create the in-memory conversation store — a {@link ConversationStoreInterface} backed by a
|
|
2412
2270
|
* process-lifetime `Map` of {@link import('./types.js').ConversationSnapshot}s keyed by conversation
|
|
2413
2271
|
* id, the DEFAULT backing for the durable {@link ConversationManagerInterface.open} /
|
|
2414
|
-
* {@link ConversationManagerInterface.save} seam. The
|
|
2272
|
+
* {@link ConversationManagerInterface.save} seam. The exact twin of
|
|
2273
|
+
* {@link import('@orkestrel/workspace').createMemoryWorkspaceStore}.
|
|
2415
2274
|
*
|
|
2416
2275
|
* @remarks
|
|
2417
2276
|
* A plain `Map` (the snapshot is already pure JSON, so no encoding is needed for the memory tier),
|
|
2418
|
-
* the structural twin of {@link createMemoryWorkspaceStore}.
|
|
2277
|
+
* the structural twin of {@link import('@orkestrel/workspace').createMemoryWorkspaceStore}.
|
|
2278
|
+
* `get` / `set` / `delete` are async (the
|
|
2419
2279
|
* same shape a durable backend fits); UNLIKE a session store there is NO idle-TTL / eviction — a
|
|
2420
2280
|
* persisted conversation lives until an explicit `delete`. Its driver-pluggable twin is
|
|
2421
2281
|
* {@link createDatabaseConversationStore} (the snapshot as one opaque JSON column over a `databases`
|
|
@@ -2439,37 +2299,6 @@ export declare function createInstructionManager(options?: InstructionManagerOpt
|
|
|
2439
2299
|
*/
|
|
2440
2300
|
export declare function createMemoryConversationStore(): ConversationStoreInterface;
|
|
2441
2301
|
|
|
2442
|
-
/**
|
|
2443
|
-
* Create the in-memory workspace store — a {@link WorkspaceStoreInterface} backed by a
|
|
2444
|
-
* process-lifetime `Map` of {@link import('./types.js').WorkspaceSnapshot}s keyed by workspace id,
|
|
2445
|
-
* the DEFAULT backing for the durable {@link WorkspaceManagerInterface.open} /
|
|
2446
|
-
* {@link WorkspaceManagerInterface.save} seam.
|
|
2447
|
-
*
|
|
2448
|
-
* @remarks
|
|
2449
|
-
* A plain `Map` (the snapshot is already pure JSON, so no encoding is needed for the memory tier),
|
|
2450
|
-
* the structural twin of the analogous `createMemoryWorkflowStore` in `@orkestrel/workflow`.
|
|
2451
|
-
* `get` / `set` / `delete` are async (the same shape a durable backend fits); UNLIKE a session
|
|
2452
|
-
* store there is NO idle-TTL / eviction — a persisted workspace lives until an explicit `delete`.
|
|
2453
|
-
* Its driver-pluggable twin is {@link createDatabaseWorkspaceStore} (the snapshot as one opaque
|
|
2454
|
-
* JSON column over a `databases` table) — for a DURABLE store pass it a JSON / SQLite / IndexedDB
|
|
2455
|
-
* driver, and it swaps in WITHOUT touching the manager or the workspace. Hydration stays a manager
|
|
2456
|
-
* concern: read a snapshot back and rebuild the live workspace through the constructor `seed`.
|
|
2457
|
-
*
|
|
2458
|
-
* @returns A memory-backed {@link WorkspaceStoreInterface}
|
|
2459
|
-
*
|
|
2460
|
-
* @example
|
|
2461
|
-
* ```ts
|
|
2462
|
-
* import { createMemoryWorkspaceStore, createWorkspaceManager } from '@src/core'
|
|
2463
|
-
*
|
|
2464
|
-
* const store = createMemoryWorkspaceStore()
|
|
2465
|
-
* const manager = createWorkspaceManager({ store })
|
|
2466
|
-
* const workspace = manager.add()
|
|
2467
|
-
* workspace.write('notes.txt', 'hello')
|
|
2468
|
-
* await manager.save(workspace.id) // persist the workspace
|
|
2469
|
-
* ```
|
|
2470
|
-
*/
|
|
2471
|
-
export declare function createMemoryWorkspaceStore(): WorkspaceStoreInterface;
|
|
2472
|
-
|
|
2473
2302
|
/**
|
|
2474
2303
|
* Create a named scope — an immutable {@link ScopeInterface} from its `name` and the four
|
|
2475
2304
|
* optional per-category allow-lists, the `id` minted at construction.
|
|
@@ -2519,23 +2348,6 @@ export declare function createScope(input: ScopeInput): ScopeInterface;
|
|
|
2519
2348
|
*/
|
|
2520
2349
|
export declare function createScopeManager(options?: ScopeManagerOptions): ScopeManagerInterface;
|
|
2521
2350
|
|
|
2522
|
-
/**
|
|
2523
|
-
* Build the TEXT {@link FileContent} arm — the §4.2.3 split constructor for text (a separate
|
|
2524
|
-
* function per arm, not one constructor dispatching on a discriminator parameter).
|
|
2525
|
-
*
|
|
2526
|
-
* @param text - The literal text body
|
|
2527
|
-
* @param language - The fenced-code language the text renders as (e.g. `'typescript'`)
|
|
2528
|
-
* @returns A `{ text; language }` content arm
|
|
2529
|
-
*
|
|
2530
|
-
* @example
|
|
2531
|
-
* ```ts
|
|
2532
|
-
* import { createTextContent } from '@src/core'
|
|
2533
|
-
*
|
|
2534
|
-
* createTextContent('const x = 1', 'typescript') // { text: 'const x = 1', language: 'typescript' }
|
|
2535
|
-
* ```
|
|
2536
|
-
*/
|
|
2537
|
-
export declare function createTextContent(text: string, language: string): FileContent;
|
|
2538
|
-
|
|
2539
2351
|
/**
|
|
2540
2352
|
* Create a stream-stateful `<think>` separator — a {@link ThinkSplitterInterface} that
|
|
2541
2353
|
* splits a thinking model's in-content `<think>…</think>` reasoning spans away from
|
|
@@ -2565,122 +2377,12 @@ export declare function createTextContent(text: string, language: string): FileC
|
|
|
2565
2377
|
*/
|
|
2566
2378
|
export declare function createThinkSplitter(): ThinkSplitterInterface;
|
|
2567
2379
|
|
|
2568
|
-
/**
|
|
2569
|
-
* Create a tool — a {@link ToolInterface} binding a {@link ToolDefinition} schema
|
|
2570
|
-
* (the `name` / `description` / `parameters` the model sees) to the `execute` handler
|
|
2571
|
-
* that runs a call.
|
|
2572
|
-
*
|
|
2573
|
-
* @remarks
|
|
2574
|
-
* Only `name` is required (it keys the tool in a {@link ToolManagerInterface} and is
|
|
2575
|
-
* what the model calls); `description` / `parameters` are the optional JSON-Schema the
|
|
2576
|
-
* provider advertises (forwarded verbatim). The handler's `args` is the model-supplied
|
|
2577
|
-
* `unknown` arguments record — narrow it inside (§14); a `createToolManager` registry
|
|
2578
|
-
* isolates a throw into a `ToolResult.error`.
|
|
2579
|
-
*
|
|
2580
|
-
* @param options - `name` (required), optional `description` / `parameters`, and the
|
|
2581
|
-
* `execute` handler (see {@link ToolOptions})
|
|
2582
|
-
* @returns A working {@link ToolInterface}
|
|
2583
|
-
*
|
|
2584
|
-
* @example
|
|
2585
|
-
* ```ts
|
|
2586
|
-
* import { createTool } from '@src/core'
|
|
2587
|
-
*
|
|
2588
|
-
* const add = createTool({
|
|
2589
|
-
* name: 'add',
|
|
2590
|
-
* description: 'Add two numbers',
|
|
2591
|
-
* execute: (args) => Number(args.a) + Number(args.b),
|
|
2592
|
-
* })
|
|
2593
|
-
* ```
|
|
2594
|
-
*/
|
|
2595
|
-
export declare function createTool(options: ToolOptions): ToolInterface;
|
|
2596
|
-
|
|
2597
|
-
/**
|
|
2598
|
-
* Create a tool registry — a {@link ToolManagerInterface} that resolves tool names,
|
|
2599
|
-
* lists {@link ToolDefinition}s for the provider, and executes calls with per-call
|
|
2600
|
-
* error isolation.
|
|
2601
|
-
*
|
|
2602
|
-
* @remarks
|
|
2603
|
-
* Starts empty; `add` registers one tool or a batch (§9.2), `definitions()` yields the
|
|
2604
|
-
* schemas to hand a provider, and `execute` runs a {@link ToolCall} (or a batch),
|
|
2605
|
-
* ALWAYS resolving a {@link ToolResult} — a handler throw becomes an `error` result and
|
|
2606
|
-
* an unknown name a not-found `error`, so a tool throw never escapes and a batch never
|
|
2607
|
-
* fails as a whole.
|
|
2608
|
-
*
|
|
2609
|
-
* @returns An empty {@link ToolManagerInterface}
|
|
2610
|
-
*
|
|
2611
|
-
* @example
|
|
2612
|
-
* ```ts
|
|
2613
|
-
* import { createTool, createToolManager } from '@src/core'
|
|
2614
|
-
*
|
|
2615
|
-
* const tools = createToolManager()
|
|
2616
|
-
* tools.add(createTool({ name: 'add', execute: (a) => Number(a.x) + Number(a.y) }))
|
|
2617
|
-
* const result = await tools.execute({ id: '1', name: 'add', arguments: { x: 1, y: 2 } })
|
|
2618
|
-
* ```
|
|
2619
|
-
*/
|
|
2620
|
-
export declare function createToolManager(): ToolManagerInterface;
|
|
2621
|
-
|
|
2622
|
-
/**
|
|
2623
|
-
* Create a workspace — a mutable, `path`-keyed working set of immutable
|
|
2624
|
-
* {@link FileInterface}s with the in-memory edit surface (read / write / search / replace /
|
|
2625
|
-
* move / remove), observable through its `EmitterInterface` (from `@orkestrel/emitter`).
|
|
2626
|
-
*
|
|
2627
|
-
* @param options - Optional initial {@link import('./types.js').WorkspaceEventMap} listeners (`on`) and the emitter's `error` handler (see {@link WorkspaceOptions})
|
|
2628
|
-
* @returns A working {@link WorkspaceInterface}
|
|
2629
|
-
*
|
|
2630
|
-
* @example
|
|
2631
|
-
* ```ts
|
|
2632
|
-
* import { createWorkspace } from '@src/core'
|
|
2633
|
-
*
|
|
2634
|
-
* const workspace = createWorkspace({ on: { write: (file) => console.log(file.path) } })
|
|
2635
|
-
* workspace.write('src/main.ts', 'const x = 1')
|
|
2636
|
-
* workspace.file('src/main.ts')?.state // 'created'
|
|
2637
|
-
* ```
|
|
2638
|
-
*/
|
|
2639
|
-
export declare function createWorkspace(options?: WorkspaceOptions): WorkspaceInterface;
|
|
2640
|
-
|
|
2641
|
-
/**
|
|
2642
|
-
* Create a workspace registry — a {@link WorkspaceManagerInterface} holding
|
|
2643
|
-
* {@link WorkspaceInterface}s keyed by their `id` (in insertion order) WITH an active pointer:
|
|
2644
|
-
* the §9 store over the workspace layer plus the `active` / `switch` seam the context renders.
|
|
2645
|
-
*
|
|
2646
|
-
* @remarks
|
|
2647
|
-
* Starts empty; `add(input?)` mints a {@link WorkspaceInterface} (its `id` from the input or a
|
|
2648
|
-
* random UUID), flowing the manager's default `on` / `error` in unless the input overrides them,
|
|
2649
|
-
* and stores it (an already-present `id` overwrites — last write wins) — and AUTO-ACTIVATES the
|
|
2650
|
-
* FIRST one (a registry with workspaces always has one `active`); a later `add` leaves `active`
|
|
2651
|
-
* unchanged. `switch(id)` re-points `active` (an unknown `id` returns `undefined`, leaving
|
|
2652
|
-
* `active` unchanged — lenient, never throws); `workspace(id)` / `workspaces()` look up;
|
|
2653
|
-
* `remove` (one or a batch, §9.2) reports whether any was removed AND clears `active` if it was
|
|
2654
|
-
* the removed one; `clear` empties it and clears `active`. Event-free (each workspace owns its
|
|
2655
|
-
* own observable `emitter`).
|
|
2656
|
-
*
|
|
2657
|
-
* With the optional `store` ({@link WorkspaceStoreInterface}, e.g. `createMemoryWorkspaceStore` /
|
|
2658
|
-
* `createDatabaseWorkspaceStore`), `open(id)` HYDRATES a workspace on a registry miss (rebuilding it
|
|
2659
|
-
* through the constructor `seed` from the snapshot's `files`, then activating it) and `save(id)`
|
|
2660
|
-
* PERSISTS a registered workspace's `snapshot()`. Both are LENIENT without a store (open resolves
|
|
2661
|
-
* only registered ids, save is a no-op `false`).
|
|
2662
|
-
*
|
|
2663
|
-
* @param options - Optional default `on` / `error` for created workspaces + the durable `store`
|
|
2664
|
-
* (see {@link WorkspaceManagerOptions})
|
|
2665
|
-
* @returns An empty {@link WorkspaceManagerInterface}
|
|
2666
|
-
*
|
|
2667
|
-
* @example
|
|
2668
|
-
* ```ts
|
|
2669
|
-
* import { createWorkspaceManager } from '@src/core'
|
|
2670
|
-
*
|
|
2671
|
-
* const workspaces = createWorkspaceManager()
|
|
2672
|
-
* const scratch = workspaces.add() // auto-activates — workspaces.active === scratch
|
|
2673
|
-
* scratch.write('notes.txt', 'hello')
|
|
2674
|
-
* ```
|
|
2675
|
-
*/
|
|
2676
|
-
export declare function createWorkspaceManager(options?: WorkspaceManagerOptions): WorkspaceManagerInterface;
|
|
2677
|
-
|
|
2678
2380
|
/**
|
|
2679
2381
|
* A {@link ConversationStoreInterface} backed by one table of the `databases` layer — a
|
|
2680
2382
|
* conversation's durable state IS a row, so persistence reduces to keyed point-access (`get` / `set`
|
|
2681
2383
|
* / `delete`) over a {@link TableInterface}, the driver-pluggable twin of the plain-`Map`
|
|
2682
2384
|
* {@link import('./MemoryConversationStore.js').MemoryConversationStore}. The EXACT twin of
|
|
2683
|
-
* {@link import('
|
|
2385
|
+
* {@link import('@orkestrel/workspace').DatabaseWorkspaceStore}.
|
|
2684
2386
|
*
|
|
2685
2387
|
* @remarks
|
|
2686
2388
|
* The store is driver-agnostic: it holds a single {@link TableInterface} whose backend (memory,
|
|
@@ -2688,7 +2390,7 @@ export declare function createWorkspaceManager(options?: WorkspaceManagerOptions
|
|
|
2688
2390
|
* IndexedDB backend swaps in WITHOUT touching the
|
|
2689
2391
|
* {@link import('../ConversationManager.js').ConversationManager} or the
|
|
2690
2392
|
* {@link import('../Conversation.js').Conversation} — the same seam as
|
|
2691
|
-
* {@link import('
|
|
2393
|
+
* {@link import('@orkestrel/workspace').DatabaseWorkspaceStore}. The
|
|
2692
2394
|
* driver defaults to memory ({@link import('../../factories.js').createDatabaseConversationStore}
|
|
2693
2395
|
* passes `createMemoryDriver()`), so it ALSO works in memory out of the box; you opt into the
|
|
2694
2396
|
* durable plumbing by passing a JSON / SQLite / IndexedDB driver.
|
|
@@ -2741,96 +2443,6 @@ export declare class DatabaseConversationStore implements ConversationStoreInter
|
|
|
2741
2443
|
delete(id: string): Promise<void>;
|
|
2742
2444
|
}
|
|
2743
2445
|
|
|
2744
|
-
/**
|
|
2745
|
-
* A {@link WorkspaceStoreInterface} backed by one table of the `databases` layer — a workspace's
|
|
2746
|
-
* durable state IS a row, so persistence reduces to keyed point-access (`get` / `set` / `delete`)
|
|
2747
|
-
* over a {@link TableInterface}, the driver-pluggable twin of the plain-`Map`
|
|
2748
|
-
* {@link import('./MemoryWorkspaceStore.js').MemoryWorkspaceStore}.
|
|
2749
|
-
*
|
|
2750
|
-
* @remarks
|
|
2751
|
-
* The store is driver-agnostic: it holds a single {@link TableInterface} whose backend (memory,
|
|
2752
|
-
* JSON, SQLite, IndexedDB) is chosen by whoever builds it (the factories), so a JSON / SQLite /
|
|
2753
|
-
* IndexedDB backend swaps in WITHOUT touching the
|
|
2754
|
-
* {@link import('../WorkspaceManager.js').WorkspaceManager} or the
|
|
2755
|
-
* {@link import('../Workspace.js').Workspace} — the same seam as
|
|
2756
|
-
* the analogous `DatabaseWorkflowStore` in `@orkestrel/workflow`. The
|
|
2757
|
-
* driver defaults to memory ({@link import('../../factories.js').createDatabaseWorkspaceStore}
|
|
2758
|
-
* passes `createMemoryDriver()`), so it ALSO works in memory out of the box; you opt into the
|
|
2759
|
-
* durable plumbing by passing a JSON / SQLite / IndexedDB driver.
|
|
2760
|
-
*
|
|
2761
|
-
* The {@link WorkspaceSnapshot} is stored as ONE OPAQUE JSON COLUMN — the table is a row of
|
|
2762
|
-
* `{ id; snapshot }` ({@link WorkspaceSnapshotRow}), the snapshot the whole JSON blob (a `rawShape`
|
|
2763
|
-
* column the factory builds) — exactly as `DatabaseWorkflowStore` stores its snapshot. The snapshot
|
|
2764
|
-
* is already a COMPLETE, self-contained, pure-JSON payload, so storing it whole is lossless AND
|
|
2765
|
-
* keeps the row type flat (`snapshot` reads back as `unknown`).
|
|
2766
|
-
*
|
|
2767
|
-
* - **`set(snapshot)` upserts under the snapshot's OWN `id`** (no separate id param) — it writes
|
|
2768
|
-
* the row `{ id: snapshot.id, snapshot }`.
|
|
2769
|
-
* - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to
|
|
2770
|
-
* a {@link WorkspaceSnapshot} ({@link import('../../helpers.js').isWorkspaceSnapshot} — the AGENTS
|
|
2771
|
-
* §14 boundary narrow for an untrusted storage read), or `undefined` if none is stored.
|
|
2772
|
-
* - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).
|
|
2773
|
-
*
|
|
2774
|
-
* UNLIKE a session store there is NO idle-TTL / eviction — a persisted workspace lives until an
|
|
2775
|
-
* explicit `delete`. The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the
|
|
2776
|
-
* §22 method bijection with {@link WorkspaceStoreInterface}). Hydration stays a caller concern: a
|
|
2777
|
-
* {@link import('../WorkspaceManager.js').WorkspaceManager} reads a snapshot back and rebuilds the
|
|
2778
|
-
* live workspace through the constructor `seed` (its `open` / `save`).
|
|
2779
|
-
*
|
|
2780
|
-
* @example
|
|
2781
|
-
* ```ts
|
|
2782
|
-
* import { createDatabaseWorkspaceStore, createMemoryDriver, createWorkspace } from '@src/core'
|
|
2783
|
-
*
|
|
2784
|
-
* const store = createDatabaseWorkspaceStore(createMemoryDriver()) // a durable driver swaps in here
|
|
2785
|
-
* const workspace = createWorkspace()
|
|
2786
|
-
* workspace.write('notes.txt', 'hello')
|
|
2787
|
-
* await store.set(workspace.snapshot()) // persist the workspace (one JSON column)
|
|
2788
|
-
* const snapshot = await store.get(workspace.id)
|
|
2789
|
-
* await store.delete(workspace.id) // drop it
|
|
2790
|
-
* ```
|
|
2791
|
-
*/
|
|
2792
|
-
export declare class DatabaseWorkspaceStore implements WorkspaceStoreInterface {
|
|
2793
|
-
#private;
|
|
2794
|
-
/**
|
|
2795
|
-
* Wrap a table as a workspace store.
|
|
2796
|
-
*
|
|
2797
|
-
* @param table - The {@link TableInterface} holding the snapshots — its row is the
|
|
2798
|
-
* {@link WorkspaceSnapshotRow} `{ id; snapshot }` shape (the snapshot one opaque JSON column)
|
|
2799
|
-
*/
|
|
2800
|
-
constructor(table: TableInterface<WorkspaceSnapshotRow>);
|
|
2801
|
-
/** Resolve the persisted snapshot for `id`, narrowing the opaque JSON column back to a `WorkspaceSnapshot`. */
|
|
2802
|
-
get(id: string): Promise<WorkspaceSnapshot | undefined>;
|
|
2803
|
-
/** Insert or replace under the snapshot's OWN `id` (no separate id param) — the row is `{ id, snapshot }`. */
|
|
2804
|
-
set(snapshot: WorkspaceSnapshot): Promise<void>;
|
|
2805
|
-
/** Drop a snapshot by id; an absent id is a no-op (no throw). */
|
|
2806
|
-
delete(id: string): Promise<void>;
|
|
2807
|
-
}
|
|
2808
|
-
|
|
2809
|
-
/**
|
|
2810
|
-
* Compute the decoded byte length of a base64 string ARITHMETICALLY — the image-payload
|
|
2811
|
-
* sizing primitive {@link computeSize} uses, with no `atob` / `Buffer` decode.
|
|
2812
|
-
*
|
|
2813
|
-
* @remarks
|
|
2814
|
-
* A base64 string encodes each group of 3 input bytes as 4 characters, so a well-formed
|
|
2815
|
-
* string's length is a multiple of 4 and its decoded length is `(length / 4) * 3` MINUS
|
|
2816
|
-
* the trailing `=` padding (one `=` ⇒ the last group held 2 bytes, two `==` ⇒ 1 byte).
|
|
2817
|
-
* The padding is counted from the trailing `=` characters, so both the `=` and `==` cases
|
|
2818
|
-
* are handled. The empty string decodes to `0`. Total — never throws (a malformed,
|
|
2819
|
-
* non-multiple-of-4 length still yields a defined non-negative estimate via `floor`).
|
|
2820
|
-
*
|
|
2821
|
-
* @param base64 - The base64-encoded string (e.g. an image's `data`)
|
|
2822
|
-
* @returns The decoded payload's byte length
|
|
2823
|
-
*
|
|
2824
|
-
* @example
|
|
2825
|
-
* ```ts
|
|
2826
|
-
* decodedSize('') // 0
|
|
2827
|
-
* decodedSize('AAAA') // 3 (no padding)
|
|
2828
|
-
* decodedSize('AAA=') // 2 (one '=')
|
|
2829
|
-
* decodedSize('AA==') // 1 (two '=')
|
|
2830
|
-
* ```
|
|
2831
|
-
*/
|
|
2832
|
-
export declare function decodedSize(base64: string): number;
|
|
2833
|
-
|
|
2834
2446
|
/**
|
|
2835
2447
|
* The default cap on an {@link AgentInterface} turn's tool iterations — the maximum
|
|
2836
2448
|
* number of context → provider → tools cycles before the loop stops, so a model that
|
|
@@ -2858,28 +2470,6 @@ export declare const DEFAULT_AUTHORITY_ZONE = "default";
|
|
|
2858
2470
|
*/
|
|
2859
2471
|
export declare const DEFAULT_CONVERSATION_KEEP = 0;
|
|
2860
2472
|
|
|
2861
|
-
/**
|
|
2862
|
-
* Escape a string's regex-special characters so it matches LITERALLY inside a `RegExp` — the
|
|
2863
|
-
* primitive a {@link import('./workspaces/Workspace.js').Workspace} search builds a literal-text
|
|
2864
|
-
* search pattern through (as opposed to a caller-supplied regex pattern).
|
|
2865
|
-
*
|
|
2866
|
-
* @remarks
|
|
2867
|
-
* Prefixes every character in the class `. * + ? ^ $ { } ( ) | [ ] \` with a backslash, so the
|
|
2868
|
-
* escaped string, when compiled into a `RegExp`, matches only its own literal characters — no
|
|
2869
|
-
* character acts as a quantifier, anchor, group, or class. Pure string assembly, total — never
|
|
2870
|
-
* throws.
|
|
2871
|
-
*
|
|
2872
|
-
* @param value - The text to escape for literal use inside a `RegExp` pattern
|
|
2873
|
-
* @returns `value` with every regex-special character backslash-escaped
|
|
2874
|
-
*
|
|
2875
|
-
* @example
|
|
2876
|
-
* ```ts
|
|
2877
|
-
* escapeRegExp('a.b*c') // 'a\\.b\\*c'
|
|
2878
|
-
* new RegExp(escapeRegExp('a.b*c')).test('a.b*c') // true
|
|
2879
|
-
* ```
|
|
2880
|
-
*/
|
|
2881
|
-
export declare function escapeRegExp(value: string): string;
|
|
2882
|
-
|
|
2883
2473
|
/**
|
|
2884
2474
|
* Estimate the context-token footprint of a batch of messages — the default `consume`
|
|
2885
2475
|
* estimator for an agent's context `BudgetInterface` (a budgets surface's tracking contract)
|
|
@@ -2934,13 +2524,6 @@ export declare function estimateMessages(messages: readonly MessageInterface[]):
|
|
|
2934
2524
|
*/
|
|
2935
2525
|
export declare function estimateTokens(text: string): number;
|
|
2936
2526
|
|
|
2937
|
-
/**
|
|
2938
|
-
* The extension→language table {@link import('./helpers.js').inferLanguage} reads to
|
|
2939
|
-
* map a file path's extension to a fenced-code language tag. Covers the common source /
|
|
2940
|
-
* markup / data extensions; an unlisted extension falls back to `'text'`.
|
|
2941
|
-
*/
|
|
2942
|
-
export declare const EXTENSION_TO_LANGUAGE: Readonly<Record<string, string>>;
|
|
2943
|
-
|
|
2944
2527
|
/**
|
|
2945
2528
|
* Render a path-addressed text body as a fenced reference block — the framing an
|
|
2946
2529
|
* {@link import('./AgentContext.js').AgentContext}'s ACTIVE-workspace text-file render emits (the
|
|
@@ -2951,7 +2534,7 @@ export declare const EXTENSION_TO_LANGUAGE: Readonly<Record<string, string>>;
|
|
|
2951
2534
|
* fenced code block tagged with `language`, the `content` verbatim inside. Pure string assembly,
|
|
2952
2535
|
* total — never throws. The one fenced-file format string for the whole module — `AgentContext.build()`
|
|
2953
2536
|
* frames an active workspace's text files with it (each carries its own `language` on its
|
|
2954
|
-
* {@link FileContent} text arm).
|
|
2537
|
+
* {@link import('@orkestrel/workspace').FileContent} text arm).
|
|
2955
2538
|
*
|
|
2956
2539
|
* @param path - The file path shown on the `File:` label line
|
|
2957
2540
|
* @param language - The fenced-code language tag (e.g. `'typescript'`)
|
|
@@ -2968,74 +2551,6 @@ export declare const EXTENSION_TO_LANGUAGE: Readonly<Record<string, string>>;
|
|
|
2968
2551
|
*/
|
|
2969
2552
|
export declare function fencedFile(path: string, language: string, content: string): string;
|
|
2970
2553
|
|
|
2971
|
-
/**
|
|
2972
|
-
* A {@link FileInterface}'s content — a TAGLESS union of a TEXT arm and a BINARY arm, narrowed
|
|
2973
|
-
* by the {@link import('./helpers.js').isText} / {@link import('./helpers.js').isBinary}
|
|
2974
|
-
* guards (AGENTS §14: an untyped arm is narrowed via a guard, never an `as`).
|
|
2975
|
-
*
|
|
2976
|
-
* @remarks
|
|
2977
|
-
* - The TEXT arm carries the literal `text` plus the fenced-code `language` it renders as.
|
|
2978
|
-
* - The BINARY arm carries the base64-encoded `data` plus the {@link BinaryMIME} that labels it.
|
|
2979
|
-
*
|
|
2980
|
-
* There is no `modality` discriminant — the arms are told apart structurally
|
|
2981
|
-
* (`'text' in content` vs `'data' in content`) by the guards. A binary arm whose `mime`
|
|
2982
|
-
* starts with `image/` IS an image ({@link import('./helpers.js').isImage}). A future
|
|
2983
|
-
* non-image binary (a PDF) is the same binary arm with a new {@link BinaryMIME} — additive,
|
|
2984
|
-
* with nothing above it changed.
|
|
2985
|
-
*/
|
|
2986
|
-
export declare type FileContent = {
|
|
2987
|
-
readonly text: string;
|
|
2988
|
-
readonly language: string;
|
|
2989
|
-
} | {
|
|
2990
|
-
readonly data: string;
|
|
2991
|
-
readonly mime: BinaryMIME;
|
|
2992
|
-
};
|
|
2993
|
-
|
|
2994
|
-
/**
|
|
2995
|
-
* The minimal data to author a {@link FileInterface} — `size` / `lines` are DERIVED from the
|
|
2996
|
-
* `content`, so a caller supplies only `path` / `content` (and an optional `state`, defaulting
|
|
2997
|
-
* to `'created'`).
|
|
2998
|
-
*/
|
|
2999
|
-
export declare interface FileInput {
|
|
3000
|
-
readonly path: string;
|
|
3001
|
-
readonly content: FileContent;
|
|
3002
|
-
/** The lifecycle state; defaults to `'created'` when omitted. */
|
|
3003
|
-
readonly state?: FileState;
|
|
3004
|
-
}
|
|
3005
|
-
|
|
3006
|
-
/**
|
|
3007
|
-
* An immutable file value object — a `path`-addressed {@link FileContent} carrying a
|
|
3008
|
-
* lifecycle {@link FileState}, with `size` / `lines` DERIVED once when built.
|
|
3009
|
-
*
|
|
3010
|
-
* @remarks
|
|
3011
|
-
* A PLAIN frozen record (not a class instance) produced by
|
|
3012
|
-
* {@link import('./factories.js').createFile} — the `path` IS its identity (there is no
|
|
3013
|
-
* `id`). `size` and `lines` are computed from `content` when built (so they can never drift
|
|
3014
|
-
* from it) and re-read for free thereafter. Never mutated — a Workspace REPLACES a file
|
|
3015
|
-
* rather than editing it in place. A DATA-ONLY value object — no methods, plus it
|
|
3016
|
-
* `structuredClone`s losslessly (every field is a plain primitive / record).
|
|
3017
|
-
*/
|
|
3018
|
-
export declare interface FileInterface {
|
|
3019
|
-
readonly path: string;
|
|
3020
|
-
readonly content: FileContent;
|
|
3021
|
-
readonly state: FileState;
|
|
3022
|
-
/** Derived byte size: UTF-8 byte length (text) / decoded payload bytes (binary). */
|
|
3023
|
-
readonly size: number;
|
|
3024
|
-
/** Derived line count: the text line count; `0` for a binary arm. */
|
|
3025
|
-
readonly lines: number;
|
|
3026
|
-
}
|
|
3027
|
-
|
|
3028
|
-
/**
|
|
3029
|
-
* The lifecycle state of a {@link FileInterface} relative to its (future) durable backing
|
|
3030
|
-
* — a multi-value lifecycle union (AGENTS §10), not a boolean.
|
|
3031
|
-
*
|
|
3032
|
-
* @remarks
|
|
3033
|
-
* `'created'` is a brand-new file not yet persisted; `'modified'` has unsaved edits over a
|
|
3034
|
-
* persisted original; `'loaded'` was read from the backing and is unchanged; `'deleted'`
|
|
3035
|
-
* is tombstoned. A `File` authored without a `state` defaults to `'created'`.
|
|
3036
|
-
*/
|
|
3037
|
-
export declare type FileState = 'created' | 'modified' | 'loaded' | 'deleted';
|
|
3038
|
-
|
|
3039
2554
|
/**
|
|
3040
2555
|
* Filter a list of items by a {@link import('./types.js').ScopeInterface} allow-list of
|
|
3041
2556
|
* keys — the pure, total set-membership primitive the context's build step and the agent
|
|
@@ -3108,33 +2623,12 @@ export declare function handleAgentRunnerJob(registry: AgentRegistryInterface, a
|
|
|
3108
2623
|
export declare const IMAGE_TOKEN_ESTIMATE = 512;
|
|
3109
2624
|
|
|
3110
2625
|
/**
|
|
3111
|
-
*
|
|
3112
|
-
* (
|
|
2626
|
+
* An immutable named directive — a {@link InstructionInterface} assembled once from its
|
|
2627
|
+
* input (`name` / `content`, an optional `priority` defaulting to `0`), the `id` minted
|
|
2628
|
+
* at construction.
|
|
3113
2629
|
*
|
|
3114
2630
|
* @remarks
|
|
3115
|
-
*
|
|
3116
|
-
* fixed extension→language table. An unknown extension, or a path with no extension,
|
|
3117
|
-
* falls back to `'text'` (a safe, language-agnostic fence). Total — never throws.
|
|
3118
|
-
*
|
|
3119
|
-
* @param path - The document's file path (e.g. `'src/main.ts'`)
|
|
3120
|
-
* @returns The inferred language tag (e.g. `'typescript'`), or `'text'` when unknown
|
|
3121
|
-
*
|
|
3122
|
-
* @example
|
|
3123
|
-
* ```ts
|
|
3124
|
-
* inferLanguage('src/main.ts') // 'typescript'
|
|
3125
|
-
* inferLanguage('README.md') // 'markdown'
|
|
3126
|
-
* inferLanguage('LICENSE') // 'text'
|
|
3127
|
-
* ```
|
|
3128
|
-
*/
|
|
3129
|
-
export declare function inferLanguage(path: string): string;
|
|
3130
|
-
|
|
3131
|
-
/**
|
|
3132
|
-
* An immutable named directive — a {@link InstructionInterface} assembled once from its
|
|
3133
|
-
* input (`name` / `content`, an optional `priority` defaulting to `0`), the `id` minted
|
|
3134
|
-
* at construction.
|
|
3135
|
-
*
|
|
3136
|
-
* @remarks
|
|
3137
|
-
* A thin immutable value object (mirroring {@link import('../tools/Tool.js').Tool}): the
|
|
2631
|
+
* A thin immutable value object (mirroring {@link import('@orkestrel/tool').Tool}): the
|
|
3138
2632
|
* constructor mints a fresh `id` (`crypto.randomUUID()`), copies the input's `name` /
|
|
3139
2633
|
* `content`, resolves `priority` to the input's value or `0`, and carries the input's
|
|
3140
2634
|
* per-item `format` override ONLY when supplied (assigned just when present, mirroring a
|
|
@@ -3373,28 +2867,6 @@ export declare function isAgentError(value: unknown): value is AgentError;
|
|
|
3373
2867
|
*/
|
|
3374
2868
|
export declare function isAgentJobError(value: unknown): value is AgentJobError;
|
|
3375
2869
|
|
|
3376
|
-
/**
|
|
3377
|
-
* Whether a {@link FileContent} is the BINARY arm — the narrowing guard for the text-vs-binary
|
|
3378
|
-
* union (AGENTS §14: narrow an untyped arm via a guard, never an `as`).
|
|
3379
|
-
*
|
|
3380
|
-
* @remarks
|
|
3381
|
-
* Tests `'data' in content` structurally — there is no `modality` discriminant. A `true`
|
|
3382
|
-
* narrows `content` to `{ data: string; mime: BinaryMIME }`, unlocking `.data` / `.mime`. An
|
|
3383
|
-
* image is a binary whose `mime` starts with `image/` ({@link isImage}). Total — never throws.
|
|
3384
|
-
*
|
|
3385
|
-
* @param content - The file content to test
|
|
3386
|
-
* @returns `true` when `content` is the binary arm (carries base64 `data` + `mime`)
|
|
3387
|
-
*
|
|
3388
|
-
* @example
|
|
3389
|
-
* ```ts
|
|
3390
|
-
* if (isBinary(file.content)) file.content.data // the base64 payload + .mime
|
|
3391
|
-
* ```
|
|
3392
|
-
*/
|
|
3393
|
-
export declare function isBinary(content: FileContent): content is {
|
|
3394
|
-
readonly data: string;
|
|
3395
|
-
readonly mime: BinaryMIME;
|
|
3396
|
-
};
|
|
3397
|
-
|
|
3398
2870
|
/**
|
|
3399
2871
|
* Narrow an unknown caught value to a {@link ConversationError}.
|
|
3400
2872
|
*
|
|
@@ -3417,7 +2889,7 @@ export declare function isConversationError(value: unknown): value is Conversati
|
|
|
3417
2889
|
* UNTRUSTED snapshot read (a storage row a
|
|
3418
2890
|
* {@link import('./conversations/stores/DatabaseConversationStore.js').DatabaseConversationStore}
|
|
3419
2891
|
* reads back from its opaque JSON column, a snapshot loaded from disk). The EXACT analogue of
|
|
3420
|
-
* {@link isWorkspaceSnapshot}.
|
|
2892
|
+
* {@link import('@orkestrel/workspace').isWorkspaceSnapshot}.
|
|
3421
2893
|
*
|
|
3422
2894
|
* @remarks
|
|
3423
2895
|
* A total guard (it NEVER throws — adversarial input returns `false`). It checks the snapshot's
|
|
@@ -3426,7 +2898,7 @@ export declare function isConversationError(value: unknown): value is Conversati
|
|
|
3426
2898
|
* {@link SectionInterface} ({@link isSection}), and a `messages` array EVERY element of which is a
|
|
3427
2899
|
* valid {@link MessageInterface} ({@link isMessage}) — enough to safely impose the
|
|
3428
2900
|
* {@link ConversationSnapshot} type at a storage boundary WITHOUT a cast. The structural twin of
|
|
3429
|
-
* {@link isWorkspaceSnapshot}. A malformed blob (a non-record, a missing / non-string `id`, a
|
|
2901
|
+
* {@link import('@orkestrel/workspace').isWorkspaceSnapshot}. A malformed blob (a non-record, a missing / non-string `id`, a
|
|
3430
2902
|
* non-string `summary` when present, a non-array `sections` / `messages`, or any malformed
|
|
3431
2903
|
* element) resolves `false`, so a
|
|
3432
2904
|
* {@link import('./conversations/stores/DatabaseConversationStore.js').DatabaseConversationStore}
|
|
@@ -3445,68 +2917,23 @@ export declare function isConversationError(value: unknown): value is Conversati
|
|
|
3445
2917
|
*/
|
|
3446
2918
|
export declare function isConversationSnapshot(value: unknown): value is ConversationSnapshot;
|
|
3447
2919
|
|
|
3448
|
-
/**
|
|
3449
|
-
* Whether an `unknown` is structurally a {@link FileInterface} record — the per-file step of the
|
|
3450
|
-
* {@link isWorkspaceSnapshot} read-boundary narrow (AGENTS §14: narrow an untrusted storage read
|
|
3451
|
-
* via a guard, never an `as`).
|
|
3452
|
-
*
|
|
3453
|
-
* @remarks
|
|
3454
|
-
* A total guard (it NEVER throws — adversarial input returns `false`). It checks the file's SHAPE:
|
|
3455
|
-
* a record with a `string` `path`, a `string` `state`, `number` `size` / `lines`, and a `content`
|
|
3456
|
-
* that is EITHER the TEXT arm (`{ text: string; language: string }`) OR the BINARY arm
|
|
3457
|
-
* (`{ data: string; mime: string }`) — the tagless {@link FileContent} union, told apart
|
|
3458
|
-
* structurally exactly as {@link isText} / {@link isBinary} do (no `modality` discriminant). Enough
|
|
3459
|
-
* to safely impose the {@link FileInterface} type at a storage boundary WITHOUT a cast; the `mime`
|
|
3460
|
-
* is left as a broad `string` here (an open {@link BinaryMIME}, so any storage-read MIME string is
|
|
3461
|
-
* accepted defensively rather than rejected against the current literal set).
|
|
3462
|
-
*
|
|
3463
|
-
* @param value - The value to test (one element of a snapshot's opaque `files` array)
|
|
3464
|
-
* @returns `true` when `value` has the structural shape of a {@link FileInterface}
|
|
3465
|
-
*
|
|
3466
|
-
* @example
|
|
3467
|
-
* ```ts
|
|
3468
|
-
* isFile({ path: 'a.ts', content: { text: 'x', language: 'typescript' }, state: 'created', size: 1, lines: 1 }) // true
|
|
3469
|
-
* isFile({ path: 'a.png', content: { data: 'AAAA', mime: 'image/png' }, state: 'created', size: 3, lines: 0 }) // true
|
|
3470
|
-
* isFile({ path: 'a.ts' }) // false (missing content / state / size / lines)
|
|
3471
|
-
* ```
|
|
3472
|
-
*/
|
|
3473
|
-
export declare function isFile(value: unknown): value is FileInterface;
|
|
3474
|
-
|
|
3475
|
-
/**
|
|
3476
|
-
* Whether a {@link FileContent} is an IMAGE — a {@link isBinary} arm whose `mime` is an
|
|
3477
|
-
* `image/*` type (an image is just a binary with an image MIME).
|
|
3478
|
-
*
|
|
3479
|
-
* @remarks
|
|
3480
|
-
* Narrows to the binary arm first, then checks the `image/` MIME prefix — so a future
|
|
3481
|
-
* non-image binary (a PDF, `'application/pdf'`) is binary but NOT an image. Total — never
|
|
3482
|
-
* throws.
|
|
3483
|
-
*
|
|
3484
|
-
* @param content - The file content to test
|
|
3485
|
-
* @returns `true` when `content` is a binary arm with an `image/*` MIME
|
|
3486
|
-
*
|
|
3487
|
-
* @example
|
|
3488
|
-
* ```ts
|
|
3489
|
-
* isImage({ data: '<base64>', mime: 'image/png' }) // true
|
|
3490
|
-
* isImage({ text: 'hi', language: 'text' }) // false
|
|
3491
|
-
* ```
|
|
3492
|
-
*/
|
|
3493
|
-
export declare function isImage(content: FileContent): boolean;
|
|
3494
|
-
|
|
3495
2920
|
/**
|
|
3496
2921
|
* Whether an `unknown` is structurally a {@link MessageInterface} record — the per-message step of
|
|
3497
2922
|
* the {@link isConversationSnapshot} read-boundary narrow (AGENTS §14: narrow an untrusted storage
|
|
3498
|
-
* read via a guard, never an `as`). The conversation analogue of
|
|
2923
|
+
* read via a guard, never an `as`). The conversation analogue of
|
|
2924
|
+
* {@link import('@orkestrel/workspace').isFile}.
|
|
3499
2925
|
*
|
|
3500
2926
|
* @remarks
|
|
3501
2927
|
* A total guard (it NEVER throws — adversarial input returns `false`). It checks the message's
|
|
3502
2928
|
* SHAPE: a record with a `string` `id`, a `string` `role`, a `string` `content`, and — WHEN present
|
|
3503
|
-
* — a `calls` array EVERY element of which is a valid
|
|
2929
|
+
* — a `calls` array EVERY element of which is a valid
|
|
2930
|
+
* {@link import('@orkestrel/tool').ToolCall} ({@link isToolCall} — the
|
|
3504
2931
|
* ASI06 fail-closed deepening: a tampered `calls` element rejects the message, so the snapshot
|
|
3505
2932
|
* reads back as absent rather than replaying a malformed call) and an `images` that is an array
|
|
3506
2933
|
* (an absent optional passes). The `role` is left as a broad `string` here (an open
|
|
3507
2934
|
* {@link import('./types.js').MessageRole}, so any storage-read role string is accepted
|
|
3508
|
-
* defensively rather than rejected against the current literal set)
|
|
3509
|
-
*
|
|
2935
|
+
* defensively rather than rejected against the current literal set). Enough to safely impose the
|
|
2936
|
+
* {@link MessageInterface} type at
|
|
3510
2937
|
* a storage boundary WITHOUT a cast.
|
|
3511
2938
|
*
|
|
3512
2939
|
* @param value - The value to test (one element of a snapshot's `messages` / a section's `messages`)
|
|
@@ -3562,132 +2989,16 @@ export declare function isProviderAbortError(value: unknown): value is ProviderA
|
|
|
3562
2989
|
*/
|
|
3563
2990
|
export declare function isSection(value: unknown): value is SectionInterface;
|
|
3564
2991
|
|
|
3565
|
-
/**
|
|
3566
|
-
* Whether a {@link FileContent} is the TEXT arm — the narrowing guard for the text-vs-binary
|
|
3567
|
-
* union (AGENTS §14: narrow an untyped arm via a guard, never an `as`).
|
|
3568
|
-
*
|
|
3569
|
-
* @remarks
|
|
3570
|
-
* Tests `'text' in content` structurally — there is no `modality` discriminant. A `true`
|
|
3571
|
-
* narrows `content` to `{ text: string; language: string }`, unlocking `.text` / `.language`.
|
|
3572
|
-
* Total — never throws.
|
|
3573
|
-
*
|
|
3574
|
-
* @param content - The file content to test
|
|
3575
|
-
* @returns `true` when `content` is the text arm (carries `text` + `language`)
|
|
3576
|
-
*
|
|
3577
|
-
* @example
|
|
3578
|
-
* ```ts
|
|
3579
|
-
* if (isText(file.content)) file.content.text // the literal text + .language
|
|
3580
|
-
* ```
|
|
3581
|
-
*/
|
|
3582
|
-
export declare function isText(content: FileContent): content is {
|
|
3583
|
-
readonly text: string;
|
|
3584
|
-
readonly language: string;
|
|
3585
|
-
};
|
|
3586
|
-
|
|
3587
|
-
/**
|
|
3588
|
-
* Whether an `unknown` is structurally a {@link ToolCall} record — the per-call step of the
|
|
3589
|
-
* {@link isMessage} read-boundary narrow (AGENTS §14: narrow an untrusted storage read via a
|
|
3590
|
-
* guard, never an `as`).
|
|
3591
|
-
*
|
|
3592
|
-
* @remarks
|
|
3593
|
-
* A total guard (it NEVER throws — adversarial input returns `false`). It checks the call's
|
|
3594
|
-
* SHAPE: a record with a `string` `id`, a `string` `name`, and a record `arguments` — the real
|
|
3595
|
-
* {@link ToolCall} shape a restored assistant turn replays to a provider. This is the ASI06
|
|
3596
|
-
* fail-CLOSED element check: a tampered persisted call (`null`, a bare string, a non-record
|
|
3597
|
-
* `arguments`) fails the guard, so {@link isMessage} — and through it
|
|
3598
|
-
* {@link isConversationSnapshot} — rejects the whole snapshot and a poisoned store row reads
|
|
3599
|
-
* back as ABSENT instead of replaying a malformed call into a chat template.
|
|
3600
|
-
*
|
|
3601
|
-
* @param value - The value to test (one element of an assistant message's `calls`)
|
|
3602
|
-
* @returns `true` when `value` has the structural shape of a {@link ToolCall}
|
|
3603
|
-
*
|
|
3604
|
-
* @example
|
|
3605
|
-
* ```ts
|
|
3606
|
-
* isToolCall({ id: 'c1', name: 'search', arguments: { q: 'acme' } }) // true
|
|
3607
|
-
* isToolCall({ id: 'c1', name: 'search' }) // false (missing arguments)
|
|
3608
|
-
* isToolCall({ id: 'c1', name: 123, arguments: {} }) // false (non-string name)
|
|
3609
|
-
* ```
|
|
3610
|
-
*/
|
|
3611
|
-
export declare function isToolCall(value: unknown): value is ToolCall;
|
|
3612
|
-
|
|
3613
|
-
/**
|
|
3614
|
-
* Whether a {@link Range} is STRUCTURALLY valid — the predicate a ranged `write` checks
|
|
3615
|
-
* before applying (a `false` here is the `RANGE` throw).
|
|
3616
|
-
*
|
|
3617
|
-
* @remarks
|
|
3618
|
-
* Structural validity is independent of any content: every component must be `>= 1`
|
|
3619
|
-
* (1-based lines and columns), and `start` must not come after `end` (an inverted range
|
|
3620
|
-
* is invalid). A range that is structurally valid but reaches PAST the end of a specific
|
|
3621
|
-
* text is still valid — it is {@link clampRange}d to the bounds when applied, not rejected.
|
|
3622
|
-
* Total — never throws.
|
|
3623
|
-
*
|
|
3624
|
-
* @param range - The range to validate
|
|
3625
|
-
* @returns `true` when every component is `>= 1` and `start` is at or before `end`
|
|
3626
|
-
*
|
|
3627
|
-
* @example
|
|
3628
|
-
* ```ts
|
|
3629
|
-
* isValidRange({ start: { line: 1, column: 1 }, end: { line: 2, column: 1 } }) // true
|
|
3630
|
-
* isValidRange({ start: { line: 2, column: 1 }, end: { line: 1, column: 1 } }) // false (inverted)
|
|
3631
|
-
* isValidRange({ start: { line: 0, column: 1 }, end: { line: 1, column: 1 } }) // false (sub-1 line)
|
|
3632
|
-
* ```
|
|
3633
|
-
*/
|
|
3634
|
-
export declare function isValidRange(range: Range): boolean;
|
|
3635
|
-
|
|
3636
|
-
/**
|
|
3637
|
-
* Narrow an unknown caught value to a {@link WorkspaceError}.
|
|
3638
|
-
*
|
|
3639
|
-
* @param value - The value to test (typically a `catch` binding)
|
|
3640
|
-
* @returns `true` when `value` is a {@link WorkspaceError}
|
|
3641
|
-
*
|
|
3642
|
-
* @example
|
|
3643
|
-
* ```ts
|
|
3644
|
-
* try {
|
|
3645
|
-
* workspace.prepend('icon.png', '// header')
|
|
3646
|
-
* } catch (error) {
|
|
3647
|
-
* if (isWorkspaceError(error) && error.code === 'MODALITY') skipBinary()
|
|
3648
|
-
* }
|
|
3649
|
-
* ```
|
|
3650
|
-
*/
|
|
3651
|
-
export declare function isWorkspaceError(value: unknown): value is WorkspaceError;
|
|
3652
|
-
|
|
3653
|
-
/**
|
|
3654
|
-
* Narrow an `unknown` to a {@link WorkspaceSnapshot} — the AGENTS §14 boundary guard for an
|
|
3655
|
-
* UNTRUSTED snapshot read (a storage row a
|
|
3656
|
-
* {@link import('./workspaces/stores/DatabaseWorkspaceStore.js').DatabaseWorkspaceStore} reads back
|
|
3657
|
-
* from its opaque JSON column, a snapshot loaded from disk).
|
|
3658
|
-
*
|
|
3659
|
-
* @remarks
|
|
3660
|
-
* A total guard (it NEVER throws — adversarial input returns `false`). It checks the snapshot's
|
|
3661
|
-
* SHAPE: a `string` `id` and a `files` array EVERY element of which is a valid {@link FileInterface}
|
|
3662
|
-
* record ({@link isFile}) — enough to safely impose the {@link WorkspaceSnapshot} type at a storage
|
|
3663
|
-
* boundary WITHOUT a cast. The structural twin of
|
|
3664
|
-
* the analogous `isWorkflowSnapshot` in `@orkestrel/workflow`. A malformed blob (a non-record, a
|
|
3665
|
-
* missing / non-string `id`, a non-array `files`, or any malformed file element) resolves `false`,
|
|
3666
|
-
* so a {@link import('./workspaces/stores/DatabaseWorkspaceStore.js').DatabaseWorkspaceStore} read
|
|
3667
|
-
* yields `undefined` rather than a broken workspace.
|
|
3668
|
-
*
|
|
3669
|
-
* @param value - The value to test (an opaque storage read)
|
|
3670
|
-
* @returns `true` when `value` has the structural shape of a {@link WorkspaceSnapshot}
|
|
3671
|
-
*
|
|
3672
|
-
* @example
|
|
3673
|
-
* ```ts
|
|
3674
|
-
* isWorkspaceSnapshot({ id: 'w1', files: [] }) // true
|
|
3675
|
-
* isWorkspaceSnapshot({ id: 'w1', files: 'nope' }) // false
|
|
3676
|
-
* isWorkspaceSnapshot({ files: [] }) // false (missing id)
|
|
3677
|
-
* ```
|
|
3678
|
-
*/
|
|
3679
|
-
export declare function isWorkspaceSnapshot(value: unknown): value is WorkspaceSnapshot;
|
|
3680
|
-
|
|
3681
2992
|
/**
|
|
3682
2993
|
* The in-memory {@link ConversationStoreInterface} — a process-lifetime `Map` of
|
|
3683
2994
|
* {@link ConversationSnapshot}s keyed by conversation id, the DEFAULT store
|
|
3684
2995
|
* {@link import('../../factories.js').createMemoryConversationStore} builds. The EXACT twin of
|
|
3685
|
-
* {@link import('
|
|
2996
|
+
* {@link import('@orkestrel/workspace').MemoryWorkspaceStore}.
|
|
3686
2997
|
*
|
|
3687
2998
|
* @remarks
|
|
3688
2999
|
* A plain `Map<string, ConversationSnapshot>` (AGENTS §21 — the snapshot is already pure,
|
|
3689
3000
|
* self-contained JSON, so no encoding is needed for the memory tier). Like the
|
|
3690
|
-
* {@link import('
|
|
3001
|
+
* {@link import('@orkestrel/workspace').MemoryWorkspaceStore} it twins,
|
|
3691
3002
|
* there is NO idle-TTL and NO eviction: a persisted conversation lives until an explicit `delete`. A
|
|
3692
3003
|
* durable backend (JSON / SQLite / IndexedDB) swaps in through the SAME interface without touching
|
|
3693
3004
|
* the {@link import('../ConversationManager.js').ConversationManager} or the
|
|
@@ -3723,50 +3034,6 @@ export declare class MemoryConversationStore implements ConversationStoreInterfa
|
|
|
3723
3034
|
delete(id: string): Promise<void>;
|
|
3724
3035
|
}
|
|
3725
3036
|
|
|
3726
|
-
/**
|
|
3727
|
-
* The in-memory {@link WorkspaceStoreInterface} — a process-lifetime `Map` of
|
|
3728
|
-
* {@link WorkspaceSnapshot}s keyed by workspace id, the DEFAULT store
|
|
3729
|
-
* {@link import('../../factories.js').createMemoryWorkspaceStore} builds.
|
|
3730
|
-
*
|
|
3731
|
-
* @remarks
|
|
3732
|
-
* A plain `Map<string, WorkspaceSnapshot>` (AGENTS §21 — the snapshot is already pure,
|
|
3733
|
-
* self-contained JSON, so no encoding is needed for the memory tier). Like the
|
|
3734
|
-
* the analogous `MemoryWorkflowStore` in `@orkestrel/workflow` it twins,
|
|
3735
|
-
* there is NO idle-TTL and NO eviction: a persisted workspace lives until an explicit `delete`. A
|
|
3736
|
-
* durable backend (JSON / SQLite / IndexedDB) swaps in through the SAME interface without touching
|
|
3737
|
-
* the {@link import('../WorkspaceManager.js').WorkspaceManager} or the
|
|
3738
|
-
* {@link import('../Workspace.js').Workspace} — its driver-pluggable twin is
|
|
3739
|
-
* {@link import('./DatabaseWorkspaceStore.js').DatabaseWorkspaceStore} (the snapshot as one opaque
|
|
3740
|
-
* JSON column).
|
|
3741
|
-
*
|
|
3742
|
-
* - **`get` resolves the persisted snapshot for an id**, or `undefined` if none is stored.
|
|
3743
|
-
* - **`set` inserts / replaces under the snapshot's OWN `id`** (no separate id param).
|
|
3744
|
-
* - **`delete` drops a snapshot by id**; an absent id is a no-op (no throw).
|
|
3745
|
-
*
|
|
3746
|
-
* The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the §22 method
|
|
3747
|
-
* bijection with {@link WorkspaceStoreInterface}). Hydration is a caller concern: a
|
|
3748
|
-
* {@link import('../WorkspaceManager.js').WorkspaceManager} reads a snapshot back and rebuilds the
|
|
3749
|
-
* live workspace through the constructor `seed` (its `open` / `save`).
|
|
3750
|
-
*
|
|
3751
|
-
* @example
|
|
3752
|
-
* ```ts
|
|
3753
|
-
* import { createMemoryWorkspaceStore, createWorkspace } from '@src/core'
|
|
3754
|
-
*
|
|
3755
|
-
* const store = createMemoryWorkspaceStore()
|
|
3756
|
-
* const workspace = createWorkspace()
|
|
3757
|
-
* workspace.write('notes.txt', 'hello')
|
|
3758
|
-
* await store.set(workspace.snapshot()) // persist the workspace
|
|
3759
|
-
* const snapshot = await store.get(workspace.id)
|
|
3760
|
-
* await store.delete(workspace.id) // drop it
|
|
3761
|
-
* ```
|
|
3762
|
-
*/
|
|
3763
|
-
export declare class MemoryWorkspaceStore implements WorkspaceStoreInterface {
|
|
3764
|
-
#private;
|
|
3765
|
-
get(id: string): Promise<WorkspaceSnapshot | undefined>;
|
|
3766
|
-
set(snapshot: WorkspaceSnapshot): Promise<void>;
|
|
3767
|
-
delete(id: string): Promise<void>;
|
|
3768
|
-
}
|
|
3769
|
-
|
|
3770
3037
|
/**
|
|
3771
3038
|
* The estimated per-message role/framing overhead {@link import('./helpers.js').estimateMessages}
|
|
3772
3039
|
* adds on top of a message's content estimate — accounts for the fixed wire framing every
|
|
@@ -3844,42 +3111,6 @@ export declare interface MessageManagerInterface {
|
|
|
3844
3111
|
/** The role a {@link MessageInterface} plays in a conversation turn. */
|
|
3845
3112
|
export declare type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
3846
3113
|
|
|
3847
|
-
/**
|
|
3848
|
-
* Convert a 1-based {@link Position} to a 0-based string offset into `text` — the indexing
|
|
3849
|
-
* primitive {@link sliceRange} / {@link spliceRange} use, clamped to `text.length`.
|
|
3850
|
-
*
|
|
3851
|
-
* @remarks
|
|
3852
|
-
* Sums each preceding line's length plus its `\n` separator, then adds the `column - 1`
|
|
3853
|
-
* within the target line, capped at `text.length`. Total — never throws (an out-of-bounds
|
|
3854
|
-
* position yields a defined in-range offset).
|
|
3855
|
-
*
|
|
3856
|
-
* @param text - The text to index into
|
|
3857
|
-
* @param position - The 1-based position to resolve
|
|
3858
|
-
* @returns The 0-based offset (in `[0, text.length]`)
|
|
3859
|
-
*
|
|
3860
|
-
* @example
|
|
3861
|
-
* ```ts
|
|
3862
|
-
* offsetAt('ab\ncd', { line: 2, column: 1 }) // 3 (just after 'ab\n')
|
|
3863
|
-
* ```
|
|
3864
|
-
*/
|
|
3865
|
-
export declare function offsetAt(text: string, position: Position): number;
|
|
3866
|
-
|
|
3867
|
-
/**
|
|
3868
|
-
* A 1-based caret position inside a text file — `line` and `column` both count from `1`
|
|
3869
|
-
* (column `1` is the first character of the line), matching an editor's gutter.
|
|
3870
|
-
*
|
|
3871
|
-
* @remarks
|
|
3872
|
-
* The {@link import('./workspaces/Workspace.js').Workspace} edit surface speaks 1-based
|
|
3873
|
-
* positions end to end ({@link Range}, {@link ReadResult}, {@link SearchMatch}). A
|
|
3874
|
-
* structurally invalid component (`line < 1` or `column < 1`) is rejected by a range op
|
|
3875
|
-
* (`RANGE`); an in-bounds-but-past-the-end one is CLAMPED to the nearest valid caret rather
|
|
3876
|
-
* than rejected.
|
|
3877
|
-
*/
|
|
3878
|
-
export declare interface Position {
|
|
3879
|
-
readonly line: number;
|
|
3880
|
-
readonly column: number;
|
|
3881
|
-
}
|
|
3882
|
-
|
|
3883
3114
|
/**
|
|
3884
3115
|
* Thrown by a {@link ProviderInterface}'s `stream` when its bound signal aborts
|
|
3885
3116
|
* mid-flight — carries the {@link ProviderResult} assembled from whatever streamed
|
|
@@ -4022,87 +3253,6 @@ export declare interface ProviderStreamOptions {
|
|
|
4022
3253
|
readonly schema?: Readonly<Record<string, unknown>>;
|
|
4023
3254
|
}
|
|
4024
3255
|
|
|
4025
|
-
/**
|
|
4026
|
-
* A half-open span of text between two {@link Position}s — `start` INCLUSIVE, `end`
|
|
4027
|
-
* EXCLUSIVE (the character at `end` is not part of the span).
|
|
4028
|
-
*
|
|
4029
|
-
* @remarks
|
|
4030
|
-
* A range whose `start` is at or before its `end` is valid; an inverted range
|
|
4031
|
-
* (`start` after `end`) or one with a sub-1 component is structurally invalid and a range
|
|
4032
|
-
* op throws `RANGE`. Each in-bounds component is clamped to the text before it is applied,
|
|
4033
|
-
* so a range reaching past the end of the content reads / splices up to the end.
|
|
4034
|
-
*/
|
|
4035
|
-
export declare interface Range {
|
|
4036
|
-
readonly start: Position;
|
|
4037
|
-
readonly end: Position;
|
|
4038
|
-
}
|
|
4039
|
-
|
|
4040
|
-
/**
|
|
4041
|
-
* Assemble a 1-based nested {@link Range} from four FLAT caret integers — the bridge a
|
|
4042
|
-
* workspace-editing tool (see `@orkestrel/tool`) uses from its small-model FLAT surface back to the
|
|
4043
|
-
* nested {@link Range} the {@link import('./workspaces/Workspace.js').Workspace} edit surface
|
|
4044
|
-
* speaks. Published as a public helper for that consumer.
|
|
4045
|
-
*
|
|
4046
|
-
* @remarks
|
|
4047
|
-
* Pairs `(fromLine, fromColumn)` into `start` and `(toLine, toColumn)` into `end` verbatim — a pure
|
|
4048
|
-
* structural lift, no validation (a structurally invalid range is rejected downstream by the ranged
|
|
4049
|
-
* `write` it feeds, via {@link isValidRange}). Total — never throws. Zero-Node.
|
|
4050
|
-
*
|
|
4051
|
-
* @param fromLine - The 1-based start line
|
|
4052
|
-
* @param fromColumn - The 1-based start column
|
|
4053
|
-
* @param toLine - The 1-based end line
|
|
4054
|
-
* @param toColumn - The 1-based end column
|
|
4055
|
-
* @returns The `{ start, end }` {@link Range}
|
|
4056
|
-
*
|
|
4057
|
-
* @example
|
|
4058
|
-
* ```ts
|
|
4059
|
-
* rangeOf(1, 11, 1, 12) // { start: { line: 1, column: 11 }, end: { line: 1, column: 12 } }
|
|
4060
|
-
* ```
|
|
4061
|
-
*/
|
|
4062
|
-
export declare function rangeOf(fromLine: number, fromColumn: number, toLine: number, toColumn: number): Range;
|
|
4063
|
-
|
|
4064
|
-
/**
|
|
4065
|
-
* The outcome of a ranged {@link WorkspaceInterface.read} — the sliced `content` plus the
|
|
4066
|
-
* `range` actually applied after clamping (so a caller learns the real span it got).
|
|
4067
|
-
*
|
|
4068
|
-
* @remarks
|
|
4069
|
-
* `range` is the input {@link Range} CLAMPED to the file's bounds — when the requested
|
|
4070
|
-
* span reached past the end of the text, `range` reflects the trimmed span that was read,
|
|
4071
|
-
* never the original out-of-bounds request.
|
|
4072
|
-
*/
|
|
4073
|
-
export declare interface ReadResult {
|
|
4074
|
-
readonly content: string;
|
|
4075
|
-
/** The actual (clamped) range applied to produce `content`. */
|
|
4076
|
-
readonly range: Range;
|
|
4077
|
-
}
|
|
4078
|
-
|
|
4079
|
-
/**
|
|
4080
|
-
* Options for {@link WorkspaceInterface.replace} — how the `query` matches (the same axes
|
|
4081
|
-
* as {@link SearchOptions}).
|
|
4082
|
-
*
|
|
4083
|
-
* @param options - The replace options
|
|
4084
|
-
*
|
|
4085
|
-
* @remarks
|
|
4086
|
-
* - `regex` — treat `query` as a regular expression source rather than a literal substring; defaults to `false`.
|
|
4087
|
-
* - `exact` — match case-sensitively; defaults to `true`.
|
|
4088
|
-
* - `limit` — stop after this many replacements across all files; defaults to unlimited.
|
|
4089
|
-
*/
|
|
4090
|
-
export declare interface ReplaceOptions {
|
|
4091
|
-
readonly regex?: boolean;
|
|
4092
|
-
readonly exact?: boolean;
|
|
4093
|
-
readonly limit?: number;
|
|
4094
|
-
}
|
|
4095
|
-
|
|
4096
|
-
/**
|
|
4097
|
-
* The tally returned by {@link WorkspaceInterface.replace} — the `query` that ran, how
|
|
4098
|
-
* many occurrences were `replaced`, and the number of `files` changed.
|
|
4099
|
-
*/
|
|
4100
|
-
export declare interface ReplaceResult {
|
|
4101
|
-
readonly query: string;
|
|
4102
|
-
readonly replaced: number;
|
|
4103
|
-
readonly files: number;
|
|
4104
|
-
}
|
|
4105
|
-
|
|
4106
3256
|
/**
|
|
4107
3257
|
* The immutable per-run outcome value an {@link AgentInterface}'s loop replaces as it runs — the
|
|
4108
3258
|
* assembled value its `stream`'s `result` promise resolves into a settled
|
|
@@ -4219,7 +3369,7 @@ export declare interface ScopeConfiguration {
|
|
|
4219
3369
|
/**
|
|
4220
3370
|
* Allowed ACTIVE-workspace file `path`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed) —
|
|
4221
3371
|
* the filter {@link AgentContextInterface.build} applies to the active workspace's
|
|
4222
|
-
* {@link WorkspaceInterface.files} before rendering them (text → the system block, image →
|
|
3372
|
+
* {@link import('@orkestrel/workspace').WorkspaceInterface.files} before rendering them (text → the system block, image →
|
|
4223
3373
|
* the last user message).
|
|
4224
3374
|
*/
|
|
4225
3375
|
readonly files?: readonly string[];
|
|
@@ -4234,7 +3384,7 @@ export declare interface ScopeInput extends ScopeConfiguration {
|
|
|
4234
3384
|
}
|
|
4235
3385
|
|
|
4236
3386
|
/**
|
|
4237
|
-
* A named, immutable filter over a richer context's items — the
|
|
3387
|
+
* A named, immutable filter over a richer context's items — the three per-category
|
|
4238
3388
|
* allow-lists ({@link ScopeConfiguration}) plus an `id` / `name`, and a `narrow` that
|
|
4239
3389
|
* composes a tighter child by set-INTERSECTION.
|
|
4240
3390
|
*
|
|
@@ -4322,7 +3472,7 @@ export declare type ScopeManagerEventMap = {
|
|
|
4322
3472
|
* mints + stores one (never overwrites), `scopes()` lists them in insertion order.
|
|
4323
3473
|
*
|
|
4324
3474
|
* @remarks
|
|
4325
|
-
* - **Registry.** `create(input)` mints a scope (an `id` + the
|
|
3475
|
+
* - **Registry.** `create(input)` mints a scope (an `id` + the three allow-lists) and
|
|
4326
3476
|
* stores it; `count` is how many are stored. `scope(id)` looks one up; `scopes()` lists
|
|
4327
3477
|
* them in insertion order. (Keyed by minted `id`, not `name`, so two scopes may share a
|
|
4328
3478
|
* `name` and `create` always adds.)
|
|
@@ -4352,40 +3502,6 @@ export declare interface ScopeManagerOptions {
|
|
|
4352
3502
|
readonly error?: EmitterErrorHandler;
|
|
4353
3503
|
}
|
|
4354
3504
|
|
|
4355
|
-
/**
|
|
4356
|
-
* One hit from {@link WorkspaceInterface.search} — where the match was found and the line
|
|
4357
|
-
* that carried it.
|
|
4358
|
-
*
|
|
4359
|
-
* @remarks
|
|
4360
|
-
* `line` / `column` are 1-based (column `1` is the first character of the line); `length`
|
|
4361
|
-
* is the matched substring's length; `content` is the FULL line the match sits on (not
|
|
4362
|
-
* just the matched fragment), so a caller can render the hit in context.
|
|
4363
|
-
*/
|
|
4364
|
-
export declare interface SearchMatch {
|
|
4365
|
-
readonly path: string;
|
|
4366
|
-
readonly line: number;
|
|
4367
|
-
readonly column: number;
|
|
4368
|
-
readonly length: number;
|
|
4369
|
-
/** The full text of the line the match was found on. */
|
|
4370
|
-
readonly content: string;
|
|
4371
|
-
}
|
|
4372
|
-
|
|
4373
|
-
/**
|
|
4374
|
-
* Options for {@link WorkspaceInterface.search} — how the `query` matches.
|
|
4375
|
-
*
|
|
4376
|
-
* @param options - The search options
|
|
4377
|
-
*
|
|
4378
|
-
* @remarks
|
|
4379
|
-
* - `regex` — treat `query` as a regular expression source rather than a literal substring; defaults to `false`.
|
|
4380
|
-
* - `exact` — match case-sensitively; defaults to `true` (set `false` for a case-insensitive scan).
|
|
4381
|
-
* - `limit` — stop after this many matches across all files; defaults to unlimited.
|
|
4382
|
-
*/
|
|
4383
|
-
export declare interface SearchOptions {
|
|
4384
|
-
readonly regex?: boolean;
|
|
4385
|
-
readonly exact?: boolean;
|
|
4386
|
-
readonly limit?: number;
|
|
4387
|
-
}
|
|
4388
|
-
|
|
4389
3505
|
/**
|
|
4390
3506
|
* A slice of folded messages digested into a summary — the unit of compaction a
|
|
4391
3507
|
* {@link ConversationInterface} produces when it `compact`s its live tail.
|
|
@@ -4428,48 +3544,6 @@ export declare interface SectionInterface {
|
|
|
4428
3544
|
*/
|
|
4429
3545
|
export declare function settleAgentJob(agent: AgentInterface, allowPartial: boolean): Promise<AgentResult>;
|
|
4430
3546
|
|
|
4431
|
-
/**
|
|
4432
|
-
* Slice the substring of `text` spanned by a {@link Range} (start INCLUSIVE, end
|
|
4433
|
-
* EXCLUSIVE), clamping the range to the text's bounds first — the read half of the ranged
|
|
4434
|
-
* edit surface.
|
|
4435
|
-
*
|
|
4436
|
-
* @remarks
|
|
4437
|
-
* Clamps via {@link clampRange}, resolves each end to an offset via {@link offsetAt}, and
|
|
4438
|
-
* returns `text.slice(startOffset, endOffset)`. Total — never throws.
|
|
4439
|
-
*
|
|
4440
|
-
* @param text - The text to slice
|
|
4441
|
-
* @param range - The 1-based range to extract
|
|
4442
|
-
* @returns The spanned substring (empty when the clamped span is empty)
|
|
4443
|
-
*
|
|
4444
|
-
* @example
|
|
4445
|
-
* ```ts
|
|
4446
|
-
* sliceRange('hello\nworld', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }) // 'hello'
|
|
4447
|
-
* ```
|
|
4448
|
-
*/
|
|
4449
|
-
export declare function sliceRange(text: string, range: Range): string;
|
|
4450
|
-
|
|
4451
|
-
/**
|
|
4452
|
-
* Replace the span of `text` covered by a {@link Range} with `replacement` (start
|
|
4453
|
-
* INCLUSIVE, end EXCLUSIVE), clamping the range to the text's bounds first — the write
|
|
4454
|
-
* half of the ranged edit surface.
|
|
4455
|
-
*
|
|
4456
|
-
* @remarks
|
|
4457
|
-
* Clamps via {@link clampRange}, then stitches `before + replacement + after` around the
|
|
4458
|
-
* resolved offsets. An empty span (`start === end`) becomes a pure insertion. Total —
|
|
4459
|
-
* never throws.
|
|
4460
|
-
*
|
|
4461
|
-
* @param text - The original text
|
|
4462
|
-
* @param range - The 1-based range to overwrite
|
|
4463
|
-
* @param replacement - The text to splice in place of the spanned range
|
|
4464
|
-
* @returns The text with the spanned range replaced by `replacement`
|
|
4465
|
-
*
|
|
4466
|
-
* @example
|
|
4467
|
-
* ```ts
|
|
4468
|
-
* spliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }, 'bye') // 'bye'
|
|
4469
|
-
* ```
|
|
4470
|
-
*/
|
|
4471
|
-
export declare function spliceRange(text: string, range: Range, replacement: string): string;
|
|
4472
|
-
|
|
4473
3547
|
/**
|
|
4474
3548
|
* A live event stream paired with the eventual settled result and a cancel — the
|
|
4475
3549
|
* generic pull/streaming handle a long-running operation hands back.
|
|
@@ -4599,299 +3673,6 @@ export declare interface ThinkSplitterInterface {
|
|
|
4599
3673
|
flush(): string;
|
|
4600
3674
|
}
|
|
4601
3675
|
|
|
4602
|
-
/**
|
|
4603
|
-
* A registered tool — its {@link import('../types.js').ToolDefinition} schema (the
|
|
4604
|
-
* `name` / `description` / `parameters` the model sees) bound to the `execute`
|
|
4605
|
-
* handler that runs a call.
|
|
4606
|
-
*
|
|
4607
|
-
* @remarks
|
|
4608
|
-
* A thin value object: the constructor stores the schema fields and the handler, and
|
|
4609
|
-
* `execute` delegates to the handler verbatim. `parameters` is kept by reference (the
|
|
4610
|
-
* open JSON-Schema the provider forwards as-is) — not cloned. The handler's `args` is
|
|
4611
|
-
* the model-supplied `unknown` arguments record, narrowed inside the handler (§14);
|
|
4612
|
-
* isolating a throw is the {@link ToolManager}'s job, not this class's. Event-free —
|
|
4613
|
-
* no Emitter, no events.
|
|
4614
|
-
*
|
|
4615
|
-
* @example
|
|
4616
|
-
* ```ts
|
|
4617
|
-
* const tool = new Tool({
|
|
4618
|
-
* name: 'add',
|
|
4619
|
-
* description: 'Add two numbers',
|
|
4620
|
-
* parameters: { type: 'object', properties: { a: { type: 'number' }, b: { type: 'number' } } },
|
|
4621
|
-
* execute: (args) => Number(args.a) + Number(args.b),
|
|
4622
|
-
* })
|
|
4623
|
-
* ```
|
|
4624
|
-
*/
|
|
4625
|
-
export declare class Tool implements ToolInterface {
|
|
4626
|
-
#private;
|
|
4627
|
-
readonly name: string;
|
|
4628
|
-
readonly description?: string;
|
|
4629
|
-
readonly summary?: string;
|
|
4630
|
-
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
4631
|
-
constructor(options: ToolOptions);
|
|
4632
|
-
execute(args: Readonly<Record<string, unknown>>): Promise<unknown> | unknown;
|
|
4633
|
-
}
|
|
4634
|
-
|
|
4635
|
-
/**
|
|
4636
|
-
* A tool call the model emitted — the tool `name` and its parsed `arguments`.
|
|
4637
|
-
*
|
|
4638
|
-
* @remarks
|
|
4639
|
-
* `id` correlates the call with its later {@link ToolResult}; when the wire omits an
|
|
4640
|
-
* id the provider mints one (a random UUID) so every call is addressable. `arguments`
|
|
4641
|
-
* is always a record — the provider narrows the wire value (an object, or a JSON
|
|
4642
|
-
* string it parses) to one, defaulting to `{}` when neither.
|
|
4643
|
-
*/
|
|
4644
|
-
export declare interface ToolCall {
|
|
4645
|
-
readonly id: string;
|
|
4646
|
-
readonly name: string;
|
|
4647
|
-
readonly arguments: Readonly<Record<string, unknown>>;
|
|
4648
|
-
}
|
|
4649
|
-
|
|
4650
|
-
/**
|
|
4651
|
-
* The MCP `CallToolResult` shape a {@link ToolResult} maps to via {@link buildToolResult} —
|
|
4652
|
-
* `content` blocks plus an `isError` flag set ONLY on failure (never `false`).
|
|
4653
|
-
*/
|
|
4654
|
-
export declare interface ToolCallResult {
|
|
4655
|
-
readonly content: readonly ToolResultContent[];
|
|
4656
|
-
readonly isError?: true;
|
|
4657
|
-
}
|
|
4658
|
-
|
|
4659
|
-
/**
|
|
4660
|
-
* A tool the model may call — its name, an optional description, and an optional
|
|
4661
|
-
* JSON-Schema `parameters` object describing its arguments.
|
|
4662
|
-
*
|
|
4663
|
-
* @remarks
|
|
4664
|
-
* Passed to a {@link ProviderInterface}'s `generate` / `stream`; the provider maps
|
|
4665
|
-
* each into the wire's function-tool shape. `parameters` is an open JSON-Schema
|
|
4666
|
-
* record (the provider forwards it verbatim).
|
|
4667
|
-
*/
|
|
4668
|
-
export declare interface ToolDefinition {
|
|
4669
|
-
readonly name: string;
|
|
4670
|
-
readonly description?: string;
|
|
4671
|
-
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
4672
|
-
}
|
|
4673
|
-
|
|
4674
|
-
/**
|
|
4675
|
-
* A registered tool: its {@link ToolDefinition} (the schema the model sees) plus the
|
|
4676
|
-
* handler that runs a call.
|
|
4677
|
-
*
|
|
4678
|
-
* @remarks
|
|
4679
|
-
* The definition fields (`name` / `description` / `parameters`) are what a
|
|
4680
|
-
* {@link ProviderInterface} advertises to the model; `execute` is the local handler a
|
|
4681
|
-
* {@link ToolManagerInterface} invokes when the model calls the tool. The handler's
|
|
4682
|
-
* `args` is the model-supplied `unknown` JSON object — narrow it inside the handler
|
|
4683
|
-
* (§14), never assert; the manager isolates a throw into a {@link ToolResult} `error`.
|
|
4684
|
-
*/
|
|
4685
|
-
export declare interface ToolInterface extends ToolDefinition {
|
|
4686
|
-
/**
|
|
4687
|
-
* A one-or-two-sentence concise description advertised to the model IN PLACE of the
|
|
4688
|
-
* full `description` (which stays on the tool for on-demand retrieval, e.g. a
|
|
4689
|
-
* describe tool); absent ⇒ the full `description` is advertised exactly as today.
|
|
4690
|
-
*/
|
|
4691
|
-
readonly summary?: string;
|
|
4692
|
-
/**
|
|
4693
|
-
* Run the tool. `args` is the model-supplied `unknown` JSON object — narrow it
|
|
4694
|
-
* inside (§14); the manager isolates a throw into a {@link ToolResult} `error`.
|
|
4695
|
-
*
|
|
4696
|
-
* @param args - The model-supplied arguments record (an open `unknown` object)
|
|
4697
|
-
* @returns The tool's result (sync or async) — folded into a `ToolResult.value`
|
|
4698
|
-
*/
|
|
4699
|
-
execute(args: Readonly<Record<string, unknown>>): Promise<unknown> | unknown;
|
|
4700
|
-
}
|
|
4701
|
-
|
|
4702
|
-
/**
|
|
4703
|
-
* The tool registry the agent loop dispatches model tool-calls through — resolves
|
|
4704
|
-
* names, lists {@link ToolDefinition}s for the provider, and executes calls with
|
|
4705
|
-
* per-call error isolation.
|
|
4706
|
-
*
|
|
4707
|
-
* @remarks
|
|
4708
|
-
* - **Registry.** Tools live in an insertion-ordered `Map` keyed by `tool.name`;
|
|
4709
|
-
* `add` takes one or a batch (§9.2) and a re-`add` of the same name OVERWRITES it
|
|
4710
|
-
* (last write wins). `count` is the map size, `tool(name)` looks one up, `tools()`
|
|
4711
|
-
* lists them in insertion order, and `definitions()` maps each to a plain
|
|
4712
|
-
* {@link ToolDefinition} (`name` / `description?` / `parameters?`, the `execute`
|
|
4713
|
-
* handler stripped) — exactly what a provider advertises to the model, with
|
|
4714
|
-
* `tool.summary ?? tool.description` advertised as `description` (a lean `summary`
|
|
4715
|
-
* stands in for the full text when set).
|
|
4716
|
-
* - **Per-call error isolation (the load-bearing part).** `execute` resolves a
|
|
4717
|
-
* {@link ToolCall}'s tool by name and ALWAYS resolves a {@link ToolResult}: an
|
|
4718
|
-
* unknown name → `{ id, name, error: 'tool not found: <name>' }`; a successful run →
|
|
4719
|
-
* `{ id, name, value }`; a handler throw is CAUGHT into `{ id, name, error }` (an
|
|
4720
|
-
* `Error`'s message, else the stringified throw). A tool throw never escapes — it
|
|
4721
|
-
* becomes a result the model can react to.
|
|
4722
|
-
* - **Batch never fails as a whole.** `execute(calls)` runs every call via
|
|
4723
|
-
* `Promise.all(calls.map(...))` and resolves the results correlated by `id` in the
|
|
4724
|
-
* input order — a mix of success, throw, and not-found all resolve; one bad call
|
|
4725
|
-
* does not reject the batch.
|
|
4726
|
-
* - **Event-free.** A purely functional registry — no Emitter, no events.
|
|
4727
|
-
*
|
|
4728
|
-
* @example
|
|
4729
|
-
* ```ts
|
|
4730
|
-
* const manager = new ToolManager()
|
|
4731
|
-
* manager.add(new Tool({ name: 'add', execute: (a) => Number(a.x) + Number(a.y) }))
|
|
4732
|
-
* const result = await manager.execute({ id: '1', name: 'add', arguments: { x: 1, y: 2 } })
|
|
4733
|
-
* result.value // 3
|
|
4734
|
-
* ```
|
|
4735
|
-
*/
|
|
4736
|
-
export declare class ToolManager implements ToolManagerInterface {
|
|
4737
|
-
#private;
|
|
4738
|
-
get count(): number;
|
|
4739
|
-
add(tool: ToolInterface): void;
|
|
4740
|
-
add(tools: readonly ToolInterface[]): void;
|
|
4741
|
-
tool(name: string): ToolInterface | undefined;
|
|
4742
|
-
tools(): readonly ToolInterface[];
|
|
4743
|
-
definitions(): readonly ToolDefinition[];
|
|
4744
|
-
execute(call: ToolCall): Promise<ToolResult>;
|
|
4745
|
-
execute(calls: readonly ToolCall[]): Promise<readonly ToolResult[]>;
|
|
4746
|
-
remove(name: string): boolean;
|
|
4747
|
-
remove(names: readonly string[]): boolean;
|
|
4748
|
-
clear(): void;
|
|
4749
|
-
}
|
|
4750
|
-
|
|
4751
|
-
/**
|
|
4752
|
-
* A registry of tools — resolves names, lists definitions for the provider, and
|
|
4753
|
-
* executes calls with per-call error isolation.
|
|
4754
|
-
*
|
|
4755
|
-
* @remarks
|
|
4756
|
-
* - **Registry.** `add` registers one tool or a batch (§9.2), keyed by `tool.name`
|
|
4757
|
-
* (a re-`add` of the same name overwrites — last write wins); `count` is the number
|
|
4758
|
-
* registered. `tool(name)` looks one up; `tools()` lists them in insertion order;
|
|
4759
|
-
* `definitions()` strips each to a plain {@link ToolDefinition} for the provider,
|
|
4760
|
-
* advertising `tool.summary ?? tool.description` in the definition's `description`
|
|
4761
|
-
* field — a lean `summary` stands in for the full `description` when set.
|
|
4762
|
-
* - **Per-call error isolation.** `execute` resolves a {@link ToolCall}'s tool by name
|
|
4763
|
-
* and runs it, ALWAYS resolving a {@link ToolResult}: a success carries `value`, a
|
|
4764
|
-
* handler throw is caught into `error`, and an unknown name becomes a not-found
|
|
4765
|
-
* `error`. A tool throw NEVER escapes — it becomes a result the model can react to.
|
|
4766
|
-
* - **Batch never fails as a whole.** The array `execute` runs every call (via
|
|
4767
|
-
* `Promise.all`) and resolves results correlated by `id` in order — one bad call
|
|
4768
|
-
* (throw or not-found) does not fail the batch.
|
|
4769
|
-
* - **Event-free.** A purely functional registry — no Emitter, no events.
|
|
4770
|
-
*/
|
|
4771
|
-
export declare interface ToolManagerInterface {
|
|
4772
|
-
readonly count: number;
|
|
4773
|
-
add(tool: ToolInterface): void;
|
|
4774
|
-
add(tools: readonly ToolInterface[]): void;
|
|
4775
|
-
tool(name: string): ToolInterface | undefined;
|
|
4776
|
-
tools(): readonly ToolInterface[];
|
|
4777
|
-
definitions(): readonly ToolDefinition[];
|
|
4778
|
-
execute(call: ToolCall): Promise<ToolResult>;
|
|
4779
|
-
execute(calls: readonly ToolCall[]): Promise<readonly ToolResult[]>;
|
|
4780
|
-
remove(name: string): boolean;
|
|
4781
|
-
remove(names: readonly string[]): boolean;
|
|
4782
|
-
clear(): void;
|
|
4783
|
-
}
|
|
4784
|
-
|
|
4785
|
-
/**
|
|
4786
|
-
* Options for `createTool` — the schema the model sees (`name` / `description` /
|
|
4787
|
-
* `parameters`) plus the `execute` handler that runs a call.
|
|
4788
|
-
*
|
|
4789
|
-
* @remarks
|
|
4790
|
-
* `name` is required (it keys the tool in a {@link ToolManagerInterface} and is what
|
|
4791
|
-
* the model calls); `description` and `parameters` are the optional JSON-Schema the
|
|
4792
|
-
* provider advertises (forwarded verbatim). `summary`, when set, is a lean
|
|
4793
|
-
* one-or-two-sentence advertisement used IN PLACE of `description` in a
|
|
4794
|
-
* {@link ToolManagerInterface.definitions} listing — `description` stays available on
|
|
4795
|
-
* the tool for on-demand retrieval. `execute` receives the model-supplied arguments
|
|
4796
|
-
* record and returns the tool's result (sync or async).
|
|
4797
|
-
*/
|
|
4798
|
-
export declare interface ToolOptions {
|
|
4799
|
-
readonly name: string;
|
|
4800
|
-
readonly description?: string;
|
|
4801
|
-
readonly summary?: string;
|
|
4802
|
-
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
4803
|
-
readonly execute: (args: Readonly<Record<string, unknown>>) => Promise<unknown> | unknown;
|
|
4804
|
-
}
|
|
4805
|
-
|
|
4806
|
-
/**
|
|
4807
|
-
* The outcome of executing a {@link ToolCall} — keyed back to the call by `id` and
|
|
4808
|
-
* `name`, carrying either a `value` (the result) or an `error` string (the failure).
|
|
4809
|
-
*/
|
|
4810
|
-
export declare interface ToolResult {
|
|
4811
|
-
readonly id: string;
|
|
4812
|
-
readonly name: string;
|
|
4813
|
-
readonly value?: unknown;
|
|
4814
|
-
readonly error?: string;
|
|
4815
|
-
}
|
|
4816
|
-
|
|
4817
|
-
/**
|
|
4818
|
-
* One block of an MCP-shaped tool call response — plain text, the only content kind
|
|
4819
|
-
* {@link buildToolResult} emits.
|
|
4820
|
-
*/
|
|
4821
|
-
export declare interface ToolResultContent {
|
|
4822
|
-
readonly type: 'text';
|
|
4823
|
-
readonly text: string;
|
|
4824
|
-
}
|
|
4825
|
-
|
|
4826
|
-
/**
|
|
4827
|
-
* A mutable, `path`-keyed working set of immutable {@link FileInterface}s — the
|
|
4828
|
-
* in-memory editing surface over the file primitive.
|
|
4829
|
-
*
|
|
4830
|
-
* @remarks
|
|
4831
|
-
* - **Registry.** Files live in an insertion-ordered `Map` keyed by `path`; `count` is the
|
|
4832
|
-
* map size, `file(path)` looks one up, and `files()` lists them in insertion order.
|
|
4833
|
-
* - **Write replaces the File (§11 immutability).** Every edit MINTS a replacement
|
|
4834
|
-
* {@link FileInterface} (via {@link import('../factories.js').createFile}) rather than
|
|
4835
|
-
* mutating in place, transitioning `state` to `'created'` for a brand-new path or
|
|
4836
|
-
* `'modified'` for an existing one. A whole-file string write preserves an existing text
|
|
4837
|
-
* file's `language`, else infers it from the `path` (`inferLanguage`); writing a string
|
|
4838
|
-
* onto an existing BINARY path replaces it with a text file (a deliberate retype). A
|
|
4839
|
-
* ranged `write` splices a `Range` of an existing text file.
|
|
4840
|
-
* - **Modality rules.** Text-only ops on a binary file are rejected: a ranged `read` /
|
|
4841
|
-
* `write`, `prepend`, and `append` throw `MODALITY`; a plain `read(path)` of a binary
|
|
4842
|
-
* file returns `undefined`; `search` / `replace` skip binary files (0 matches).
|
|
4843
|
-
* - **In-memory removal.** `remove(path)` / `remove(paths)` drop files outright (no
|
|
4844
|
-
* tombstone — the `'loaded'` / `'deleted'` states are reserved for a future FileStore);
|
|
4845
|
-
* `remove()` and `clear()` both empty the registry and emit the single `clear` signal.
|
|
4846
|
-
* The disk/sync lifecycle (`load` / `revert` / `accept` / `purge` / `dirty`) is NOT part
|
|
4847
|
-
* of this surface.
|
|
4848
|
-
* - **Observable (§13).** The owned {@link emitter} ({@link WorkspaceEventMap}) carries
|
|
4849
|
-
* `write` (the resulting file) / `remove` (the path) / `move` (`{ from, to }`) / `clear`.
|
|
4850
|
-
* Every event is emitted directly, strictly AFTER the map mutation completes; the
|
|
4851
|
-
* emitter isolates a listener throw and routes it to its `error` handler, so a buggy
|
|
4852
|
-
* observer can never corrupt a mutation.
|
|
4853
|
-
*
|
|
4854
|
-
* @example
|
|
4855
|
-
* ```ts
|
|
4856
|
-
* const workspace = new Workspace()
|
|
4857
|
-
* workspace.write('src/main.ts', 'const x = 1')
|
|
4858
|
-
* workspace.file('src/main.ts')?.state // 'created'
|
|
4859
|
-
* workspace.append('src/main.ts', '\nconst y = 2')
|
|
4860
|
-
* workspace.file('src/main.ts')?.state // 'modified'
|
|
4861
|
-
* workspace.read('src/main.ts') // 'const x = 1\nconst y = 2'
|
|
4862
|
-
* ```
|
|
4863
|
-
*/
|
|
4864
|
-
export declare class Workspace implements WorkspaceInterface {
|
|
4865
|
-
#private;
|
|
4866
|
-
constructor(options?: WorkspaceOptions, seed?: Iterable<readonly [string, FileInterface]>);
|
|
4867
|
-
get id(): string;
|
|
4868
|
-
get emitter(): EmitterInterface<WorkspaceEventMap>;
|
|
4869
|
-
get count(): number;
|
|
4870
|
-
file(path: string): FileInterface | undefined;
|
|
4871
|
-
files(): readonly FileInterface[];
|
|
4872
|
-
read(path: string): string | undefined;
|
|
4873
|
-
read(path: string, range: Range): ReadResult | undefined;
|
|
4874
|
-
read(paths: readonly string[]): Readonly<Record<string, string>>;
|
|
4875
|
-
has(path: string): boolean;
|
|
4876
|
-
has(paths: readonly string[]): boolean;
|
|
4877
|
-
search(query: string, options?: SearchOptions): readonly SearchMatch[];
|
|
4878
|
-
replace(query: string, replacement: string, options?: ReplaceOptions): ReplaceResult;
|
|
4879
|
-
write(path: string, content: string): void;
|
|
4880
|
-
write(path: string, content: string, range: Range): void;
|
|
4881
|
-
write(files: Readonly<Record<string, string>>): void;
|
|
4882
|
-
prepend(path: string, content: string): void;
|
|
4883
|
-
prepend(files: Readonly<Record<string, string>>): void;
|
|
4884
|
-
append(path: string, content: string): void;
|
|
4885
|
-
append(files: Readonly<Record<string, string>>): void;
|
|
4886
|
-
move(from: string, to: string): boolean;
|
|
4887
|
-
move(mapping: Readonly<Record<string, string>>): boolean;
|
|
4888
|
-
remove(): void;
|
|
4889
|
-
remove(path: string): boolean;
|
|
4890
|
-
remove(paths: readonly string[]): boolean;
|
|
4891
|
-
clear(): void;
|
|
4892
|
-
snapshot(): WorkspaceSnapshot;
|
|
4893
|
-
}
|
|
4894
|
-
|
|
4895
3676
|
/**
|
|
4896
3677
|
* The section header {@link import('./AgentContext.js').AgentContext}'s `build()` renders the
|
|
4897
3678
|
* ACTIVE workspace's TEXT files under — the leading line of the dedicated workspace block in the
|
|
@@ -4906,393 +3687,4 @@ export declare class Workspace implements WorkspaceInterface {
|
|
|
4906
3687
|
*/
|
|
4907
3688
|
export declare const WORKSPACE_SECTION_HEADER = "## Workspace";
|
|
4908
3689
|
|
|
4909
|
-
/**
|
|
4910
|
-
* An error thrown by the in-memory {@link import('./workspaces/Workspace.js').Workspace} edit
|
|
4911
|
-
* surface.
|
|
4912
|
-
*
|
|
4913
|
-
* @remarks
|
|
4914
|
-
* Carries a {@link WorkspaceErrorCode} and an optional `context` bag naming the offending
|
|
4915
|
-
* path / range. Thrown for a text-only operation aimed at an image file (`MODALITY` — a
|
|
4916
|
-
* ranged read / write, `prepend`, or `append`), an invalid `search` / `replace` regular
|
|
4917
|
-
* expression (`PATTERN`), and a structurally invalid ranged-write {@link import('./types.js').Range}
|
|
4918
|
-
* (`RANGE` — inverted, or a sub-1 line / column).
|
|
4919
|
-
*/
|
|
4920
|
-
export declare class WorkspaceError extends Error {
|
|
4921
|
-
readonly code: WorkspaceErrorCode;
|
|
4922
|
-
readonly context?: Readonly<Record<string, unknown>>;
|
|
4923
|
-
constructor(code: WorkspaceErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
|
|
4924
|
-
}
|
|
4925
|
-
|
|
4926
|
-
/**
|
|
4927
|
-
* The machine-readable code a {@link import('./errors.js').WorkspaceError} carries
|
|
4928
|
-
* (AGENTS §12) — a `catch` branches on `error.code` instead of parsing the message.
|
|
4929
|
-
*
|
|
4930
|
-
* @remarks
|
|
4931
|
-
* - `MODALITY` — a text-only op (ranged read/write, `prepend`, `append`) was aimed at a binary file.
|
|
4932
|
-
* - `PATTERN` — a `search` / `replace` `query` was an invalid regular expression (with `regex: true`).
|
|
4933
|
-
* - `RANGE` — a ranged `write` got a structurally invalid {@link Range} (inverted, or a sub-1 line/column).
|
|
4934
|
-
* - `TOOL` — a handler-level validation fault raised by a workspace-editing tool boundary (see
|
|
4935
|
-
* `@orkestrel/tool`) when the agent-supplied args were malformed / unknown. Distinct from the
|
|
4936
|
-
* surface faults above (which the live workspace raises) — this is the tool boundary rejecting an
|
|
4937
|
-
* un-parseable operation before any workspace call.
|
|
4938
|
-
*/
|
|
4939
|
-
export declare type WorkspaceErrorCode = 'MODALITY' | 'PATTERN' | 'RANGE' | 'TOOL';
|
|
4940
|
-
|
|
4941
|
-
/**
|
|
4942
|
-
* The observable events a {@link import('./workspaces/Workspace.js').Workspace} emits
|
|
4943
|
-
* (AGENTS §13) — each fired AFTER the corresponding mutation completes.
|
|
4944
|
-
*
|
|
4945
|
-
* @remarks
|
|
4946
|
-
* - `write` — a file was written / edited, carrying the resulting {@link FileInterface}.
|
|
4947
|
-
* - `remove` — a single file was dropped, carrying its `path`.
|
|
4948
|
-
* - `move` — a file was re-keyed, carrying `{ from, to }`.
|
|
4949
|
-
* - `clear` — the workspace was emptied (the canonical "emptied" signal, fired by both `remove()` and `clear()`).
|
|
4950
|
-
*/
|
|
4951
|
-
export declare type WorkspaceEventMap = {
|
|
4952
|
-
readonly write: readonly [file: FileInterface];
|
|
4953
|
-
readonly remove: readonly [path: string];
|
|
4954
|
-
readonly move: readonly [move: {
|
|
4955
|
-
readonly from: string;
|
|
4956
|
-
readonly to: string;
|
|
4957
|
-
}];
|
|
4958
|
-
readonly clear: readonly [];
|
|
4959
|
-
};
|
|
4960
|
-
|
|
4961
|
-
/**
|
|
4962
|
-
* The data to author a {@link WorkspaceInterface} through a
|
|
4963
|
-
* {@link WorkspaceManagerInterface} — the optional `id`, the reserved `on` hooks + `error`
|
|
4964
|
-
* handler (§13), and an optional `seed` of initial files.
|
|
4965
|
-
*
|
|
4966
|
-
* @remarks
|
|
4967
|
-
* `id` is the workspace's identity (minted when omitted). `on` / `error` are the §8/§13
|
|
4968
|
-
* keys (initial {@link WorkspaceEventMap} listeners + the listener-error handler), flowing
|
|
4969
|
-
* the manager's defaults in unless overridden. `seed` is the construction-time hydration
|
|
4970
|
-
* seam (path → {@link FileInterface}) — the only way to seat a non-text (binary) file, and
|
|
4971
|
-
* what a future FileStore reads a snapshot into; seeding is silent (no `write` events).
|
|
4972
|
-
*/
|
|
4973
|
-
export declare interface WorkspaceInput {
|
|
4974
|
-
readonly id?: string;
|
|
4975
|
-
readonly on?: EmitterHooks<WorkspaceEventMap>;
|
|
4976
|
-
readonly error?: EmitterErrorHandler;
|
|
4977
|
-
/** Pre-seeded initial files (path → File), placed silently at construction. */
|
|
4978
|
-
readonly seed?: Iterable<readonly [string, FileInterface]>;
|
|
4979
|
-
}
|
|
4980
|
-
|
|
4981
|
-
/**
|
|
4982
|
-
* A mutable, `path`-keyed working set of immutable {@link FileInterface}s — the in-memory
|
|
4983
|
-
* editing surface over the file primitive.
|
|
4984
|
-
*
|
|
4985
|
-
* @remarks
|
|
4986
|
-
* Files live in an insertion-ordered map keyed by `path`. Every edit REPLACES the
|
|
4987
|
-
* immutable {@link FileInterface} at a path with a new one (transitioning its `state` to
|
|
4988
|
-
* `'created'` for a fresh path or `'modified'` for an existing one) rather than mutating in
|
|
4989
|
-
* place. The disk/sync lifecycle (`load` / `revert` / `accept` / `purge` / `dirty`) is
|
|
4990
|
-
* deliberately NOT part of this surface — it is deferred to a future FileStore. Text-only
|
|
4991
|
-
* operations on a binary file are governed by the modality rules (a ranged read/write,
|
|
4992
|
-
* `prepend`, and `append` throw `MODALITY`; a plain `read` returns `undefined`; `search` /
|
|
4993
|
-
* `replace` skip the file). Observe mutations through the owned {@link emitter} (AGENTS §13).
|
|
4994
|
-
*/
|
|
4995
|
-
export declare interface WorkspaceInterface {
|
|
4996
|
-
/** The workspace's identity — its key in a {@link WorkspaceManagerInterface}; minted when not supplied. */
|
|
4997
|
-
readonly id: string;
|
|
4998
|
-
/** The push observation surface (AGENTS §13) — `write` / `remove` / `move` / `clear`. */
|
|
4999
|
-
readonly emitter: EmitterInterface<WorkspaceEventMap>;
|
|
5000
|
-
/** The number of files currently held. */
|
|
5001
|
-
readonly count: number;
|
|
5002
|
-
/** Look up one file by path, or `undefined` when absent. */
|
|
5003
|
-
file(path: string): FileInterface | undefined;
|
|
5004
|
-
/** List every file in insertion order. */
|
|
5005
|
-
files(): readonly FileInterface[];
|
|
5006
|
-
read(path: string): string | undefined;
|
|
5007
|
-
read(path: string, range: Range): ReadResult | undefined;
|
|
5008
|
-
read(paths: readonly string[]): Readonly<Record<string, string>>;
|
|
5009
|
-
has(path: string): boolean;
|
|
5010
|
-
has(paths: readonly string[]): boolean;
|
|
5011
|
-
/** Scan every text file's lines for `query`, returning each hit in insertion order. */
|
|
5012
|
-
search(query: string, options?: SearchOptions): readonly SearchMatch[];
|
|
5013
|
-
/** Replace `query` with `replacement` across every text file, returning the tally. */
|
|
5014
|
-
replace(query: string, replacement: string, options?: ReplaceOptions): ReplaceResult;
|
|
5015
|
-
write(path: string, content: string): void;
|
|
5016
|
-
write(path: string, content: string, range: Range): void;
|
|
5017
|
-
write(files: Readonly<Record<string, string>>): void;
|
|
5018
|
-
prepend(path: string, content: string): void;
|
|
5019
|
-
prepend(files: Readonly<Record<string, string>>): void;
|
|
5020
|
-
append(path: string, content: string): void;
|
|
5021
|
-
append(files: Readonly<Record<string, string>>): void;
|
|
5022
|
-
move(from: string, to: string): boolean;
|
|
5023
|
-
move(mapping: Readonly<Record<string, string>>): boolean;
|
|
5024
|
-
remove(): void;
|
|
5025
|
-
remove(path: string): boolean;
|
|
5026
|
-
remove(paths: readonly string[]): boolean;
|
|
5027
|
-
/** Empty the workspace (emits `clear`). */
|
|
5028
|
-
clear(): void;
|
|
5029
|
-
/**
|
|
5030
|
-
* Serialize this workspace to a plain, JSON-serializable {@link WorkspaceSnapshot} — its
|
|
5031
|
-
* `id` plus a flat list of its {@link FileInterface}s (each already carries its `path`).
|
|
5032
|
-
*
|
|
5033
|
-
* @remarks
|
|
5034
|
-
* The container serializes ITSELF (`{ id: this.id, files: this.files() }`) — the
|
|
5035
|
-
* {@link WorkspaceStoreInterface} persistence seam's payload, paralleling the
|
|
5036
|
-
* {@link ConversationInterface}'s own snapshot a later track adds. The snapshot is the
|
|
5037
|
-
* durable analogue of the constructor `seed`: a {@link WorkspaceManagerInterface} HYDRATES a
|
|
5038
|
-
* workspace from `snapshot.files` through that seam (see {@link WorkspaceManagerInterface.open}).
|
|
5039
|
-
* Pure — the `File`s are already frozen plain records (so the snapshot `structuredClone`s /
|
|
5040
|
-
* JSON-round-trips losslessly), and snapshotting mutates nothing.
|
|
5041
|
-
*
|
|
5042
|
-
* @returns The {@link WorkspaceSnapshot} (`{ id, files }`)
|
|
5043
|
-
*/
|
|
5044
|
-
snapshot(): WorkspaceSnapshot;
|
|
5045
|
-
}
|
|
5046
|
-
|
|
5047
|
-
/**
|
|
5048
|
-
* The registry of {@link Workspace}s keyed by `id`, in insertion order, WITH an active pointer
|
|
5049
|
-
* — the §9 store over the workspace layer PLUS the `active` / `switch` seam the context renders.
|
|
5050
|
-
* Event-free (a registry, like {@link ConversationManager}); the observability lives on each
|
|
5051
|
-
* {@link Workspace}.
|
|
5052
|
-
*
|
|
5053
|
-
* @remarks
|
|
5054
|
-
* - **Registry.** Workspaces live in an insertion-ordered `Map` keyed by `id`. `add(input?)`
|
|
5055
|
-
* mints a {@link Workspace} (its `id` from `input` or `crypto.randomUUID()`), flowing the
|
|
5056
|
-
* manager's default `on` / `error` in unless the `input` OVERRIDES them, and stores it (an
|
|
5057
|
-
* already-present `id` OVERWRITES — last write wins). `count` is the map size, `workspace(id)`
|
|
5058
|
-
* looks one up, `workspaces()` lists them in insertion order.
|
|
5059
|
-
* - **Active pointer.** `active` is the active workspace (what the context renders), `undefined`
|
|
5060
|
-
* until the FIRST `add` (which auto-activates it — a registry with workspaces always has one
|
|
5061
|
-
* active). A subsequent `add` leaves `active` unchanged. `switch(id)` re-points `active` to the
|
|
5062
|
-
* workspace with `id` and returns it; an unknown `id` returns `undefined` and leaves `active`
|
|
5063
|
-
* unchanged (the lenient lookup style — never throws, no new error code).
|
|
5064
|
-
* - **Removal.** `remove` drops one by id, or a batch (§9.2) — `true` when any was removed;
|
|
5065
|
-
* removing the ACTIVE workspace sets `active` to `undefined`. `clear` empties the registry and
|
|
5066
|
-
* sets `active` to `undefined`.
|
|
5067
|
-
* - **Durable open / save (the optional `store`).** With a {@link WorkspaceStoreInterface} supplied
|
|
5068
|
-
* (the `store` option), `open(id)` HYDRATES a workspace on a registry miss — it `store.get(id)`s
|
|
5069
|
-
* the snapshot and rebuilds a fresh {@link Workspace} through the constructor `seed`
|
|
5070
|
-
* (`snapshot.files` → path → File), then activates it — and `save(id)` PERSISTS a registered
|
|
5071
|
-
* workspace's `snapshot()`. Both are LENIENT without a store (open resolves only registered ids,
|
|
5072
|
-
* save is a no-op `false`), consistent with the lenient `switch`.
|
|
5073
|
-
* - **Event-free.** A purely registry store — no Emitter, no events (each workspace owns its own
|
|
5074
|
-
* observable `emitter`).
|
|
5075
|
-
*
|
|
5076
|
-
* @example
|
|
5077
|
-
* ```ts
|
|
5078
|
-
* const manager = new WorkspaceManager()
|
|
5079
|
-
* const first = manager.add() // auto-activates — active === first
|
|
5080
|
-
* manager.add({ id: 'scratch' }) // leaves active unchanged
|
|
5081
|
-
* manager.switch('scratch') // re-points active to the 'scratch' workspace
|
|
5082
|
-
* manager.count // 2
|
|
5083
|
-
* ```
|
|
5084
|
-
*/
|
|
5085
|
-
export declare class WorkspaceManager implements WorkspaceManagerInterface {
|
|
5086
|
-
#private;
|
|
5087
|
-
constructor(options?: WorkspaceManagerOptions);
|
|
5088
|
-
get count(): number;
|
|
5089
|
-
get active(): WorkspaceInterface | undefined;
|
|
5090
|
-
workspace(id: string): WorkspaceInterface | undefined;
|
|
5091
|
-
workspaces(): readonly WorkspaceInterface[];
|
|
5092
|
-
add(input?: WorkspaceInput): WorkspaceInterface;
|
|
5093
|
-
switch(id: string): WorkspaceInterface | undefined;
|
|
5094
|
-
open(id: string): Promise<WorkspaceInterface | undefined>;
|
|
5095
|
-
save(id: string): Promise<boolean>;
|
|
5096
|
-
remove(ids: readonly string[]): boolean;
|
|
5097
|
-
remove(id: string): boolean;
|
|
5098
|
-
clear(): void;
|
|
5099
|
-
}
|
|
5100
|
-
|
|
5101
|
-
/**
|
|
5102
|
-
* A registry of {@link WorkspaceInterface}s keyed by their `id`, in insertion order, WITH an
|
|
5103
|
-
* active pointer — the §9 store over the workspace layer PLUS the `active` / `switch` seam the
|
|
5104
|
-
* context renders. Event-free (each {@link WorkspaceInterface} owns its own `emitter`).
|
|
5105
|
-
*
|
|
5106
|
-
* @remarks
|
|
5107
|
-
* - **Registry.** `count` is how many are stored. `add(input?)` mints a
|
|
5108
|
-
* {@link WorkspaceInterface} (its `id` from `input` or a random UUID), flowing the manager's
|
|
5109
|
-
* default `on` / `error` in unless the `input` overrides them; `add` of an already-present
|
|
5110
|
-
* `id` OVERWRITES it (last write wins). `workspace(id)` looks one up (`undefined` when
|
|
5111
|
-
* absent); `workspaces()` lists them in insertion order.
|
|
5112
|
-
* - **Active pointer.** `active` is the active workspace (what the context renders), `undefined`
|
|
5113
|
-
* until the FIRST `add` (which auto-activates it). A later `add` leaves `active` unchanged.
|
|
5114
|
-
* `switch(id)` re-points `active` to the workspace with `id` and returns it; an unknown `id`
|
|
5115
|
-
* returns `undefined` and leaves `active` unchanged (the lenient lookup style — never throws).
|
|
5116
|
-
* - **Removal.** `remove` drops one by id, or a batch (§9.2, array overload FIRST) — `true`
|
|
5117
|
-
* when any was removed; removing the ACTIVE workspace sets `active` to `undefined`. `clear`
|
|
5118
|
-
* empties the registry and sets `active` to `undefined`.
|
|
5119
|
-
* - **Durable open / save (the optional `store` seam).** When a {@link WorkspaceStoreInterface}
|
|
5120
|
-
* is supplied (the `store` option), `open(id)` HYDRATES a workspace from the store on a registry
|
|
5121
|
-
* miss (rebuilding it through the constructor `seed` from `snapshot.files`) and `save(id)`
|
|
5122
|
-
* PERSISTS a registered workspace's {@link WorkspaceInterface.snapshot}. Both are LENIENT without
|
|
5123
|
-
* a store — `open` resolves only registered ids, `save` is a no-op (`false`) — consistent with
|
|
5124
|
-
* the lenient `switch`.
|
|
5125
|
-
* - **Event-free.** A purely registry store — no Emitter, no events (each workspace owns its own).
|
|
5126
|
-
*/
|
|
5127
|
-
export declare interface WorkspaceManagerInterface {
|
|
5128
|
-
readonly count: number;
|
|
5129
|
-
/** The active workspace — what the context renders; `undefined` until the first `add`. */
|
|
5130
|
-
readonly active: WorkspaceInterface | undefined;
|
|
5131
|
-
workspace(id: string): WorkspaceInterface | undefined;
|
|
5132
|
-
workspaces(): readonly WorkspaceInterface[];
|
|
5133
|
-
add(input?: WorkspaceInput): WorkspaceInterface;
|
|
5134
|
-
switch(id: string): WorkspaceInterface | undefined;
|
|
5135
|
-
/**
|
|
5136
|
-
* Resolve a workspace by id, ACTIVATING it — from the registry if present, else HYDRATED from
|
|
5137
|
-
* the optional {@link WorkspaceStoreInterface} (`store`).
|
|
5138
|
-
*
|
|
5139
|
-
* @remarks
|
|
5140
|
-
* - If `id` is ALREADY registered, it is ACTIVATED (`switch`ed to) and returned — no store hit.
|
|
5141
|
-
* - Else if a `store` is set, `store.get(id)` is awaited; on a HIT the snapshot is rehydrated
|
|
5142
|
-
* into a fresh {@link WorkspaceInterface} through the constructor `seed`
|
|
5143
|
-
* (`add({ id, seed: snapshot.files.map((file) => [file.path, file]) })`), which registers AND
|
|
5144
|
-
* auto-activates it (or activates it explicitly), and it is returned.
|
|
5145
|
-
* - Else (no store, or a store MISS) ⇒ `undefined` (lenient — no throw).
|
|
5146
|
-
*
|
|
5147
|
-
* @param id - The workspace id to open
|
|
5148
|
-
* @returns The activated {@link WorkspaceInterface}, or `undefined` when neither registered nor stored
|
|
5149
|
-
*/
|
|
5150
|
-
open(id: string): Promise<WorkspaceInterface | undefined>;
|
|
5151
|
-
/**
|
|
5152
|
-
* Persist a REGISTERED workspace's {@link WorkspaceInterface.snapshot} to the optional
|
|
5153
|
-
* {@link WorkspaceStoreInterface} (`store`).
|
|
5154
|
-
*
|
|
5155
|
-
* @remarks
|
|
5156
|
-
* Lenient: when a `store` is set AND `id` is registered, `store.set(workspace.snapshot())` is
|
|
5157
|
-
* awaited and `true` is returned; otherwise (no store, OR an unknown id) it is a NO-OP returning
|
|
5158
|
-
* `false` — never a throw, consistent with the lenient `switch`.
|
|
5159
|
-
*
|
|
5160
|
-
* @param id - The id of the registered workspace to persist
|
|
5161
|
-
* @returns `true` when the snapshot was persisted; `false` when no store / unknown id
|
|
5162
|
-
*/
|
|
5163
|
-
save(id: string): Promise<boolean>;
|
|
5164
|
-
remove(ids: readonly string[]): boolean;
|
|
5165
|
-
remove(id: string): boolean;
|
|
5166
|
-
clear(): void;
|
|
5167
|
-
}
|
|
5168
|
-
|
|
5169
|
-
/**
|
|
5170
|
-
* Options for `createWorkspaceManager` — the per-workspace `on` / `error` defaults the
|
|
5171
|
-
* workspaces it creates inherit.
|
|
5172
|
-
*
|
|
5173
|
-
* @remarks
|
|
5174
|
-
* `on` / `error` are the default {@link WorkspaceEventMap} listeners + the emitter's
|
|
5175
|
-
* listener-error handler (§13) flowed into every workspace the manager `add`s (a per-`add`
|
|
5176
|
-
* {@link WorkspaceInput.on} / `.error` overrides them). Kept minimal (AGENTS §21) — a
|
|
5177
|
-
* registry needs no more.
|
|
5178
|
-
*/
|
|
5179
|
-
export declare interface WorkspaceManagerOptions {
|
|
5180
|
-
/** The default event listeners for workspaces this manager creates (a per-`add` override wins). */
|
|
5181
|
-
readonly on?: EmitterHooks<WorkspaceEventMap>;
|
|
5182
|
-
/** The default listener-error handler (a per-`add` override wins). */
|
|
5183
|
-
readonly error?: EmitterErrorHandler;
|
|
5184
|
-
/**
|
|
5185
|
-
* The optional durable {@link WorkspaceStoreInterface} backing {@link WorkspaceManagerInterface.open}
|
|
5186
|
-
* / {@link WorkspaceManagerInterface.save} — a memory / JSON / SQLite / IndexedDB store a workspace
|
|
5187
|
-
* is HYDRATED from (`open` a registry-miss) and PERSISTED to (`save`). Omitted ⇒ the manager is
|
|
5188
|
-
* registry-only: `open` resolves only what is already registered, and `save` is a no-op (`false`).
|
|
5189
|
-
*/
|
|
5190
|
-
readonly store?: WorkspaceStoreInterface;
|
|
5191
|
-
}
|
|
5192
|
-
|
|
5193
|
-
/**
|
|
5194
|
-
* Options for {@link import('./factories.js').createWorkspace} / the
|
|
5195
|
-
* {@link import('./workspaces/Workspace.js').Workspace} constructor.
|
|
5196
|
-
*
|
|
5197
|
-
* @param options - The workspace options
|
|
5198
|
-
*
|
|
5199
|
-
* @remarks
|
|
5200
|
-
* - `id` — the workspace's identity (its key in a {@link WorkspaceManagerInterface}); MINTED via `crypto.randomUUID()` when omitted.
|
|
5201
|
-
* - `on` — initial {@link WorkspaceEventMap} listeners (AGENTS §8), wired at construction.
|
|
5202
|
-
* - `error` — the emitter's listener-error handler (AGENTS §13); a throw from any listener is routed here instead of rethrown.
|
|
5203
|
-
*/
|
|
5204
|
-
export declare interface WorkspaceOptions {
|
|
5205
|
-
readonly id?: string;
|
|
5206
|
-
readonly on?: EmitterHooks<WorkspaceEventMap>;
|
|
5207
|
-
readonly error?: EmitterErrorHandler;
|
|
5208
|
-
}
|
|
5209
|
-
|
|
5210
|
-
/**
|
|
5211
|
-
* A JSON-serializable snapshot of a workspace's state — its `id` plus a FLAT list of its
|
|
5212
|
-
* {@link FileInterface}s — the durable payload the {@link WorkspaceStoreInterface} persists.
|
|
5213
|
-
*
|
|
5214
|
-
* @remarks
|
|
5215
|
-
* Pure JSON DATA (no class instances, no functions): each {@link FileInterface} is already a
|
|
5216
|
-
* PLAIN frozen record that `structuredClone`s / JSON-round-trips losslessly, and a `File` carries
|
|
5217
|
-
* its OWN `path`, so a flat `files` list is enough to reconstruct the path-keyed map (no nested
|
|
5218
|
-
* `path → File` object needed for serialization). The snapshot the container produces from itself
|
|
5219
|
-
* ({@link WorkspaceInterface.snapshot}); the durable analogue of the constructor `seed`. A
|
|
5220
|
-
* {@link WorkspaceManagerInterface} hydrates a workspace from `snapshot.files` through the seed
|
|
5221
|
-
* seam (see {@link WorkspaceManagerInterface.open}). It is narrowed back from an untrusted storage
|
|
5222
|
-
* read by {@link import('./helpers.js').isWorkspaceSnapshot} (the AGENTS §14 boundary narrow).
|
|
5223
|
-
*/
|
|
5224
|
-
export declare interface WorkspaceSnapshot {
|
|
5225
|
-
readonly id: string;
|
|
5226
|
-
readonly files: readonly FileInterface[];
|
|
5227
|
-
}
|
|
5228
|
-
|
|
5229
|
-
/**
|
|
5230
|
-
* One row of the table a
|
|
5231
|
-
* {@link import('./workspaces/stores/DatabaseWorkspaceStore.js').DatabaseWorkspaceStore} persists
|
|
5232
|
-
* — a workspace `id` plus its {@link WorkspaceSnapshot} held as ONE OPAQUE JSON column.
|
|
5233
|
-
*
|
|
5234
|
-
* @remarks
|
|
5235
|
-
* The Database twin of {@link WorkspaceStoreInterface} stores the snapshot whole (the `snapshot`
|
|
5236
|
-
* column is a `rawShape`, an opaque JSON blob — exactly as the analogous
|
|
5237
|
-
* `WorkflowSnapshotRow` in `@orkestrel/workflow` stores a workflow snapshot), so the
|
|
5238
|
-
* row type stays FLAT and the `File`-list snapshot shape never forces the contract to `Infer` it.
|
|
5239
|
-
* The column therefore reads back as the broad `unknown`; the store narrows it to a
|
|
5240
|
-
* {@link WorkspaceSnapshot} on `get` ({@link import('./helpers.js').isWorkspaceSnapshot}, the
|
|
5241
|
-
* AGENTS §14 boundary narrow). `id` mirrors {@link WorkspaceSnapshot.id} (the primary key), so a
|
|
5242
|
-
* `set` writes `{ id: snapshot.id, snapshot }`.
|
|
5243
|
-
*/
|
|
5244
|
-
export declare interface WorkspaceSnapshotRow {
|
|
5245
|
-
readonly id: string;
|
|
5246
|
-
/** The whole {@link WorkspaceSnapshot} as one opaque JSON blob — read back as `unknown`, narrowed on `get`. */
|
|
5247
|
-
readonly snapshot: unknown;
|
|
5248
|
-
}
|
|
5249
|
-
|
|
5250
|
-
/**
|
|
5251
|
-
* The durable persistence seam for a {@link WorkspaceSnapshot} — three async primitives
|
|
5252
|
-
* (`get` / `set` / `delete`) keyed by a workspace id, mirroring the analogous
|
|
5253
|
-
* `WorkflowStoreInterface` in `@orkestrel/workflow` (and the driver-swap pattern a server
|
|
5254
|
-
* surface's session store would follow).
|
|
5255
|
-
*
|
|
5256
|
-
* @remarks
|
|
5257
|
-
* The store persists the {@link WorkspaceSnapshot} — the self-contained, pure-JSON workspace
|
|
5258
|
-
* state — so a JSON / SQLite / IndexedDB backend swaps in WITHOUT touching the manager or the
|
|
5259
|
-
* workspace: the in-memory default
|
|
5260
|
-
* {@link import('./workspaces/stores/MemoryWorkspaceStore.js').MemoryWorkspaceStore} and its
|
|
5261
|
-
* driver-pluggable twin
|
|
5262
|
-
* {@link import('./workspaces/stores/DatabaseWorkspaceStore.js').DatabaseWorkspaceStore} (the
|
|
5263
|
-
* snapshot as one opaque JSON column) share THIS one interface. Hydration is NOT a store concern
|
|
5264
|
-
* — a {@link WorkspaceManagerInterface} reads a snapshot back and rebuilds the live workspace
|
|
5265
|
-
* through the constructor `seed` (see {@link WorkspaceManagerInterface.open} /
|
|
5266
|
-
* {@link WorkspaceManagerInterface.save}).
|
|
5267
|
-
*
|
|
5268
|
-
* Every primitive is async (a `Promise`), so a durable backend (a database round-trip) fits the
|
|
5269
|
-
* same shape as the memory one. The snapshot carries its OWN id, so `set` takes no separate id
|
|
5270
|
-
* param (mirroring the analogous `WorkflowStoreInterface.set` in `@orkestrel/workflow`). UNLIKE a
|
|
5271
|
-
* session store there is NO idle-TTL / eviction — a persisted workspace lives until an explicit
|
|
5272
|
-
* `delete`. It is concrete over {@link WorkspaceSnapshot} — no generic parameter (AGENTS §21
|
|
5273
|
-
* minimal-interface), since the snapshot is the ONE payload a workspace store persists.
|
|
5274
|
-
*/
|
|
5275
|
-
export declare interface WorkspaceStoreInterface {
|
|
5276
|
-
/**
|
|
5277
|
-
* Resolve the persisted snapshot for `id`, or `undefined` if none is stored.
|
|
5278
|
-
*
|
|
5279
|
-
* @param id - The workspace id to resolve (a {@link WorkspaceSnapshot.id})
|
|
5280
|
-
* @returns The persisted snapshot, or `undefined` if absent
|
|
5281
|
-
*/
|
|
5282
|
-
get(id: string): Promise<WorkspaceSnapshot | undefined>;
|
|
5283
|
-
/**
|
|
5284
|
-
* Insert or replace a snapshot under its own `snapshot.id` (no separate id param —
|
|
5285
|
-
* mirroring the analogous `WorkflowStoreInterface.set` in `@orkestrel/workflow`).
|
|
5286
|
-
*
|
|
5287
|
-
* @param snapshot - The snapshot to store (keyed by its `id`)
|
|
5288
|
-
*/
|
|
5289
|
-
set(snapshot: WorkspaceSnapshot): Promise<void>;
|
|
5290
|
-
/**
|
|
5291
|
-
* Drop a snapshot by id; an absent id is a no-op (no throw).
|
|
5292
|
-
*
|
|
5293
|
-
* @param id - The workspace id to drop
|
|
5294
|
-
*/
|
|
5295
|
-
delete(id: string): Promise<void>;
|
|
5296
|
-
}
|
|
5297
|
-
|
|
5298
3690
|
export { }
|