@wrongstack/core 0.54.1 → 0.66.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.
Files changed (63) hide show
  1. package/dist/{agent-bridge-Dnhw4tnM.d.ts → agent-bridge-D-j6OOBT.d.ts} +1 -1
  2. package/dist/agent-subagent-runner-DRZ9-NnR.d.ts +1042 -0
  3. package/dist/{compactor-Duhsf0ge.d.ts → compactor-D_ExJajC.d.ts} +1 -1
  4. package/dist/{config-bht0txXS.d.ts → config--86aHSln.d.ts} +112 -2
  5. package/dist/{context-DtPKqKYV.d.ts → context-y87Jc5ei.d.ts} +8 -8
  6. package/dist/coordination/index.d.ts +12 -12
  7. package/dist/coordination/index.js +87 -69
  8. package/dist/coordination/index.js.map +1 -1
  9. package/dist/defaults/index.d.ts +22 -22
  10. package/dist/defaults/index.js +365 -174
  11. package/dist/defaults/index.js.map +1 -1
  12. package/dist/{events-CbHTS4ZZ.d.ts → events-CIplI98R.d.ts} +20 -1
  13. package/dist/execution/index.d.ts +16 -385
  14. package/dist/execution/index.js +129 -61
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/extension/index.d.ts +7 -7
  17. package/dist/goal-store-C7jcumEh.d.ts +96 -0
  18. package/dist/index-DKUvyTvV.d.ts +560 -0
  19. package/dist/{index-ge5F2dnc.d.ts → index-b5uhfTSl.d.ts} +10 -8
  20. package/dist/index.d.ts +59 -33
  21. package/dist/index.js +1138 -733
  22. package/dist/index.js.map +1 -1
  23. package/dist/infrastructure/index.d.ts +6 -6
  24. package/dist/infrastructure/index.js +1 -1
  25. package/dist/infrastructure/index.js.map +1 -1
  26. package/dist/kernel/index.d.ts +9 -9
  27. package/dist/kernel/index.js +3 -1
  28. package/dist/kernel/index.js.map +1 -1
  29. package/dist/{mcp-servers-DE6gzBry.d.ts → mcp-servers-DwoNBf6r.d.ts} +3 -3
  30. package/dist/models/index.d.ts +2 -2
  31. package/dist/{multi-agent-coordinator-CjNX4uBD.d.ts → multi-agent-coordinator-CWnH-CiX.d.ts} +10 -2
  32. package/dist/{null-fleet-bus-BNiSlTna.d.ts → null-fleet-bus-VApKRxcp.d.ts} +6 -7
  33. package/dist/observability/index.d.ts +2 -2
  34. package/dist/parallel-eternal-engine-0UwotoSx.d.ts +483 -0
  35. package/dist/{path-resolver-Bax85amb.d.ts → path-resolver-DVkEcIw8.d.ts} +2 -2
  36. package/dist/{permission-Drm7LpPo.d.ts → permission-C1A5whY5.d.ts} +17 -1
  37. package/dist/{permission-policy-CU6sqWxF.d.ts → permission-policy-B2dK-T5N.d.ts} +28 -7
  38. package/dist/{plan-templates-CLRcurWN.d.ts → plan-templates-Bprrzhbu.d.ts} +4 -4
  39. package/dist/{provider-runner-BikCxGCx.d.ts → provider-runner-mXvXGSIw.d.ts} +3 -3
  40. package/dist/{retry-policy-Chtlvr5b.d.ts → retry-policy-CG3qvH_e.d.ts} +1 -1
  41. package/dist/sdd/index.d.ts +9 -9
  42. package/dist/sdd/index.js +59 -52
  43. package/dist/sdd/index.js.map +1 -1
  44. package/dist/security/index.d.ts +3 -3
  45. package/dist/security/index.js +144 -33
  46. package/dist/security/index.js.map +1 -1
  47. package/dist/{selector-BvSPdJj6.d.ts → selector-RvBR_YRW.d.ts} +1 -1
  48. package/dist/session-event-bridge-CDHxcmQU.d.ts +93 -0
  49. package/dist/{session-reader-BGhzMir4.d.ts → session-reader-BIpwM60D.d.ts} +1 -1
  50. package/dist/storage/index.d.ts +7 -6
  51. package/dist/{system-prompt-dtzV_mLm.d.ts → system-prompt-b61lOd49.d.ts} +32 -2
  52. package/dist/types/index.d.ts +23 -14
  53. package/dist/types/index.js +62 -6
  54. package/dist/types/index.js.map +1 -1
  55. package/dist/utils/index.d.ts +2 -2
  56. package/dist/utils/index.js.map +1 -1
  57. package/package.json +1 -1
  58. package/skills/multi-agent/SKILL.md +0 -2
  59. package/dist/agent-subagent-runner-By7jruZ_.d.ts +0 -182
  60. package/dist/goal-store-DwcTDDiX.d.ts +0 -188
  61. package/dist/index-CI271MjL.d.ts +0 -903
  62. package/dist/multi-agent-BmC_xiog.d.ts +0 -554
  63. package/dist/tool-executor-CgU0yWpB.d.ts +0 -110
@@ -1,10 +1,10 @@
1
- export { A as AfterIterationHook, a as AfterRunHook, b as AfterToolExecutionHook, d as AgentExtension, B as BeforeIterationHook, h as BeforeRunHook, i as BeforeToolExecutionHook, E as ExtensionRegistry, O as OnErrorHook, s as ProviderRunnerFn, t as ProviderRunnerWrapper } from '../index-CI271MjL.js';
2
- import '../context-DtPKqKYV.js';
1
+ export { A as AfterIterationHook, a as AfterRunHook, b as AfterToolExecutionHook, c as AgentExtension, B as BeforeIterationHook, g as BeforeRunHook, h as BeforeToolExecutionHook, E as ExtensionRegistry, O as OnErrorHook, n as ProviderRunnerFn, o as ProviderRunnerWrapper } from '../index-DKUvyTvV.js';
2
+ import '../context-y87Jc5ei.js';
3
3
  import '../logger-DDd5C--Z.js';
4
- import '../system-prompt-dtzV_mLm.js';
4
+ import '../system-prompt-b61lOd49.js';
5
+ import '../config--86aHSln.js';
6
+ import '../models-registry-BcYJDKLm.js';
5
7
  import '../observability-BhnVLBLS.js';
6
- import '../events-CbHTS4ZZ.js';
8
+ import '../events-CIplI98R.js';
7
9
  import '../secret-scrubber-3MHDDAtm.js';
8
- import '../permission-Drm7LpPo.js';
9
- import '../config-bht0txXS.js';
10
- import '../models-registry-BcYJDKLm.js';
10
+ import '../permission-C1A5whY5.js';
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Long-running autonomous mission. A goal survives across sessions and
3
+ * drives the EternalAutonomyEngine — every iteration of the engine
4
+ * consults the goal to choose what to do next.
5
+ *
6
+ * Storage: `~/.wrongstack/projects/<hash>/goal.json`. Persistent and
7
+ * project-scoped on purpose: the goal belongs to the codebase, not the
8
+ * REPL session.
9
+ */
10
+ interface JournalEntry {
11
+ /** ISO timestamp of the iteration. */
12
+ at: string;
13
+ /** Sequential iteration counter (1-based, monotonically increasing). */
14
+ iteration: number;
15
+ /** Source that produced the action ('todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel'). */
16
+ source: 'todo' | 'git' | 'brainstorm' | 'resume' | 'manual' | 'parallel';
17
+ /** Short one-line description of what the iteration set out to do. */
18
+ task: string;
19
+ /** Outcome status. */
20
+ status: 'success' | 'failure' | 'aborted' | 'skipped';
21
+ /** Optional free-form note (error message, summary, etc.). */
22
+ note?: string;
23
+ /** Optional token usage delta for this iteration. */
24
+ tokens?: {
25
+ input: number;
26
+ output: number;
27
+ };
28
+ /** Optional USD cost delta for this iteration (provider-estimated). */
29
+ costUsd?: number;
30
+ }
31
+ interface GoalFile {
32
+ version: 1;
33
+ /** The mission statement. */
34
+ goal: string;
35
+ /** When the goal was first set or last replaced. */
36
+ setAt: string;
37
+ /** Updated on every iteration completion. */
38
+ lastActivityAt: string;
39
+ /** Total iterations the engine has run against this goal (cumulative). */
40
+ iterations: number;
41
+ /** Engine lifecycle state — 'running' means another process owns this goal. */
42
+ engineState: 'idle' | 'running' | 'stopped';
43
+ /**
44
+ * Mission-level lifecycle. `active` is the default; `completed` is set
45
+ * when the engine detects `[GOAL_COMPLETE]` in a successful iteration's
46
+ * final text AND a verification pass agrees; `abandoned` is set by the
47
+ * user (e.g. `/goal abandon`) or when the engine exceeds a configured
48
+ * failure ceiling. Once not `active`, the engine refuses to run further
49
+ * iterations against this goal — protects against accidental restarts
50
+ * burning through API quota after the work is done.
51
+ *
52
+ * Optional for backward compatibility — pre-existing `goal.json` files
53
+ * without this field load as `active`.
54
+ */
55
+ goalState?: 'active' | 'paused' | 'completed' | 'abandoned';
56
+ /**
57
+ * Per-todo attempt counter. Keyed by TodoItem id. Used by the engine
58
+ * to skip a todo that has failed N times rather than spinning on it
59
+ * forever. Persisted so attempt counts survive restarts (`/autonomy
60
+ * stop` + resume should not reset progress against a stuck task).
61
+ */
62
+ todoAttempts?: Record<string, number>;
63
+ /** Bounded ring buffer of recent iterations (newest last). */
64
+ journal: JournalEntry[];
65
+ }
66
+ /** Cap on persisted journal entries — older entries are evicted FIFO. */
67
+ declare const MAX_JOURNAL_ENTRIES = 500;
68
+ /**
69
+ * Resolve the goal file path for a given project root.
70
+ * Exposed so the engine and CLI use one canonical path.
71
+ * Uses `~/.wrongstack/projects/<hash>/goal.json` .<hash>/`.
72
+ */
73
+ declare function goalFilePath(projectRoot: string): string;
74
+ declare function loadGoal(filePath: string): Promise<GoalFile | null>;
75
+ declare function saveGoal(filePath: string, goal: GoalFile): Promise<void>;
76
+ declare function emptyGoal(goal: string): GoalFile;
77
+ /**
78
+ * Append a journal entry, bumping iteration counters and trimming the
79
+ * ring buffer. Returns a new GoalFile — does not mutate the argument.
80
+ */
81
+ declare function appendJournal(goal: GoalFile, entry: Omit<JournalEntry, 'iteration' | 'at'>): GoalFile;
82
+ /**
83
+ * Aggregate cumulative cost + tokens across all journal entries. Entries
84
+ * without telemetry are skipped (legacy entries from before the field
85
+ * was added still load cleanly).
86
+ */
87
+ declare function summarizeUsage(goal: GoalFile): {
88
+ totalCostUsd: number;
89
+ totalInputTokens: number;
90
+ totalOutputTokens: number;
91
+ iterationsWithUsage: number;
92
+ };
93
+ /** Format the goal + recent journal as a human-readable status block. */
94
+ declare function formatGoal(goal: GoalFile, journalLimit?: number): string;
95
+
96
+ export { type GoalFile as G, type JournalEntry as J, MAX_JOURNAL_ENTRIES as M, appendJournal as a, summarizeUsage as b, emptyGoal as e, formatGoal as f, goalFilePath as g, loadGoal as l, saveGoal as s };
@@ -0,0 +1,560 @@
1
+ import { T as TextBlock, Q as Tool, Y as ToolResultBlock, _ as ToolUseBlock, d as Context, p as Request, q as Response, m as Provider, a0 as WrongStackError, c as ContentBlock } from './context-y87Jc5ei.js';
2
+ import { a as Logger } from './logger-DDd5C--Z.js';
3
+ import { a as BuildContext, H as HookRegistry, e as Renderer, P as Pipeline, C as Container } from './system-prompt-b61lOd49.js';
4
+ import { l as HookEvent, r as ProviderConfig } from './config--86aHSln.js';
5
+ import { T as Tracer } from './observability-BhnVLBLS.js';
6
+ import { E as EventBus } from './events-CIplI98R.js';
7
+ import { S as SecretScrubber } from './secret-scrubber-3MHDDAtm.js';
8
+ import { a as PermissionPolicy } from './permission-C1A5whY5.js';
9
+ import { W as WireFamily } from './models-registry-BcYJDKLm.js';
10
+
11
+ /**
12
+ * A contributor that injects additional TextBlocks into the system prompt.
13
+ *
14
+ * Contributors are called on every `build()` in registration order.
15
+ * Their output is inserted after the core blocks (identity, tool usage,
16
+ * environment) but before the mode and plan blocks. This lets plugins
17
+ * inject ephemeral context — current state, recent events, plugin-specific
18
+ * instructions — without replacing the entire system prompt builder.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * api.extensions.registerSystemPromptContributor(async (ctx) => {
23
+ * return [{ type: 'text', text: '## My Plugin Context\n...' }];
24
+ * });
25
+ * ```
26
+ */
27
+ type SystemPromptContributor = (ctx: BuildContext) => Promise<TextBlock[]>;
28
+
29
+ /**
30
+ * A function that wraps (decorates) an existing tool. Receives the
31
+ * original tool and returns a modified version — typically the same
32
+ * tool with a wrapped `execute` / `executeStream`, or with modified
33
+ * metadata (description, permission).
34
+ *
35
+ * Use `ToolRegistry.wrap()` to apply; the wrapper is called immediately
36
+ * and the result replaces the registered tool. Multiple wraps stack —
37
+ * each wrapper receives the output of the previous.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * registry.wrap('read', (original) => ({
42
+ * ...original,
43
+ * async execute(input, ctx, opts) {
44
+ * console.log('read called');
45
+ * return original.execute(input, ctx, opts);
46
+ * }
47
+ * }));
48
+ * ```
49
+ */
50
+ type ToolWrapper = (tool: Tool) => Tool;
51
+ declare class ToolRegistry {
52
+ private readonly tools;
53
+ register(tool: Tool, owner?: string): void;
54
+ /**
55
+ * Attempt to register a tool. Returns true if successful, false if a tool
56
+ * with the same name is already registered. Useful in multi-agent or plugin
57
+ * scenarios where duplicate registration may be intentional.
58
+ */
59
+ tryRegister(tool: Tool, owner?: string): boolean;
60
+ /**
61
+ * Bulk-register multiple tools at once. Each tool that conflicts with an
62
+ * existing registration is silently skipped — use `registerAllOrThrow`
63
+ * if you want it to throw on conflicts.
64
+ */
65
+ registerAll(tools: Tool[], owner?: string): void;
66
+ /**
67
+ * Bulk-register and throw on the first conflict. Use when you need
68
+ * strict registration (e.g. at boot time).
69
+ */
70
+ registerAllOrThrow(tools: Tool[], owner?: string): void;
71
+ /**
72
+ * Register a tool as a default. If the tool name is already registered,
73
+ * this is a no-op — the existing registration (from core or another
74
+ * plugin) takes precedence. Use `override` to intentionally replace.
75
+ */
76
+ registerDefault(tool: Tool, owner?: string): void;
77
+ unregister(name: string): boolean;
78
+ /**
79
+ * Override an existing tool. Throws if the tool is not already registered.
80
+ * Plugins use this to replace built-in tools with custom implementations.
81
+ */
82
+ override(name: string, tool: Tool, owner?: string): void;
83
+ /**
84
+ * Wrap (decorate) an existing tool. The wrapper receives the current
85
+ * tool and must return a new tool — typically the same tool with a
86
+ * wrapped `execute` or `executeStream`. Throws if the tool is not
87
+ * registered.
88
+ *
89
+ * Multiple wraps stack: each wrapper gets the output of the previous.
90
+ *
91
+ * @example
92
+ * registry.wrap('bash', (t) => ({ ...t, permission: 'confirm' }));
93
+ */
94
+ wrap(name: string, wrapper: ToolWrapper, owner?: string): void;
95
+ get(name: string): Tool | undefined;
96
+ ownerOf(name: string): string | undefined;
97
+ list(): Tool[];
98
+ /**
99
+ * Group tools by their `category` field. Tools without a category
100
+ * are placed under the key `""` (empty string). Returns a Map of
101
+ * category → tools, sorted by registration order within each category.
102
+ */
103
+ listByCategory(): Map<string, Tool[]>;
104
+ listWithOwner(): {
105
+ tool: Tool;
106
+ owner: string;
107
+ }[];
108
+ clear(): void;
109
+ /**
110
+ * Return a new ToolRegistry with the same registered tools and owners.
111
+ * Useful for creating filtered copies in multi-agent scenarios.
112
+ */
113
+ clone(): ToolRegistry;
114
+ }
115
+
116
+ /** Minimal run-state the runner reads. `Context` structurally satisfies it. */
117
+ interface HookRunEnv {
118
+ cwd: string;
119
+ }
120
+ interface HookRunnerOptions {
121
+ registry: HookRegistry;
122
+ logger?: Logger;
123
+ /**
124
+ * When false, shell hooks are skipped entirely (in-process hooks still run).
125
+ * Set by the boot path under `--bare` / `--no-hooks` / untrusted sessions.
126
+ */
127
+ allowShell?: boolean;
128
+ /** Resolves the active session id for the `HookInput` payload. */
129
+ sessionId?: () => string | undefined;
130
+ }
131
+ interface PreToolUseResult {
132
+ block?: boolean;
133
+ reason?: string;
134
+ /** Present only when a hook replaced the tool input. */
135
+ input?: Record<string, unknown>;
136
+ }
137
+ interface PromptResult {
138
+ block?: boolean;
139
+ reason?: string;
140
+ additionalContext?: string;
141
+ }
142
+ /**
143
+ * Drives the registered hooks at each lifecycle phase. Pure orchestration —
144
+ * the executor / pipeline / agent extension call the matching method and act on
145
+ * the returned decision. Hook failures are caught and logged; they never abort
146
+ * the agent.
147
+ */
148
+ declare class HookRunner {
149
+ private readonly opts;
150
+ private readonly registry;
151
+ constructor(opts: HookRunnerOptions);
152
+ /** Cheap guard so callers can skip building payloads when nothing listens. */
153
+ has(event: HookEvent): boolean;
154
+ preToolUse(toolName: string, toolInput: Record<string, unknown>, env: HookRunEnv): Promise<PreToolUseResult>;
155
+ postToolUse(toolName: string, toolInput: unknown, result: {
156
+ content: string;
157
+ isError: boolean;
158
+ }, env: HookRunEnv): Promise<{
159
+ additionalContext?: string;
160
+ }>;
161
+ userPromptSubmit(prompt: string, env: HookRunEnv): Promise<PromptResult>;
162
+ sessionStart(env: HookRunEnv): Promise<{
163
+ additionalContext?: string;
164
+ }>;
165
+ stop(env: HookRunEnv): Promise<void>;
166
+ private base;
167
+ private matching;
168
+ private invoke;
169
+ private collectContext;
170
+ }
171
+
172
+ /**
173
+ * Output from a single tool execution.
174
+ */
175
+ interface ToolExecutionOutput {
176
+ result: ToolResultBlock | ToolConfirmPendingResult;
177
+ tool?: Tool;
178
+ durationMs: number;
179
+ }
180
+ /**
181
+ * Result of running a batch of tools for a single agent iteration.
182
+ */
183
+ interface ToolBatchResult {
184
+ outputs: ToolExecutionOutput[];
185
+ remainingBudget: number;
186
+ }
187
+ type ConfirmAwaiter = (tool: Tool, input: unknown, toolUseId: string, suggestedPattern: string) => Promise<'yes' | 'no' | 'always' | 'deny'>;
188
+ interface ToolExecutorOptions {
189
+ permissionPolicy: PermissionPolicy;
190
+ secretScrubber: SecretScrubber;
191
+ renderer?: Renderer | undefined;
192
+ /**
193
+ * Optional event bus. When provided, the executor emits `tool.started`
194
+ * before invoking each tool's `execute()`. Closes the observability gap
195
+ * between "model decided to call tool" and "tool finished".
196
+ */
197
+ events?: EventBus | undefined;
198
+ /**
199
+ * Optional tracer. When provided, every tool execution opens a
200
+ * `tool.<name>` span with attributes for tool name, permission decision,
201
+ * input size, output size, and outcome. Spans are no-op by default.
202
+ */
203
+ tracer?: Tracer | undefined;
204
+ /**
205
+ * Async callback invoked when a tool needs user confirmation.
206
+ * When omitted and confirmation is required, the executor returns a
207
+ * failure result immediately (TUI path). When provided (CLI path),
208
+ * the callback handles the interactive prompt and returns a decision.
209
+ */
210
+ confirmAwaiter?: ConfirmAwaiter | undefined;
211
+ iterationTimeoutMs?: number;
212
+ perIterationOutputCapBytes?: number;
213
+ /**
214
+ * Optional lifecycle hook runner. When present, `PreToolUse` hooks run
215
+ * before the permission check (and can block the call or rewrite its input)
216
+ * and `PostToolUse` hooks run after the tool returns (and can append context
217
+ * to the result the model sees).
218
+ */
219
+ hookRunner?: HookRunner | undefined;
220
+ }
221
+ /**
222
+ * Result returned by executeBatch when a tool needs confirmation and
223
+ * no confirmAwaiter is available. The TUI catches this and surfaces a
224
+ * confirmation dialog; once resolved the tool is re-executed.
225
+ * The string tag identifies it as a "pending confirm" result so callers
226
+ * can distinguish it from an error without inspecting content strings.
227
+ */
228
+ interface ToolConfirmPendingResult {
229
+ type: 'tool_confirm_pending';
230
+ toolUseId: string;
231
+ toolName: string;
232
+ input: unknown;
233
+ suggestedPattern: string;
234
+ }
235
+ type ToolExecutorStrategy = 'parallel' | 'sequential' | 'smart';
236
+ /**
237
+ * Minimal contract for tool execution.
238
+ *
239
+ * Defined here (in `types/`) so `core/` does not need to import the
240
+ * concrete `ToolExecutor` class from `execution/`. Callers that create
241
+ * the executor (e.g. CLI wiring) implement this interface.
242
+ *
243
+ * Only the methods actually called by `Agent` are included — keeping the
244
+ * interface narrow prevents unnecessary coupling.
245
+ */
246
+ interface ToolExecutorLike {
247
+ /**
248
+ * Execute a batch of tool uses. The strategy controls whether tools run
249
+ * sequentially, in parallel, or smart (parallel non-mutating + sequential mutating).
250
+ */
251
+ executeBatch(toolUses: ToolUseBlock[], ctx: Context, strategy: ToolExecutorStrategy): Promise<ToolBatchResult>;
252
+ /**
253
+ * Clear the interactive confirm awaiter so the executor returns
254
+ * `ToolConfirmPendingResult` instead of blocking.
255
+ */
256
+ clearConfirmAwaiter(): void;
257
+ /**
258
+ * Execute a single tool with timeout and output capping.
259
+ * Used by the agent when it needs to run one tool at a time.
260
+ */
261
+ executeTool(tool: Tool, use: ToolUseBlock, ctx: Context, budget: number): Promise<ToolResultBlock>;
262
+ }
263
+
264
+ /**
265
+ * Extension points for the Agent lifecycle.
266
+ *
267
+ * Each extension point is a hook that gets called at a specific phase.
268
+ * Extensions are always optional and failures are isolated — a failing
269
+ * extension never aborts the agent run.
270
+ *
271
+ * Plugins register extensions via `PluginAPI.extensions`, not by
272
+ * directly importing this module. The Agent calls the registry in
273
+ * order at each phase.
274
+ */
275
+
276
+ /**
277
+ * Called before Agent.run() begins the main iteration loop.
278
+ * Returns `false` or throws to prevent the run from starting.
279
+ */
280
+ type BeforeRunHook = (ctx: Context, input: UserInputPayload) => void | Promise<void>;
281
+ /**
282
+ * Called after Agent.run() completes (or fails/aborts).
283
+ * Receives the final RunResult, always called regardless of outcome.
284
+ */
285
+ type AfterRunHook = (ctx: Context, result: RunResult) => void | Promise<void>;
286
+ /**
287
+ * Called right before each iteration of the agent loop.
288
+ * The context is live (messages, signal, etc.) and can be inspected.
289
+ * Modifications to ctx (e.g. ctx.messages, ctx.model) take effect
290
+ * for the upcoming iteration.
291
+ */
292
+ type BeforeIterationHook = (ctx: Context, iterationIndex: number) => void | Promise<void>;
293
+ /**
294
+ * Called after each iteration completes (tool results appended,
295
+ * compaction done, but before the next loop iteration check).
296
+ */
297
+ type AfterIterationHook = (ctx: Context, iterationIndex: number) => void | Promise<void>;
298
+ /**
299
+ * Called when the agent encounters an error during the provider call
300
+ * or tool execution phase. The hook can return a modified context
301
+ * or signal that recovery should be attempted.
302
+ *
303
+ * Return `{ action: 'retry', model?: string }` to retry the turn
304
+ * (possibly with a different model).
305
+ * Return `{ action: 'fail' }` to propagate the error.
306
+ * Return `{ action: 'continue' }` to skip and continue the loop.
307
+ */
308
+ type OnErrorHook = (ctx: Context, err: unknown, phase: 'provider' | 'tool' | 'agent', iterationIndex: number) => {
309
+ action: 'retry';
310
+ model?: string;
311
+ } | {
312
+ action: 'fail';
313
+ } | {
314
+ action: 'continue';
315
+ } | void | Promise<{
316
+ action: 'retry';
317
+ model?: string;
318
+ } | {
319
+ action: 'fail';
320
+ } | {
321
+ action: 'continue';
322
+ } | void>;
323
+ /**
324
+ * The default provider runner function signature — what the Agent's
325
+ * built-in provider runner looks like. Extensions that wrap the provider
326
+ * runner receive this as the `inner` parameter they can delegate to.
327
+ */
328
+ type ProviderRunnerFn = (ctx: Context, request: Request) => Promise<Response>;
329
+ /**
330
+ * Wrap or replace the provider call in the agent loop.
331
+ *
332
+ * The `inner` function is the default provider runner (with retries).
333
+ * The extension can call it, modify the request/response, add caching,
334
+ * or bypass it entirely.
335
+ */
336
+ type ProviderRunnerWrapper = (ctx: Context, request: Request, inner: ProviderRunnerFn) => Promise<Response>;
337
+ /**
338
+ * Called before a batch of tools is executed. Can modify or reject
339
+ * the tool list. Return the (possibly filtered/modified) tool uses.
340
+ */
341
+ type BeforeToolExecutionHook = (ctx: Context, toolUses: ToolUseBlock[]) => ToolUseBlock[] | Promise<ToolUseBlock[]>;
342
+ /**
343
+ * Called after a batch of tools has been executed and results
344
+ * are available. The extension can inspect or transform results
345
+ * before they're appended to context.
346
+ */
347
+ type AfterToolExecutionHook = (ctx: Context, outputs: ToolExecutionOutput[]) => void | Promise<void>;
348
+ /**
349
+ * An extension registered by a plugin or the host application.
350
+ *
351
+ * Every hook is optional — implement only the phases you need.
352
+ * Hooks are called in registration order. A hook failure is
353
+ * caught, logged, and does not prevent subsequent hooks from running.
354
+ *
355
+ * @example
356
+ * ```ts
357
+ * const myExt: AgentExtension = {
358
+ * name: 'my-plugin-ext',
359
+ * beforeIteration: async (ctx, idx) => {
360
+ * console.log('Starting iteration', idx);
361
+ * },
362
+ * };
363
+ * api.extensions.register(myExt);
364
+ * ```
365
+ */
366
+ interface AgentExtension {
367
+ /** Unique name for this extension. Used in diagnostics and logging. */
368
+ name: string;
369
+ /** Optional owner tag (plugin name or host identifier). */
370
+ owner?: string;
371
+ beforeRun?: BeforeRunHook;
372
+ afterRun?: AfterRunHook;
373
+ beforeIteration?: BeforeIterationHook;
374
+ afterIteration?: AfterIterationHook;
375
+ onError?: OnErrorHook;
376
+ wrapProviderRunner?: ProviderRunnerWrapper;
377
+ beforeToolExecution?: BeforeToolExecutionHook;
378
+ afterToolExecution?: AfterToolExecutionHook;
379
+ }
380
+
381
+ /**
382
+ * ExtensionRegistry — manages AgentExtension registrations.
383
+ *
384
+ * Extensions are called in registration order at each lifecycle phase.
385
+ * Each extension hook failure is caught and logged independently so
386
+ * one bad extension can't take down the agent.
387
+ */
388
+
389
+ declare class ExtensionRegistry {
390
+ private readonly extensions;
391
+ private readonly promptContributors;
392
+ private log;
393
+ setLogger(log: Logger): void;
394
+ /**
395
+ * Register a system prompt contributor. Returns an unregister function.
396
+ * Contributors are called on every system prompt build in registration
397
+ * order. Their output blocks are inserted after the core environment
398
+ * block, before the mode and plan blocks.
399
+ */
400
+ registerSystemPromptContributor(c: SystemPromptContributor): () => void;
401
+ /**
402
+ * Build all registered system prompt contributions.
403
+ * Failures are caught and logged — one bad contributor doesn't
404
+ * break the prompt assembly.
405
+ */
406
+ buildSystemPromptContributions(ctx: Parameters<SystemPromptContributor>[0]): Promise<TextBlock[]>;
407
+ /**
408
+ * Returns the live array of contributors (readonly snapshot for
409
+ * passing to DefaultSystemPromptBuilder at build time).
410
+ */
411
+ listSystemPromptContributors(): readonly SystemPromptContributor[];
412
+ /**
413
+ * Register an extension. Duplicate names are rejected.
414
+ * Returns an unregister function.
415
+ */
416
+ register(ext: AgentExtension): () => void;
417
+ /**
418
+ * Register an extension, silently replacing any previous registration
419
+ * with the same name. Use this when overriding a default extension.
420
+ */
421
+ registerOrReplace(ext: AgentExtension): () => void;
422
+ /**
423
+ * Unregister an extension by name. Returns true if found.
424
+ */
425
+ unregister(name: string): boolean;
426
+ /**
427
+ * List registered extension names in order.
428
+ */
429
+ list(): readonly string[];
430
+ /**
431
+ * Check if an extension with the given name is registered.
432
+ */
433
+ has(name: string): boolean;
434
+ /**
435
+ * Remove all registered extensions and contributors.
436
+ */
437
+ clear(): void;
438
+ runBeforeRun(...args: Parameters<BeforeRunHook>): Promise<void>;
439
+ runAfterRun(...args: Parameters<AfterRunHook>): Promise<void>;
440
+ runBeforeIteration(...args: Parameters<BeforeIterationHook>): Promise<void>;
441
+ runAfterIteration(...args: Parameters<AfterIterationHook>): Promise<void>;
442
+ /**
443
+ * Run onError hooks in order. The first hook that returns a non-void
444
+ * result wins; subsequent hooks are skipped.
445
+ */
446
+ runOnError(...args: Parameters<OnErrorHook>): Promise<{
447
+ action: 'retry';
448
+ model?: string;
449
+ } | {
450
+ action: 'fail';
451
+ } | {
452
+ action: 'continue';
453
+ } | void>;
454
+ /**
455
+ * Build a composed provider runner. Extensions with `wrapProviderRunner`
456
+ * form a middleware-style chain: the innermost extension wraps the
457
+ * default runner, each subsequent wrapper wraps the previous.
458
+ */
459
+ wrapProviderRunner(inner: ProviderRunnerFn): ProviderRunnerFn;
460
+ runBeforeToolExecution(...args: Parameters<BeforeToolExecutionHook>): Promise<Parameters<BeforeToolExecutionHook>[1]>;
461
+ runAfterToolExecution(...args: Parameters<AfterToolExecutionHook>): Promise<void>;
462
+ }
463
+
464
+ /**
465
+ * Factory for constructing a Provider instance. The `family` field
466
+ * declares the wire protocol so callers can route without inspecting
467
+ * the returned instance. The `type` is the registry key (e.g. a
468
+ * provider's models.dev id or a user-chosen alias).
469
+ */
470
+ interface ProviderFactory {
471
+ /**
472
+ * Unique identifier used as the registry key. When registered via
473
+ * a plugin, this becomes `cfg.type` in `ProviderRegistry.create(cfg)`.
474
+ */
475
+ type: string;
476
+ /**
477
+ * Declares the wire protocol family so consumers can route based on
478
+ * capability (e.g. which tool-format converter to use) without
479
+ * instantiating the provider.
480
+ */
481
+ family: WireFamily;
482
+ create(cfg: ProviderConfig): Provider;
483
+ }
484
+ declare class ProviderRegistry {
485
+ private readonly factories;
486
+ /**
487
+ * Register a provider factory. If a factory with the same type already
488
+ * exists, it is replaced. Use this for both initial registration and
489
+ * runtime overrides (e.g. from plugins or CLI flags).
490
+ */
491
+ register(f: ProviderFactory): void;
492
+ /**
493
+ * Bulk-register multiple provider factories at once.
494
+ */
495
+ registerAll(factories: ProviderFactory[]): void;
496
+ /**
497
+ * Override an existing factory. Throws if no factory is registered
498
+ * for the given type. Use this to safely replace a provider at runtime
499
+ * (e.g. in tests or when a plugin provides a custom implementation).
500
+ */
501
+ override(type: string, f: ProviderFactory): void;
502
+ has(type: string): boolean;
503
+ create(cfg: ProviderConfig): Provider;
504
+ list(): string[];
505
+ }
506
+
507
+ /** Default iteration cap. Use 0 or Infinity via config to disable. */
508
+ declare const DEFAULT_MAX_ITERATIONS = 100;
509
+ interface RunResult {
510
+ status: 'done' | 'failed' | 'max_iterations' | 'aborted';
511
+ error?: WrongStackError;
512
+ finalText?: string;
513
+ iterations: number;
514
+ delegateSummaries?: Array<{
515
+ summary: string;
516
+ ok: boolean;
517
+ }>;
518
+ }
519
+ interface AgentInit {
520
+ container: Container;
521
+ tools: ToolRegistry;
522
+ providers: ProviderRegistry;
523
+ events: EventBus;
524
+ pipelines: AgentPipelines;
525
+ context: Context;
526
+ maxIterations?: number;
527
+ iterationTimeoutMs?: number;
528
+ executionStrategy?: 'parallel' | 'sequential' | 'smart';
529
+ perIterationOutputCapBytes?: number;
530
+ autoExtendLimit?: boolean;
531
+ autonomousContinue?: boolean;
532
+ confirmAwaiter?: ConfirmAwaiter | undefined;
533
+ permissionPolicy?: PermissionPolicy;
534
+ tracer?: Tracer | undefined;
535
+ extensions?: ExtensionRegistry | undefined;
536
+ toolExecutor: ToolExecutorLike;
537
+ }
538
+ interface AgentPipelines {
539
+ request: Pipeline<Request>;
540
+ response: Pipeline<Response>;
541
+ toolCall: Pipeline<ToolCallPipelinePayload>;
542
+ userInput: Pipeline<UserInputPayload>;
543
+ assistantOutput: Pipeline<TextBlock>;
544
+ contextWindow: Pipeline<Context>;
545
+ }
546
+ interface UserInputPayload {
547
+ content: ContentBlock[];
548
+ text: string;
549
+ ctx: Context;
550
+ }
551
+ type AgentInput = string | ContentBlock[];
552
+ interface ToolCallPipelinePayload {
553
+ toolUse: ToolUseBlock;
554
+ result: ToolResultBlock;
555
+ ctx: Context;
556
+ tool?: Tool;
557
+ }
558
+ declare function createDefaultPipelines(): AgentPipelines;
559
+
560
+ export { type AfterIterationHook as A, type BeforeIterationHook as B, DEFAULT_MAX_ITERATIONS as D, ExtensionRegistry as E, type HookRunEnv as H, type OnErrorHook as O, type PreToolUseResult as P, type RunResult as R, type SystemPromptContributor as S, type ToolBatchResult as T, type UserInputPayload as U, type AfterRunHook as a, type AfterToolExecutionHook as b, type AgentExtension as c, type AgentInit as d, type AgentInput as e, type AgentPipelines as f, type BeforeRunHook as g, type BeforeToolExecutionHook as h, HookRunner as i, type HookRunnerOptions as j, type PromptResult as k, type ProviderFactory as l, ProviderRegistry as m, type ProviderRunnerFn as n, type ProviderRunnerWrapper as o, type ToolCallPipelinePayload as p, type ToolExecutorLike as q, type ToolExecutorOptions as r, type ToolExecutorStrategy as s, ToolRegistry as t, type ToolWrapper as u, createDefaultPipelines as v };