@orkestrel/agent 0.0.8 → 0.0.10

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.
@@ -1,8 +1,10 @@
1
1
  import { BudgetInterface } from '@orkestrel/budget';
2
+ import { ControllerInterface } from '@orkestrel/workflow';
2
3
  import { DriverInterface } from '@orkestrel/database';
3
4
  import { EmitterErrorHandler } from '@orkestrel/emitter';
4
5
  import { EmitterHooks } from '@orkestrel/emitter';
5
6
  import { EmitterInterface } from '@orkestrel/emitter';
7
+ import { QueueExecution } from '@orkestrel/queue';
6
8
  import { QueueInterface } from '@orkestrel/queue';
7
9
  import { QueueStoreInterface } from '@orkestrel/queue';
8
10
  import { RunnerInterface } from '@orkestrel/workflow';
@@ -182,7 +184,7 @@ export declare class AgentContext implements AgentContextInterface {
182
184
  * @remarks
183
185
  * The richer context — `system` (the optional system prompt), the context managers
184
186
  * (`instructions` / `tools` / `workspaces` / `conversations`), `messages` (the active
185
- * conversation's live tail, satisfying {@link MessageManagerInterface}), and a mutable `scope`
187
+ * conversation's live tail, satisfying {@link MessageManagerInterface}), and the current `scope`
186
188
  * (the active {@link ScopeInterface} filter, or `undefined` for no filtering). `build()` folds the
187
189
  * scoped instructions into ONE leading `system` message (under the manager's `description`,
188
190
  * each item via its `format`) — PLUS the ACTIVE workspace's scope-filtered text files
@@ -200,13 +202,12 @@ export declare interface AgentContextInterface {
200
202
  * The {@link WorkspaceManagerInterface} whose ACTIVE workspace `build()` renders by carrier —
201
203
  * its text files folded into the system block (fenced reference blocks) and its image files'
202
204
  * base64 `data` attached to the LAST user message. The active workspace is the SOLE
203
- * document/image context. ALWAYS present (a fresh empty manager when none was supplied). A
204
- * SETTABLE mutable property (a getter + setter, like {@link scope} / {@link conversations}, NOT a
205
- * method): assign it to swap the whole workspace registry; `build()` reads its `active` (and the
206
- * active workspace's `files()`) FRESH each call. With NO active workspace, nothing is rendered for
207
- * workspaces. Active-only — never the other registered workspaces.
205
+ * document/image context. ALWAYS present (a fresh empty manager when none was supplied).
206
+ * `build()` reads its `active` (and the active workspace's `files()`) FRESH each call. With NO
207
+ * active workspace, nothing is rendered for workspaces. Active-only — never the other registered
208
+ * workspaces.
208
209
  */
209
- workspaces: WorkspaceManagerInterface;
210
+ readonly workspaces: WorkspaceManagerInterface;
210
211
  /**
211
212
  * The active conversation's LIVE tail — the agent's message source, ALWAYS defined (the
212
213
  * {@link conversations} registry always has an active conversation; a default is added at
@@ -221,16 +222,15 @@ export declare interface AgentContextInterface {
221
222
  * The {@link ConversationManagerInterface} the message source flows from — `messages` IS its
222
223
  * ACTIVE conversation's live tail and `build()` folds that conversation's `view()`. ALWAYS holds
223
224
  * an active conversation (a default is added at construction when none was supplied), so
224
- * `messages` is always defined. A SETTABLE mutable property (a getter + setter, like
225
- * {@link scope} / {@link workspaces}, NOT a method): assign it to swap the whole conversation
226
- * registry between runs; switch the active conversation through `conversations.switch(id)` — so
227
- * one agent can serve MANY conversations (set the active one per request). Switch BETWEEN runs,
228
- * not during one; for CONCURRENT threads use separate agents (see clause 25).
225
+ * `messages` is always defined. Switch the active conversation through
226
+ * `conversations.switch(id)` — so one agent can serve MANY conversations (set the active one per
227
+ * request). Switch BETWEEN runs, not during one; for CONCURRENT threads use separate agents (see
228
+ * clause 25).
229
229
  */
230
- conversations: ConversationManagerInterface;
230
+ readonly conversations: ConversationManagerInterface;
231
231
  readonly tools: ToolManagerInterface;
232
- /** The active scope applied at `build()` time + the loop's tool-advertise step; mutable (`undefined` ⇒ no filtering). */
233
- scope: ScopeInterface | undefined;
232
+ /** The active scope applied at `build()` time + the loop's tool-advertise step (`undefined` ⇒ no filtering). */
233
+ readonly scope: ScopeInterface | undefined;
234
234
  /**
235
235
  * The provider input for the next turn: a leading `system` message folding the prompt
236
236
  * + the scoped instructions + the ACTIVE workspace's scoped-in TEXT files (rendered as
@@ -1132,7 +1132,7 @@ export declare function clampRange(text: string, range: Range): Range;
1132
1132
 
1133
1133
  /**
1134
1134
  * The PER-RUN auto-compaction state threaded through an {@link AgentInterface}'s loop —
1135
- * a tiny mutable holder created fresh per run (so no state leaks across runs or a
1135
+ * a tiny immutable value replaced within a holder created fresh per run (so no state leaks across runs or a
1136
1136
  * conversation switch), mirroring how {@link RunOutcome} is the per-run sink.
1137
1137
  *
1138
1138
  * @remarks
@@ -1140,10 +1140,10 @@ export declare function clampRange(text: string, range: Range): Range;
1140
1140
  * the prompt is still over the context window (the v1 single-level limit — the live tail
1141
1141
  * is at/below `keep` and the over-window is structural), so auto-compaction STOPS for the
1142
1142
  * rest of that run (no per-turn churn). Like {@link RunOutcome}, it is INTERNAL loop state
1143
- * — the loop reads + flips it as it runs, not a caller-facing shape.
1143
+ * — the loop reads + replaces it as it runs, not a caller-facing shape.
1144
1144
  */
1145
1145
  export declare interface CompactionState {
1146
- futile: boolean;
1146
+ readonly futile: boolean;
1147
1147
  }
1148
1148
 
1149
1149
  /**
@@ -3056,6 +3056,34 @@ export declare type FileState = 'created' | 'modified' | 'loaded' | 'deleted';
3056
3056
  */
3057
3057
  export declare function filterAllowList<T>(allow: readonly string[] | undefined, items: readonly T[], key: (item: T) => string): readonly T[];
3058
3058
 
3059
+ /**
3060
+ * Handle one queued agent job by rehydrating it through a registry with the queue
3061
+ * attempt's signal, then applying the shared partial-result policy.
3062
+ *
3063
+ * @param registry - The registry that rehydrates the serializable job
3064
+ * @param allowPartial - Whether a partial result resolves instead of throwing
3065
+ * @param input - The serializable agent job
3066
+ * @param execution - The queue attempt whose signal bounds the agent
3067
+ * @returns The settled agent result
3068
+ */
3069
+ export declare function handleAgentQueueJob(registry: AgentRegistryInterface, allowPartial: boolean, input: AgentJobInput, execution: QueueExecution): Promise<AgentResult>;
3070
+
3071
+ /**
3072
+ * Handle one runner agent job by fanning out its declared children, rehydrating the
3073
+ * parent through a registry with the controller signal, and applying the shared
3074
+ * partial-result policy.
3075
+ *
3076
+ * @remarks
3077
+ * Children are fired and tracked through the runner controller without awaiting them
3078
+ * inline, preserving bounded-runner progress.
3079
+ *
3080
+ * @param registry - The registry that rehydrates serializable jobs
3081
+ * @param allowPartial - Whether a partial result resolves instead of throwing
3082
+ * @param controller - The runner controller for this parent job
3083
+ * @returns The settled parent agent result
3084
+ */
3085
+ export declare function handleAgentRunnerJob(registry: AgentRegistryInterface, allowPartial: boolean, controller: ControllerInterface<AgentJobInput, AgentResult>): Promise<AgentResult>;
3086
+
3059
3087
  /**
3060
3088
  * The coarse, deliberately-approximate per-image token cost {@link import('./helpers.js').estimateMessages}
3061
3089
  * charges for each attached image.
@@ -4065,12 +4093,12 @@ export declare interface ReplaceResult {
4065
4093
  }
4066
4094
 
4067
4095
  /**
4068
- * The mutable per-run sink an {@link AgentInterface}'s loop fills as it runs — the
4069
- * assembled outcome its `stream`'s `result` promise resolves into a settled
4096
+ * The immutable per-run outcome value an {@link AgentInterface}'s loop replaces as it runs — the
4097
+ * assembled value its `stream`'s `result` promise resolves into a settled
4070
4098
  * {@link AgentResult} once the run completes.
4071
4099
  *
4072
4100
  * @remarks
4073
- * Created fresh per run (so concurrent runs never share state) and threaded through
4101
+ * Created fresh per run (so concurrent runs never share state) and replaced through
4074
4102
  * the loop: `content` accumulates the streamed assistant text, `thinking` the
4075
4103
  * reasoning the provider calls separated from it ({@link ProviderResult.thinking},
4076
4104
  * joined across calls — `undefined` until one surfaces it), `usage` the summed
@@ -4082,13 +4110,21 @@ export declare interface ReplaceResult {
4082
4110
  * loop reads it back to assemble the public result — not a caller-facing shape.
4083
4111
  */
4084
4112
  export declare interface RunOutcome {
4085
- content: string;
4086
- thinking: string | undefined;
4087
- usage: TokenUsage | undefined;
4088
- partial: boolean;
4089
- exhausted: boolean;
4113
+ readonly content: string;
4114
+ readonly thinking: string | undefined;
4115
+ readonly usage: TokenUsage | undefined;
4116
+ readonly partial: boolean;
4117
+ readonly exhausted: boolean;
4090
4118
  }
4091
4119
 
4120
+ /**
4121
+ * Sanitize one reported token count into a safe non-negative integer.
4122
+ *
4123
+ * @param value - The token count to sanitize
4124
+ * @returns The floored count, or `0` when the value is non-finite or non-positive
4125
+ */
4126
+ export declare function sanitizeToken(value: number): number;
4127
+
4092
4128
  /**
4093
4129
  * Sanitize a {@link TokenUsage} into safe, non-negative integers — the guard an agent's
4094
4130
  * abort-usage path applies to a provider's partial usage before it is charged against a
@@ -4143,9 +4179,9 @@ export declare class Scope implements ScopeInterface {
4143
4179
  #private;
4144
4180
  readonly id: string;
4145
4181
  readonly name: string;
4146
- readonly instructions: readonly string[] | undefined;
4147
- readonly tools: readonly string[] | undefined;
4148
- readonly files: readonly string[] | undefined;
4182
+ readonly instructions?: readonly string[];
4183
+ readonly tools?: readonly string[];
4184
+ readonly files?: readonly string[];
4149
4185
  constructor(input: ScopeInput);
4150
4186
  narrow(config: ScopeConfiguration): ScopeInterface;
4151
4187
  }
@@ -1,8 +1,10 @@
1
1
  import { BudgetInterface } from '@orkestrel/budget';
2
+ import { ControllerInterface } from '@orkestrel/workflow';
2
3
  import { DriverInterface } from '@orkestrel/database';
3
4
  import { EmitterErrorHandler } from '@orkestrel/emitter';
4
5
  import { EmitterHooks } from '@orkestrel/emitter';
5
6
  import { EmitterInterface } from '@orkestrel/emitter';
7
+ import { QueueExecution } from '@orkestrel/queue';
6
8
  import { QueueInterface } from '@orkestrel/queue';
7
9
  import { QueueStoreInterface } from '@orkestrel/queue';
8
10
  import { RunnerInterface } from '@orkestrel/workflow';
@@ -182,7 +184,7 @@ export declare class AgentContext implements AgentContextInterface {
182
184
  * @remarks
183
185
  * The richer context — `system` (the optional system prompt), the context managers
184
186
  * (`instructions` / `tools` / `workspaces` / `conversations`), `messages` (the active
185
- * conversation's live tail, satisfying {@link MessageManagerInterface}), and a mutable `scope`
187
+ * conversation's live tail, satisfying {@link MessageManagerInterface}), and the current `scope`
186
188
  * (the active {@link ScopeInterface} filter, or `undefined` for no filtering). `build()` folds the
187
189
  * scoped instructions into ONE leading `system` message (under the manager's `description`,
188
190
  * each item via its `format`) — PLUS the ACTIVE workspace's scope-filtered text files
@@ -200,13 +202,12 @@ export declare interface AgentContextInterface {
200
202
  * The {@link WorkspaceManagerInterface} whose ACTIVE workspace `build()` renders by carrier —
201
203
  * its text files folded into the system block (fenced reference blocks) and its image files'
202
204
  * base64 `data` attached to the LAST user message. The active workspace is the SOLE
203
- * document/image context. ALWAYS present (a fresh empty manager when none was supplied). A
204
- * SETTABLE mutable property (a getter + setter, like {@link scope} / {@link conversations}, NOT a
205
- * method): assign it to swap the whole workspace registry; `build()` reads its `active` (and the
206
- * active workspace's `files()`) FRESH each call. With NO active workspace, nothing is rendered for
207
- * workspaces. Active-only — never the other registered workspaces.
205
+ * document/image context. ALWAYS present (a fresh empty manager when none was supplied).
206
+ * `build()` reads its `active` (and the active workspace's `files()`) FRESH each call. With NO
207
+ * active workspace, nothing is rendered for workspaces. Active-only — never the other registered
208
+ * workspaces.
208
209
  */
209
- workspaces: WorkspaceManagerInterface;
210
+ readonly workspaces: WorkspaceManagerInterface;
210
211
  /**
211
212
  * The active conversation's LIVE tail — the agent's message source, ALWAYS defined (the
212
213
  * {@link conversations} registry always has an active conversation; a default is added at
@@ -221,16 +222,15 @@ export declare interface AgentContextInterface {
221
222
  * The {@link ConversationManagerInterface} the message source flows from — `messages` IS its
222
223
  * ACTIVE conversation's live tail and `build()` folds that conversation's `view()`. ALWAYS holds
223
224
  * an active conversation (a default is added at construction when none was supplied), so
224
- * `messages` is always defined. A SETTABLE mutable property (a getter + setter, like
225
- * {@link scope} / {@link workspaces}, NOT a method): assign it to swap the whole conversation
226
- * registry between runs; switch the active conversation through `conversations.switch(id)` — so
227
- * one agent can serve MANY conversations (set the active one per request). Switch BETWEEN runs,
228
- * not during one; for CONCURRENT threads use separate agents (see clause 25).
225
+ * `messages` is always defined. Switch the active conversation through
226
+ * `conversations.switch(id)` — so one agent can serve MANY conversations (set the active one per
227
+ * request). Switch BETWEEN runs, not during one; for CONCURRENT threads use separate agents (see
228
+ * clause 25).
229
229
  */
230
- conversations: ConversationManagerInterface;
230
+ readonly conversations: ConversationManagerInterface;
231
231
  readonly tools: ToolManagerInterface;
232
- /** The active scope applied at `build()` time + the loop's tool-advertise step; mutable (`undefined` ⇒ no filtering). */
233
- scope: ScopeInterface | undefined;
232
+ /** The active scope applied at `build()` time + the loop's tool-advertise step (`undefined` ⇒ no filtering). */
233
+ readonly scope: ScopeInterface | undefined;
234
234
  /**
235
235
  * The provider input for the next turn: a leading `system` message folding the prompt
236
236
  * + the scoped instructions + the ACTIVE workspace's scoped-in TEXT files (rendered as
@@ -1132,7 +1132,7 @@ export declare function clampRange(text: string, range: Range): Range;
1132
1132
 
1133
1133
  /**
1134
1134
  * The PER-RUN auto-compaction state threaded through an {@link AgentInterface}'s loop —
1135
- * a tiny mutable holder created fresh per run (so no state leaks across runs or a
1135
+ * a tiny immutable value replaced within a holder created fresh per run (so no state leaks across runs or a
1136
1136
  * conversation switch), mirroring how {@link RunOutcome} is the per-run sink.
1137
1137
  *
1138
1138
  * @remarks
@@ -1140,10 +1140,10 @@ export declare function clampRange(text: string, range: Range): Range;
1140
1140
  * the prompt is still over the context window (the v1 single-level limit — the live tail
1141
1141
  * is at/below `keep` and the over-window is structural), so auto-compaction STOPS for the
1142
1142
  * rest of that run (no per-turn churn). Like {@link RunOutcome}, it is INTERNAL loop state
1143
- * — the loop reads + flips it as it runs, not a caller-facing shape.
1143
+ * — the loop reads + replaces it as it runs, not a caller-facing shape.
1144
1144
  */
1145
1145
  export declare interface CompactionState {
1146
- futile: boolean;
1146
+ readonly futile: boolean;
1147
1147
  }
1148
1148
 
1149
1149
  /**
@@ -3056,6 +3056,34 @@ export declare type FileState = 'created' | 'modified' | 'loaded' | 'deleted';
3056
3056
  */
3057
3057
  export declare function filterAllowList<T>(allow: readonly string[] | undefined, items: readonly T[], key: (item: T) => string): readonly T[];
3058
3058
 
3059
+ /**
3060
+ * Handle one queued agent job by rehydrating it through a registry with the queue
3061
+ * attempt's signal, then applying the shared partial-result policy.
3062
+ *
3063
+ * @param registry - The registry that rehydrates the serializable job
3064
+ * @param allowPartial - Whether a partial result resolves instead of throwing
3065
+ * @param input - The serializable agent job
3066
+ * @param execution - The queue attempt whose signal bounds the agent
3067
+ * @returns The settled agent result
3068
+ */
3069
+ export declare function handleAgentQueueJob(registry: AgentRegistryInterface, allowPartial: boolean, input: AgentJobInput, execution: QueueExecution): Promise<AgentResult>;
3070
+
3071
+ /**
3072
+ * Handle one runner agent job by fanning out its declared children, rehydrating the
3073
+ * parent through a registry with the controller signal, and applying the shared
3074
+ * partial-result policy.
3075
+ *
3076
+ * @remarks
3077
+ * Children are fired and tracked through the runner controller without awaiting them
3078
+ * inline, preserving bounded-runner progress.
3079
+ *
3080
+ * @param registry - The registry that rehydrates serializable jobs
3081
+ * @param allowPartial - Whether a partial result resolves instead of throwing
3082
+ * @param controller - The runner controller for this parent job
3083
+ * @returns The settled parent agent result
3084
+ */
3085
+ export declare function handleAgentRunnerJob(registry: AgentRegistryInterface, allowPartial: boolean, controller: ControllerInterface<AgentJobInput, AgentResult>): Promise<AgentResult>;
3086
+
3059
3087
  /**
3060
3088
  * The coarse, deliberately-approximate per-image token cost {@link import('./helpers.js').estimateMessages}
3061
3089
  * charges for each attached image.
@@ -4065,12 +4093,12 @@ export declare interface ReplaceResult {
4065
4093
  }
4066
4094
 
4067
4095
  /**
4068
- * The mutable per-run sink an {@link AgentInterface}'s loop fills as it runs — the
4069
- * assembled outcome its `stream`'s `result` promise resolves into a settled
4096
+ * The immutable per-run outcome value an {@link AgentInterface}'s loop replaces as it runs — the
4097
+ * assembled value its `stream`'s `result` promise resolves into a settled
4070
4098
  * {@link AgentResult} once the run completes.
4071
4099
  *
4072
4100
  * @remarks
4073
- * Created fresh per run (so concurrent runs never share state) and threaded through
4101
+ * Created fresh per run (so concurrent runs never share state) and replaced through
4074
4102
  * the loop: `content` accumulates the streamed assistant text, `thinking` the
4075
4103
  * reasoning the provider calls separated from it ({@link ProviderResult.thinking},
4076
4104
  * joined across calls — `undefined` until one surfaces it), `usage` the summed
@@ -4082,13 +4110,21 @@ export declare interface ReplaceResult {
4082
4110
  * loop reads it back to assemble the public result — not a caller-facing shape.
4083
4111
  */
4084
4112
  export declare interface RunOutcome {
4085
- content: string;
4086
- thinking: string | undefined;
4087
- usage: TokenUsage | undefined;
4088
- partial: boolean;
4089
- exhausted: boolean;
4113
+ readonly content: string;
4114
+ readonly thinking: string | undefined;
4115
+ readonly usage: TokenUsage | undefined;
4116
+ readonly partial: boolean;
4117
+ readonly exhausted: boolean;
4090
4118
  }
4091
4119
 
4120
+ /**
4121
+ * Sanitize one reported token count into a safe non-negative integer.
4122
+ *
4123
+ * @param value - The token count to sanitize
4124
+ * @returns The floored count, or `0` when the value is non-finite or non-positive
4125
+ */
4126
+ export declare function sanitizeToken(value: number): number;
4127
+
4092
4128
  /**
4093
4129
  * Sanitize a {@link TokenUsage} into safe, non-negative integers — the guard an agent's
4094
4130
  * abort-usage path applies to a provider's partial usage before it is charged against a
@@ -4143,9 +4179,9 @@ export declare class Scope implements ScopeInterface {
4143
4179
  #private;
4144
4180
  readonly id: string;
4145
4181
  readonly name: string;
4146
- readonly instructions: readonly string[] | undefined;
4147
- readonly tools: readonly string[] | undefined;
4148
- readonly files: readonly string[] | undefined;
4182
+ readonly instructions?: readonly string[];
4183
+ readonly tools?: readonly string[];
4184
+ readonly files?: readonly string[];
4149
4185
  constructor(input: ScopeInput);
4150
4186
  narrow(config: ScopeConfiguration): ScopeInterface;
4151
4187
  }