@rowan-agent/agent 0.4.9 → 0.4.11

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/dist/index.d.cts DELETED
@@ -1,1844 +0,0 @@
1
- import * as _rowan_agent_models from '@rowan-agent/models';
2
- import { LlmRequest, LlmResponse, LlmModelRef, LlmModelUsage, StreamFn, AgentEventListener, ToolCall, ToolResult, AgentMessage, Outcome, Skill as Skill$1, ContentBlock, ProviderConfig, Protocol, ModelCost, AgentEvent, LlmMessage } from '@rowan-agent/models';
3
- export { AgentEvent, AgentEventListener, AgentMessage, LlmModelRef, Outcome, Skill, StreamFn, ToolResult } from '@rowan-agent/models';
4
- import Type from 'typebox';
5
-
6
- type ExecutionTurn = {
7
- id: string;
8
- sessionId: string;
9
- parentSessionId?: string;
10
- phase: string;
11
- requestedAtMs: number;
12
- completedAtMs: number;
13
- model: LlmModelRef;
14
- usage?: LlmModelUsage;
15
- };
16
- type StepFilter = {
17
- phase?: string;
18
- afterMs?: number;
19
- };
20
- /** Raw model input/output for session persistence. */
21
- type ModelTranscript = {
22
- request: LlmRequest;
23
- response: LlmResponse;
24
- };
25
-
26
- type BeforePhaseHook = (phaseId: string, input: PhaseContext) => Promise<BeforePhaseHookResult>;
27
- type AfterPhaseHook = (phaseId: string, output: PhaseOutput) => Promise<AfterPhaseHookResult>;
28
- type BeforePromptHook = (phaseId: string, input: PhaseContext) => Promise<PhaseContext>;
29
- type LoopMetrics = {
30
- /** Number of phase iterations executed. */
31
- iterations: number;
32
- /** Phase transition history. */
33
- phaseTransitions: Array<{
34
- from: string;
35
- to: string;
36
- ts: string;
37
- }>;
38
- /** Number of times compaction was triggered. */
39
- compactionCount: number;
40
- /** Number of retry attempts due to transient errors. */
41
- retryCount: number;
42
- /** Loop start timestamp. */
43
- startedAt: string;
44
- /** Loop start time as epoch ms (for duration calculation). */
45
- startedAtMs: number;
46
- /** Loop end timestamp (set on completion). */
47
- endedAt?: string;
48
- /** Total wall-clock duration in ms. */
49
- durationMs?: number;
50
- };
51
- type SessionState = {
52
- currentPhase: string;
53
- attempt: number;
54
- metrics: LoopMetrics;
55
- status: "idle" | "running" | "completed" | "aborted" | "failed";
56
- };
57
- type AgentConfig = {
58
- context: AgentContext;
59
- sessionId?: string;
60
- model: LlmModelRef;
61
- stream: StreamFn;
62
- signal?: AbortSignal;
63
- emit?: AgentEventListener;
64
- phases?: PhaseRegistry;
65
- runtime?: AgentRuntimePort;
66
- beforeToolCall?: BeforeToolCall;
67
- afterToolCall?: AfterToolCall;
68
- beforePhase?: BeforePhaseHook;
69
- afterPhase?: AfterPhaseHook;
70
- beforePrompt?: BeforePromptHook;
71
- maxAttempts?: number;
72
- onModelTranscript?: (transcript: ModelTranscript, meta: {
73
- phase: string;
74
- model: LlmModelRef;
75
- }) => Promise<void>;
76
- onMessage?: (message: AgentMessage) => Promise<void>;
77
- onOutcome?: (outcome: Outcome) => Promise<void>;
78
- sessionState?: SessionState;
79
- };
80
- type ToolRunnerInput = {
81
- config: AgentConfig;
82
- toolCall: ToolCall;
83
- };
84
- type ToolRunner = (input: ToolRunnerInput) => Promise<ToolResult>;
85
- type AgentRuntimePort = {
86
- tools?: ToolRunner;
87
- };
88
-
89
- type ToolContext = Pick<AgentContext, "skills"> & {
90
- toolCallId: string;
91
- };
92
- type ToolExecutionMode = "sequential" | "parallel";
93
- type Tool<TArgs = unknown> = {
94
- name: string;
95
- description: string;
96
- parameters: Type.TSchema;
97
- /** One-line snippet shown in the system prompt tool list. */
98
- promptSnippet?: string;
99
- /** Additional guidelines appended to the system prompt when this tool is active. */
100
- promptGuidelines?: string[];
101
- /** Whether this tool can run concurrently with others. Default: "parallel". */
102
- executionMode?: ToolExecutionMode;
103
- execute(args: TArgs, context: ToolContext, signal?: AbortSignal): Promise<ToolResult>;
104
- };
105
- /** Context snapshot passed into the low-level agent loop. */
106
- type AgentContext = {
107
- /** System prompt included with the request. */
108
- systemPrompt: string;
109
- /** Transcript visible to the model. */
110
- messages: AgentMessage[];
111
- /** Tools available for this run. */
112
- tools: Tool[];
113
- /** Skills available for this run. */
114
- skills: Skill$1[];
115
- };
116
- type BeforeToolCall = (input: {
117
- tool: Tool;
118
- args: unknown;
119
- }) => Promise<{
120
- allow: true;
121
- } | {
122
- allow: false;
123
- reason: string;
124
- }>;
125
- type AfterToolCall = (input: {
126
- tool: Tool;
127
- result: ToolResult;
128
- }) => Promise<ToolResult>;
129
- type RunResult = {
130
- sessionId: string;
131
- messages: AgentMessage[];
132
- outcome: Outcome;
133
- metrics: LoopMetrics;
134
- };
135
- type Unsubscribe = () => void;
136
- declare function createMessage(role: AgentMessage["role"], content: AgentMessage["content"], metadata?: Record<string, unknown>): AgentMessage;
137
- declare function messageContentText(content: AgentMessage["content"]): string;
138
-
139
- type ModelInvokeOutput = {
140
- text: string;
141
- contentBlocks: ContentBlock[];
142
- toolCalls: ToolCall[];
143
- stopReason?: string;
144
- };
145
- /** Snapshot of phase-level context for restore */
146
- type PhaseContextSnapshot = {
147
- systemPrompt: string;
148
- messages: AgentMessage[];
149
- currentPhase: string;
150
- availablePhases: string[];
151
- turnNumber: number;
152
- payload?: unknown;
153
- };
154
- /** Execution capabilities for a phase — operates on PhaseContext. */
155
- type PhaseExecution = {
156
- snapshot(): PhaseContextSnapshot;
157
- restore(snapshot: PhaseContextSnapshot): void;
158
- invokeModel(context: PhaseContext): Promise<ModelInvokeOutput>;
159
- executeTool(context: AgentContext, toolCall: ToolCall): Promise<ToolResult>;
160
- };
161
-
162
- /** Unified phase output — model decides routing via route. */
163
- type PhaseOutput = {
164
- message: string;
165
- /** Route to next phase, or "continue" to re-execute current phase, or "stop" to end */
166
- route: string;
167
- /** Phase name that produced this output */
168
- phase?: string;
169
- /** Tool calls from the model invocation (used by framework for route extraction) */
170
- toolCalls?: Array<{
171
- id: string;
172
- name: string;
173
- args: unknown;
174
- }>;
175
- /** Route reason extracted from route tool call (for hooks to inspect) */
176
- routeReason?: string;
177
- /** Structured data from this phase, passed to the next phase */
178
- payload?: unknown;
179
- };
180
- /** Phase machine state — tracks position and inter-phase data */
181
- interface PhaseState {
182
- current: string;
183
- available: string[];
184
- iterations: number;
185
- payload?: unknown;
186
- }
187
- /** Everything a phase needs to execute */
188
- interface PhaseContext {
189
- systemPrompt: string;
190
- messages: AgentMessage[];
191
- /** Phase-filtered tools */
192
- tools: Tool[];
193
- /** Phase-filtered skills */
194
- skills: Skill$1[];
195
- /** Phase machine state */
196
- state: PhaseState;
197
- /** Additional guideline bullets appended to the system prompt */
198
- promptGuidelines?: string[];
199
- /** Text to append after the system prompt */
200
- appendSystemPrompt?: string;
201
- }
202
- /**
203
- * Loaded Phase object
204
- */
205
- interface Phase {
206
- /** Unique identifier */
207
- id: string;
208
- /** Display name */
209
- name: string;
210
- /** Description */
211
- description: string;
212
- /** Restricted tools (undefined = all tools available) */
213
- tools?: string[];
214
- /** Restricted skills (undefined = all skills available) */
215
- skills?: string[];
216
- /** Forced next phase */
217
- target?: string;
218
- /** Expected input fields (key → description) */
219
- input?: Record<string, string>;
220
- /** If true, phase gets a fresh context when executed in parallel */
221
- isolated?: boolean;
222
- /** Path to PHASE.md file */
223
- filePath: string;
224
- /** Phase directory path */
225
- baseDir: string;
226
- /** PHASE.md body content */
227
- content: string;
228
- /** Model override for this phase (resolved from frontmatter) */
229
- model?: LlmModelRef;
230
- /** ExtensionAPI factory function (default export pattern) */
231
- factory?: (api: ExtensionAPI) => Promise<void>;
232
- /** Legacy run function */
233
- run?: (context: PhaseContext, execution: PhaseExecution) => Promise<PhaseOutput | void>;
234
- }
235
- /**
236
- * Phase registry containing all loaded phases
237
- */
238
- interface PhaseRegistry {
239
- /** Map of phase id to Phase object */
240
- phases: Map<string, Phase>;
241
- /** Entry phase id (null if no phases defined) */
242
- entryPhaseId: string | null;
243
- }
244
-
245
- /**
246
- * Extension types — simplified for the new hook-based system.
247
- */
248
-
249
- interface SourceInfo {
250
- source: string;
251
- baseDir?: string;
252
- displayName?: string;
253
- }
254
- declare function createSourceInfo(extensionPath: string, options?: {
255
- source?: string;
256
- baseDir?: string;
257
- }): SourceInfo;
258
- /** Phase run function type for extensions */
259
- type PhaseRun = (context: PhaseContext, execution: PhaseExecution) => Promise<PhaseOutput | void>;
260
- /** Phase definition shape used by extensions */
261
- type PhaseDefinition = {
262
- id: string;
263
- name: string;
264
- description: string;
265
- run?: PhaseRun;
266
- tools?: string[];
267
- skills?: string[];
268
- target?: string;
269
- input?: Record<string, string>;
270
- model?: string;
271
- };
272
- type PhaseRegistration = Partial<Omit<PhaseDefinition, 'run'>> & {
273
- /** Optional execution override — takes over model invocation */
274
- run?: PhaseRun;
275
- };
276
- type RegisteredPhase = {
277
- definition: PhaseDefinition;
278
- source: {
279
- extensionPath: string;
280
- };
281
- };
282
- type ExtensionPackageManifest = {
283
- rowan?: {
284
- extensions?: string[];
285
- phase?: {
286
- id?: string;
287
- name?: string;
288
- description?: string;
289
- tools?: string[];
290
- skills?: string[];
291
- };
292
- };
293
- };
294
- /**
295
- * Tool definition for registering LLM-callable tools via `api.registerTool()`.
296
- *
297
- * @example
298
- * ```typescript
299
- * api.registerTool({
300
- * name: "search_docs",
301
- * description: "Search documentation",
302
- * parameters: { type: "object", properties: { query: { type: "string" } } },
303
- * execute: async (args, ctx) => {
304
- * return { content: [{ type: "text", text: "result" }] };
305
- * },
306
- * });
307
- * ```
308
- */
309
- interface ToolDefinition {
310
- /** Tool name (used in LLM tool calls) */
311
- name: string;
312
- /** Description for LLM */
313
- description: string;
314
- /** Parameter schema (JSON Schema) */
315
- parameters: Record<string, unknown>;
316
- /** Execute the tool */
317
- execute: (args: unknown, signal?: AbortSignal) => Promise<ToolExecutionResult>;
318
- /** Optional: per-tool execution mode override */
319
- executionMode?: "sequential" | "parallel";
320
- }
321
- /**
322
- * Result from tool execution.
323
- */
324
- interface ToolExecutionResult {
325
- /** Content blocks to return to the LLM */
326
- content: Array<{
327
- type: string;
328
- text?: string;
329
- [key: string]: unknown;
330
- }>;
331
- /** Whether this is an error result */
332
- isError?: boolean;
333
- }
334
- /**
335
- * Registered tool with source metadata.
336
- */
337
- interface RegisteredTool {
338
- definition: ToolDefinition;
339
- sourceInfo: SourceInfo;
340
- }
341
- /**
342
- * Structured extension error with attribution.
343
- */
344
- interface ExtensionError {
345
- /** Path of the extension that caused the error */
346
- extensionPath: string;
347
- /** Event or operation that caused the error */
348
- event: string;
349
- /** Error message */
350
- error: string;
351
- /** Optional stack trace */
352
- stack?: string;
353
- }
354
- /** Error listener callback type. */
355
- type ExtensionErrorListener = (error: ExtensionError) => void;
356
- type ExecOptions = {
357
- /** Working directory for the command. Defaults to cwd passed to runtime. */
358
- cwd?: string;
359
- /** Environment variables to add/override. */
360
- env?: Record<string, string>;
361
- /** Timeout in milliseconds. */
362
- timeout?: number;
363
- /** AbortSignal for cancellation. */
364
- signal?: AbortSignal;
365
- };
366
- type ExecResult = {
367
- exitCode: number;
368
- stdout: string;
369
- stderr: string;
370
- };
371
- type BeforePhaseHookResult = {
372
- abort?: Outcome;
373
- skip?: {
374
- route: string;
375
- message: string;
376
- };
377
- input?: PhaseContext;
378
- };
379
- type AfterPhaseHookResult = {
380
- abort?: Outcome;
381
- retry?: PhaseContext;
382
- output?: PhaseOutput;
383
- };
384
- type HandlerFn = (...args: unknown[]) => Promise<unknown>;
385
- /**
386
- * Loaded extension with all registered items.
387
- * Tracks what each extension registered for attribution and cleanup.
388
- */
389
- interface Extension {
390
- /** Extension path (may be synthetic like `<builtin:phase:chat>`) */
391
- path: string;
392
- /** Resolved absolute path */
393
- resolvedPath: string;
394
- /** Source info for error messages */
395
- sourceInfo: SourceInfo;
396
- /** Event handlers registered by this extension */
397
- handlers: Map<string, HandlerFn[]>;
398
- /** Tools registered by this extension */
399
- tools: Map<string, RegisteredTool>;
400
- /** Phases registered by this extension */
401
- phases: Map<string, RegisteredPhase>;
402
- }
403
- /**
404
- * Create an Extension object with empty collections.
405
- */
406
- declare function createExtension(extensionPath: string, resolvedPath: string, sourceInfo: SourceInfo): Extension;
407
- /**
408
- * Shared runtime state created by loader, used during registration and runtime.
409
- * All ExtensionAPI instances reference this shared state.
410
- *
411
- * Key features:
412
- * - `invalidate()` / `assertActive()` — prevents stale context usage
413
- * - Pending provider registration queue
414
- * - Shared action implementations replaceable post-bind
415
- */
416
- interface ExtensionRuntime {
417
- /** Throws when this extension instance is stale after runtime replacement. */
418
- assertActive: () => void;
419
- /** Marks this extension instance as stale after runtime replacement or reload. */
420
- invalidate: (message?: string) => void;
421
- /** Provider registrations queued during extension loading, processed when runner binds */
422
- pendingProviderRegistrations: Array<{
423
- name: string;
424
- config: ProviderConfig;
425
- extensionPath: string;
426
- }>;
427
- /**
428
- * Register a provider.
429
- * Before bind(): queues registrations.
430
- * After bind(): calls provider registration directly.
431
- */
432
- registerProvider: (name: string, config: ProviderConfig, extensionPath?: string) => void;
433
- /**
434
- * Unregister a provider.
435
- * Before bind(): removes from queue.
436
- * After bind(): calls provider unregistration directly.
437
- */
438
- unregisterProvider: (name: string, extensionPath?: string) => void;
439
- }
440
- /**
441
- * Create an ExtensionRuntime with throwing stubs.
442
- * Runner.bind() replaces these with real implementations.
443
- */
444
- declare function createExtensionRuntime(): ExtensionRuntime;
445
- /**
446
- * Result of loading extensions from filesystem.
447
- * The runner takes these and creates Extension tracking objects.
448
- */
449
- type LoadExtensionsResult = {
450
- extensions: LoadedExtension[];
451
- errors: Array<{
452
- path: string;
453
- error: string;
454
- }>;
455
- };
456
- /**
457
- * Pre-initialization extension form — factory + metadata.
458
- * Runner.loadExtensions() calls the factory and creates the full Extension object.
459
- */
460
- interface LoadedExtension {
461
- path: string;
462
- resolvedPath: string;
463
- name: string;
464
- factory: ExtensionFactory;
465
- manifest?: ExtensionManifest;
466
- }
467
- /** Extension manifest from package.json `rowan` field. */
468
- interface ExtensionManifest {
469
- entry?: string;
470
- name?: string;
471
- phase?: {
472
- id?: string;
473
- name?: string;
474
- description?: string;
475
- tools?: string[];
476
- skills?: string[];
477
- };
478
- }
479
-
480
- /**
481
- * EventBus — simple pub/sub for inter-extension communication.
482
- *
483
- * Extensions can emit and subscribe to arbitrary events via `api.events`.
484
- * This allows extensions to coordinate without direct coupling.
485
- *
486
- * @example
487
- * ```typescript
488
- * // Extension A
489
- * api.events.on("my-plugin:ready", (data) => {
490
- * console.log("Plugin ready:", data);
491
- * });
492
- *
493
- * // Extension B
494
- * api.events.emit("my-plugin:ready", { version: "1.0" });
495
- * ```
496
- */
497
- type Listener = (...args: unknown[]) => void;
498
- interface EventBus {
499
- /** Subscribe to an event. Returns unsubscribe function. */
500
- on(event: string, listener: Listener): () => void;
501
- /** Emit an event to all subscribers. */
502
- emit(event: string, ...args: unknown[]): void;
503
- /** Remove all listeners for an event, or all listeners if no event specified. */
504
- off(event?: string): void;
505
- /** Check if there are listeners for an event. */
506
- has(event: string): boolean;
507
- /** Get listener count for an event. */
508
- count(event: string): number;
509
- }
510
- declare function createEventBus(): EventBus;
511
-
512
- /**
513
- * @module extensions/hooks
514
- *
515
- * Type-safe hook system
516
- *
517
- * ## Overview
518
- *
519
- * The hook system allows extensions to intercept and modify Agent behavior at specific points.
520
- *
521
- * ## Hook Categories
522
- *
523
- * ### Modifiable (return result to change behavior)
524
- *
525
- * | Hook | Return | Effect |
526
- * |------|--------|--------|
527
- * | `before_phase` | `{ abort?, skip?, input? }` | Abort, skip, or modify phase input |
528
- * | `after_phase` | `{ abort?, retry?, output? }` | Abort, retry, or replace phase output |
529
- * | `before_prompt` | `{ input? }` | Modify input sent to LLM |
530
- * | `before_tool_call` | `{ allow, reason? }` | Allow/block tool execution |
531
- * | `after_tool_call` | `{ result? }` | Modify tool execution result |
532
- *
533
- * ### Listen-only (return void)
534
- *
535
- * | Hook | Trigger |
536
- * |------|---------|
537
- * | `agent_start` | Agent starts |
538
- * | `agent_end` | Agent ends |
539
- * | `turn_start` | Conversation turn starts |
540
- * | `turn_end` | Conversation turn ends |
541
- * | `message_start` | Message streaming starts |
542
- * | `message_update` | Message streaming update |
543
- * | `message_end` | Message completes |
544
- * | `tool_execution_start` | Tool execution starts |
545
- * | `tool_execution_update` | Tool execution progress update |
546
- * | `tool_execution_end` | Tool execution completes |
547
- * | `queue_update` | Queue state update |
548
- * | `save_point` | Session save point |
549
- * | `abort` | Agent aborted |
550
- * | `settled` | Agent idle |
551
- *
552
- * ## Usage Example
553
- *
554
- * ```typescript
555
- * import type { ExtensionAPI } from "@rowan-agent/agent";
556
- *
557
- * export default function(api: ExtensionAPI) {
558
- * // Block dangerous tools
559
- * api.on("before_tool_call", (event) => {
560
- * if (event.tool.name === "bash") {
561
- * const cmd = (event.args as any).command;
562
- * if (cmd.includes("rm -rf")) {
563
- * return { allow: false, reason: "Dangerous command" };
564
- * }
565
- * }
566
- * return { allow: true };
567
- * });
568
- *
569
- * // Inject context
570
- * api.on("before_prompt", (event) => {
571
- * return {
572
- * input: {
573
- * ...event.input,
574
- * systemPrompt: event.input.systemPrompt + "\n\nExtra context",
575
- * },
576
- * };
577
- * });
578
- *
579
- * // Log tool calls
580
- * api.on("tool_execution_end", (event) => {
581
- * console.log(`Tool ${event.toolName}: ${event.result.ok ? "success" : "failed"}`);
582
- * });
583
- * }
584
- * ```
585
- */
586
-
587
- /**
588
- * before_phase event - triggered before phase execution
589
- *
590
- * Return `{ abort }` to abort the agent.
591
- * Return `{ skip: { route, message } }` to skip the phase.
592
- * Return `{ input }` to replace the phase input.
593
- */
594
- interface BeforePhaseEvent {
595
- type: "before_phase";
596
- /** Phase ID about to execute */
597
- phaseId: string;
598
- /** Phase input */
599
- input: PhaseContext;
600
- }
601
- /**
602
- * after_phase event - triggered after phase execution
603
- *
604
- * Return `{ abort }` to abort the agent.
605
- * Return `{ retry }` to re-execute the phase with new input.
606
- * Return `{ output }` to replace the phase output.
607
- */
608
- interface AfterPhaseEvent {
609
- type: "after_phase";
610
- /** Phase ID that completed */
611
- phaseId: string;
612
- /** Phase output */
613
- output: PhaseOutput;
614
- }
615
- /**
616
- * before_prompt event - triggered before building LLM request
617
- *
618
- * Return `{ input }` to replace the input sent to LLM.
619
- */
620
- interface BeforePromptEvent {
621
- type: "before_prompt";
622
- /** Current phase ID */
623
- phaseId: string;
624
- /** Phase input (modifiable) */
625
- input: PhaseContext;
626
- }
627
- /**
628
- * before_tool_call event - triggered before tool execution
629
- *
630
- * Return `{ allow: false, reason }` to block execution.
631
- * Return `{ allow: true }` to allow execution.
632
- */
633
- interface BeforeToolCallEvent {
634
- type: "before_tool_call";
635
- /** Tool definition */
636
- tool: Tool;
637
- /** Tool arguments */
638
- args: unknown;
639
- }
640
- /**
641
- * after_tool_call event - triggered after tool execution
642
- *
643
- * Return `{ result }` to replace the tool execution result.
644
- */
645
- interface AfterToolCallEvent {
646
- type: "after_tool_call";
647
- /** Tool definition */
648
- tool: Tool;
649
- /** Tool execution result */
650
- result: ToolResult;
651
- }
652
- /**
653
- * agent_start event - triggered when agent starts
654
- */
655
- interface AgentStartEvent {
656
- type: "agent_start";
657
- /** Session ID */
658
- sessionId: string;
659
- }
660
- /**
661
- * agent_end event - triggered when agent ends
662
- */
663
- interface AgentEndEvent {
664
- type: "agent_end";
665
- /** Session ID */
666
- sessionId: string;
667
- /** Execution outcome */
668
- outcome: Outcome;
669
- /** All messages */
670
- messages: AgentMessage[];
671
- }
672
- /**
673
- * turn_start event - triggered when conversation turn starts
674
- */
675
- interface TurnStartEvent {
676
- type: "turn_start";
677
- /** Current message list */
678
- messages: AgentMessage[];
679
- }
680
- /**
681
- * turn_end event - triggered when conversation turn ends
682
- */
683
- interface TurnEndEvent {
684
- type: "turn_end";
685
- /** Message list */
686
- messages: AgentMessage[];
687
- /** Turn outcome (optional) */
688
- outcome?: Outcome;
689
- }
690
- /**
691
- * message_start event - triggered when message streaming starts
692
- */
693
- interface MessageStartEvent {
694
- type: "message_start";
695
- /** Message object */
696
- message: AgentMessage;
697
- }
698
- /**
699
- * message_update event - triggered on message streaming update
700
- */
701
- interface MessageUpdateEvent {
702
- type: "message_update";
703
- /** Message object */
704
- message: AgentMessage;
705
- /** Delta text */
706
- delta: string;
707
- }
708
- /**
709
- * message_end event - triggered when message completes
710
- */
711
- interface MessageEndEvent {
712
- type: "message_end";
713
- /** Message object */
714
- message: AgentMessage;
715
- }
716
- /**
717
- * tool_execution_start event - triggered when tool execution starts
718
- */
719
- interface ToolExecutionStartEvent {
720
- type: "tool_execution_start";
721
- /** Tool call ID */
722
- toolCallId: string;
723
- /** Tool name */
724
- toolName: string;
725
- /** Tool arguments */
726
- args: unknown;
727
- }
728
- /**
729
- * tool_execution_update event - triggered on tool execution progress
730
- */
731
- interface ToolExecutionUpdateEvent {
732
- type: "tool_execution_update";
733
- /** Tool call ID */
734
- toolCallId: string;
735
- /** Tool name */
736
- toolName: string;
737
- }
738
- /**
739
- * tool_execution_end event - triggered when tool execution completes
740
- */
741
- interface ToolExecutionEndEvent {
742
- type: "tool_execution_end";
743
- /** Tool call ID */
744
- toolCallId: string;
745
- /** Tool name */
746
- toolName: string;
747
- /** Tool execution result */
748
- result: ToolResult;
749
- }
750
- /**
751
- * queue_update event - triggered on queue state update
752
- */
753
- interface QueueUpdateEvent {
754
- type: "queue_update";
755
- /** Pending message count */
756
- pendingCount: number;
757
- }
758
- /**
759
- * save_point event - triggered at session save point
760
- */
761
- interface SavePointEvent {
762
- type: "save_point";
763
- /** Whether there are pending mutations */
764
- hadPendingMutations: boolean;
765
- }
766
- /**
767
- * abort event - triggered when agent is aborted
768
- */
769
- interface AbortEvent {
770
- type: "abort";
771
- /** Abort reason */
772
- reason?: string;
773
- }
774
- /**
775
- * settled event - triggered when agent is idle
776
- */
777
- interface SettledEvent {
778
- type: "settled";
779
- }
780
- /** Union type of all hook events */
781
- type HookEvent = BeforePhaseEvent | AfterPhaseEvent | BeforePromptEvent | BeforeToolCallEvent | AfterToolCallEvent | AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent | QueueUpdateEvent | SavePointEvent | AbortEvent | SettledEvent;
782
- /**
783
- * before_phase hook return value
784
- *
785
- * - `abort`: Abort the entire agent
786
- * - `skip`: Skip current phase, route to specified phase
787
- * - `input`: Replace phase input
788
- */
789
- interface BeforePhaseResult {
790
- /** Abort agent */
791
- abort?: Outcome;
792
- /** Skip current phase */
793
- skip?: {
794
- route: string;
795
- message: string;
796
- };
797
- /** Replace phase input */
798
- input?: PhaseContext;
799
- }
800
- /**
801
- * after_phase hook return value
802
- *
803
- * - `abort`: Abort the entire agent
804
- * - `retry`: Re-execute phase with new input
805
- * - `output`: Replace phase output
806
- */
807
- interface AfterPhaseResult {
808
- /** Abort agent */
809
- abort?: Outcome;
810
- /** Re-execute phase */
811
- retry?: PhaseContext;
812
- /** Replace phase output */
813
- output?: PhaseOutput;
814
- }
815
- /**
816
- * before_prompt hook return value
817
- *
818
- * - `input`: Replace input sent to LLM
819
- */
820
- interface BeforePromptResult {
821
- /** Replace phase input */
822
- input?: PhaseContext;
823
- }
824
- /**
825
- * before_tool_call hook return value
826
- *
827
- * - `allow`: Whether to allow execution
828
- * - `reason`: Rejection reason (when allow=false)
829
- */
830
- interface BeforeToolCallResult {
831
- /** Whether to allow execution */
832
- allow: boolean;
833
- /** Rejection reason */
834
- reason?: string;
835
- }
836
- /**
837
- * after_tool_call hook return value
838
- *
839
- * - `result`: Replace tool execution result
840
- */
841
- interface AfterToolCallResult {
842
- /** Replace tool execution result */
843
- result?: ToolResult;
844
- }
845
- /**
846
- * Hook result mapping table.
847
- *
848
- * Defines the return type for each hook event:
849
- * - Modifiable hooks return specific objects
850
- * - Listen-only hooks return undefined
851
- */
852
- interface HookResultMap {
853
- before_phase: BeforePhaseResult | undefined;
854
- after_phase: AfterPhaseResult | undefined;
855
- before_prompt: BeforePromptResult | undefined;
856
- before_tool_call: BeforeToolCallResult | undefined;
857
- after_tool_call: AfterToolCallResult | undefined;
858
- agent_start: undefined;
859
- agent_end: undefined;
860
- turn_start: undefined;
861
- turn_end: undefined;
862
- message_start: undefined;
863
- message_update: undefined;
864
- message_end: undefined;
865
- tool_execution_start: undefined;
866
- tool_execution_update: undefined;
867
- tool_execution_end: undefined;
868
- queue_update: undefined;
869
- save_point: undefined;
870
- abort: undefined;
871
- settled: undefined;
872
- }
873
- /** Hook event type string */
874
- type HookEventType = HookEvent["type"];
875
- /**
876
- * Hook handler type.
877
- *
878
- * @typeParam K - Hook event type
879
- * @param event - Event object
880
- * @returns Result object or void
881
- */
882
- type HookHandler<K extends HookEventType> = (event: Extract<HookEvent, {
883
- type: K;
884
- }>) => HookResultMap[K] | Promise<HookResultMap[K]> | void | Promise<void>;
885
- /**
886
- * Hook execution error
887
- */
888
- declare class HookError extends Error {
889
- /** Event type that caused the error */
890
- readonly eventType: string;
891
- constructor(
892
- /** Event type that caused the error */
893
- eventType: string, message: string, cause?: Error);
894
- }
895
- /**
896
- * Type-safe hook manager.
897
- *
898
- * ## Usage
899
- *
900
- * ```typescript
901
- * const hooks = new HooksManager();
902
- *
903
- * // Register hook
904
- * hooks.on("before_tool_call", (event) => {
905
- * return { allow: false, reason: "Blocked" };
906
- * });
907
- *
908
- * // Emit event (listen-only)
909
- * await hooks.emit("agent_start", { type: "agent_start", sessionId: "123" });
910
- *
911
- * // Emit event and collect result
912
- * const result = await hooks.emitFirst("before_tool_call", { type: "before_tool_call", tool, args });
913
- * ```
914
- */
915
- declare class HooksManager {
916
- private handlers;
917
- /**
918
- * Register a hook handler.
919
- * Handlers execute in registration order.
920
- *
921
- * @param eventType - Event type
922
- * @param handler - Handler function
923
- */
924
- on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
925
- /**
926
- * Unregister a hook handler.
927
- */
928
- off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
929
- /**
930
- * Clear all handlers, or clear handlers for specified event type.
931
- */
932
- clear(eventType?: HookEventType): void;
933
- /**
934
- * Check if there are handlers registered for specified event type.
935
- */
936
- has(eventType: HookEventType): boolean;
937
- /**
938
- * Get handler count for specified event type.
939
- */
940
- count(eventType: HookEventType): number;
941
- /**
942
- * Emit event (listen-only, ignore return values).
943
- * Errors are collected and thrown.
944
- *
945
- * @param eventType - Event type
946
- * @param event - Event object
947
- */
948
- emit<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
949
- type: K;
950
- }>): Promise<void>;
951
- /**
952
- * Emit event and return first non-undefined result (short-circuit).
953
- *
954
- * @param eventType - Event type
955
- * @param event - Event object
956
- * @returns First non-undefined result, or undefined
957
- */
958
- emitFirst<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
959
- type: K;
960
- }>): Promise<HookResultMap[K] | undefined>;
961
- }
962
- /**
963
- * Get global hooks manager instance (singleton).
964
- */
965
- declare function getGlobalHooks(): HooksManager;
966
- /**
967
- * Reset global hooks manager (mainly for testing).
968
- */
969
- declare function resetGlobalHooks(): void;
970
-
971
- /**
972
- * @module extensions/context
973
- *
974
- * Extension context types — runtime state and phase execution context.
975
- *
976
- * For ExtensionAPI and createExtensionAPI, see ./api.ts
977
- */
978
-
979
- /**
980
- * Runtime context available to extensions during event handler execution.
981
- *
982
- * Provides access to agent state, working directory, and utility methods.
983
- * Values are resolved lazily via getters, so changes via `runner.bind()` are
984
- * reflected immediately without recreating the context.
985
- *
986
- * @example
987
- * ```typescript
988
- * api.on("before_tool_call", (event, ctx) => {
989
- * console.log(`cwd: ${ctx.cwd}`);
990
- * if (ctx.isIdle()) { ... }
991
- * });
992
- * ```
993
- */
994
- interface ExtensionContext {
995
- /** Current working directory */
996
- cwd: string;
997
- /** Abort signal — fires when the agent operation is cancelled */
998
- signal: AbortSignal | undefined;
999
- /** Whether the agent is currently idle (not streaming) */
1000
- isIdle(): boolean;
1001
- /** Abort the current agent operation */
1002
- abort(): void;
1003
- /**
1004
- * Execute a shell command.
1005
- *
1006
- * @param command - The command to run
1007
- * @param args - Command arguments
1008
- * @param options - Execution options (cwd, env, timeout, signal)
1009
- * @returns Execution result with exitCode, stdout, stderr
1010
- */
1011
- exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
1012
- /** Extension manifest from package.json `rowan` field */
1013
- manifest?: ExtensionManifest;
1014
- /** Current model ID, if available */
1015
- modelId?: string;
1016
- /** Get current system prompt */
1017
- getSystemPrompt?(): string;
1018
- /** Set/override the system prompt */
1019
- setSystemPrompt?(prompt: string): void;
1020
- /** Get the full message history */
1021
- getMessages?(): Array<{
1022
- role: string;
1023
- content: string;
1024
- }>;
1025
- /** Append a message to the history */
1026
- addMessage?(role: "user" | "assistant" | "system", content: string): void;
1027
- /** Get all available tools */
1028
- getAvailableTools?(): Array<{
1029
- name: string;
1030
- description: string;
1031
- }>;
1032
- /** Get all available skills */
1033
- getAvailableSkills?(): Array<{
1034
- name: string;
1035
- description: string;
1036
- }>;
1037
- /** Get skill content by name */
1038
- getSkillContent?(skillName: string): string;
1039
- /** Get all available phase IDs */
1040
- getAvailablePhases?(): string[];
1041
- /** Get phase content by ID */
1042
- getPhaseContent?(phaseId: string): string;
1043
- }
1044
- /**
1045
- * Utility functions available to extensions.
1046
- */
1047
- interface ExtensionUtils {
1048
- /**
1049
- * Generate unique ID.
1050
- * @param prefix - ID prefix
1051
- * @returns Format: `{prefix}_{timestamp}_{counter}`
1052
- */
1053
- createId(prefix: string): string;
1054
- /**
1055
- * JSON serialization (with indentation).
1056
- * @param value - Value to serialize
1057
- * @returns JSON string
1058
- */
1059
- formatJson(value: unknown): string;
1060
- }
1061
-
1062
- /**
1063
- * Extension API object passed to extension factory function.
1064
- *
1065
- * @example
1066
- * ```typescript
1067
- * export default function(api: ExtensionAPI) {
1068
- * // api provides all extension APIs
1069
- * }
1070
- * ```
1071
- */
1072
- interface ExtensionAPI {
1073
- /**
1074
- * Subscribe to a hook event.
1075
- *
1076
- * @param eventType - Hook type, e.g. "before_tool_call"
1077
- * @param handler - Hook handler, can return result to modify behavior
1078
- */
1079
- on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
1080
- /** Unsubscribe from a hook event. */
1081
- off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
1082
- /** Register a custom LLM-callable tool. */
1083
- registerTool(tool: ToolDefinition): void;
1084
- /** Register a custom phase. */
1085
- registerPhase(registration: PhaseRegistration): void;
1086
- /** Register a model provider. */
1087
- registerProvider(config: _rowan_agent_models.ProviderConfig): void;
1088
- /** Unregister a model provider. */
1089
- unregisterProvider(name: string): void;
1090
- /** Extension manifest from package.json `rowan` field. */
1091
- manifest?: ExtensionManifest;
1092
- /** Utility functions. */
1093
- utils: ExtensionUtils;
1094
- /** Runtime context — cwd, signal, exec, message access, etc. */
1095
- context: ExtensionContext;
1096
- /** Shared event bus for inter-extension communication. */
1097
- events: EventBus;
1098
- /** Session context — provides access to the session-level AgentContext. */
1099
- session: {
1100
- /** Get the current session AgentContext */
1101
- getContext(): AgentContext;
1102
- };
1103
- /** Phase execution capabilities — rovides Phase In/Out, phase identity, and phase routing. */
1104
- phase: {
1105
- /** Phase In: get payload from previous phase */
1106
- getPayload(): unknown;
1107
- /** Phase Out: set payload for next phase */
1108
- setPayload(payload: unknown): void;
1109
- /** Phase Out: set outcome message */
1110
- setMessage(message: string): void;
1111
- /** Get current phase id */
1112
- getCurrentPhase(): string;
1113
- /** Set next phase (lower priority than PHASE.md target) */
1114
- setNextPhase(phaseId: string): void;
1115
- /** Get the next phase set by setNextPhase */
1116
- getNextPhase(): string | undefined;
1117
- /** Get the message set by setMessage */
1118
- getMessage(): string | undefined;
1119
- };
1120
- }
1121
- /**
1122
- * Extension factory function.
1123
- * Receives ExtensionAPI for registering hooks, phases, and providers.
1124
- */
1125
- type ExtensionFactory = (api: ExtensionAPI) => void | Promise<void>;
1126
- /**
1127
- * @internal
1128
- * Create ExtensionAPI instance.
1129
- * Works for both extension context (with hooks/runtime/eventBus) and phase context (without).
1130
- */
1131
- declare function createExtensionAPI(hooks?: HooksManager, _extensionPath?: string, options?: {
1132
- registerPhase?: (registration: PhaseRegistration) => void;
1133
- registerProvider?: (config: _rowan_agent_models.ProviderConfig) => void;
1134
- unregisterProvider?: (name: string) => void;
1135
- registerTool?: (tool: ToolDefinition) => void;
1136
- context?: ExtensionContext;
1137
- manifest?: ExtensionManifest;
1138
- phase?: PhaseContext;
1139
- session?: AgentContext;
1140
- }, runtime?: ExtensionRuntime, eventBus?: EventBus): ExtensionAPI;
1141
-
1142
- /**
1143
- * Extension runner — manages extension loading and hook execution.
1144
- *
1145
- * Architecture reference: PI's ExtensionRunner
1146
- * - Per-extension tracking via Extension objects
1147
- * - Shared ExtensionRuntime with invalidate/assertActive
1148
- * - Direct `on()` API for hook registration
1149
- * - Error listener pattern for structured error handling
1150
- * - Tool registration support
1151
- */
1152
-
1153
- type ExtensionRunnerOptions = {
1154
- entryPhaseId?: string | null;
1155
- cwd?: string;
1156
- };
1157
- /**
1158
- * Manages extensions and provides hooks for the agent loop.
1159
- *
1160
- * Features:
1161
- * - Per-extension tracking (handlers, tools, phases)
1162
- * - Shared runtime with lifecycle protection (invalidate/assertActive)
1163
- * - Error listener pattern for structured error handling
1164
- * - Direct hook API and extension-loaded hook API
1165
- * - Tool registration for LLM-callable tools
1166
- * - EventBus for inter-extension communication
1167
- *
1168
- * @example
1169
- * ```ts
1170
- * const runner = createExtensionRunner();
1171
- *
1172
- * // Direct hook registration
1173
- * const unsub = runner.on("before_tool_call", (event) => {
1174
- * return { allow: false, reason: "Blocked" };
1175
- * });
1176
- *
1177
- * // Error handling
1178
- * runner.onError((error) => {
1179
- * console.error(`Extension error in ${error.extensionPath}:`, error.error);
1180
- * });
1181
- *
1182
- * // Load extensions
1183
- * await runner.loadExtensions(extensions);
1184
- * runner.bind();
1185
- * ```
1186
- */
1187
- declare class ExtensionRunner {
1188
- readonly hooks: HooksManager;
1189
- readonly runtime: ExtensionRuntime;
1190
- readonly events: EventBus;
1191
- private readonly cwd;
1192
- private readonly abortController;
1193
- private _idle;
1194
- private readonly extensions;
1195
- private readonly phases;
1196
- private _phaseCache;
1197
- private readonly pendingProviders;
1198
- private bound;
1199
- private readonly errorListeners;
1200
- private readonly loadedExtensions;
1201
- /** Current agent context — set by the agent before each phase */
1202
- currentContext?: AgentContext;
1203
- constructor(options?: ExtensionRunnerOptions);
1204
- /** Whether the agent is currently idle (not streaming). */
1205
- get isIdle(): boolean;
1206
- /** Set idle state — called by the agent loop. */
1207
- setIdle(idle: boolean): void;
1208
- /** Abort signal for the current runner instance. */
1209
- get signal(): AbortSignal;
1210
- /** Abort the current runner operation. */
1211
- abort(): void;
1212
- /**
1213
- * Register an error listener.
1214
- * Returns an unsubscribe function.
1215
- */
1216
- onError(listener: ExtensionErrorListener): () => void;
1217
- /**
1218
- * Emit a structured extension error to all listeners.
1219
- */
1220
- emitError(error: ExtensionError): void;
1221
- /**
1222
- * Mark all extension contexts as stale.
1223
- * After calling this, any captured ExtensionAPI or ExtensionContext will throw
1224
- * on use. Used during session replacement or reload.
1225
- */
1226
- invalidate(message?: string): void;
1227
- /**
1228
- * Subscribe to a specific hook event type.
1229
- * Returns an unsubscribe function.
1230
- *
1231
- * @example
1232
- * ```ts
1233
- * const unsub = runner.on("before_tool_call", (event) => {
1234
- * return { allow: false, reason: "Blocked" };
1235
- * });
1236
- * unsub(); // Cancel subscription
1237
- * ```
1238
- */
1239
- on<K extends HookEventType>(type: K, handler: HookHandler<K>): () => void;
1240
- /**
1241
- * Subscribe to all events (read-only).
1242
- * Returns an unsubscribe function.
1243
- *
1244
- * @example
1245
- * ```ts
1246
- * const unsub = runner.subscribe((event) => {
1247
- * console.log(event.type);
1248
- * });
1249
- * ```
1250
- */
1251
- subscribe(listener: (event: {
1252
- type: HookEventType;
1253
- }) => void): () => void;
1254
- private getAllEventTypes;
1255
- /**
1256
- * Load and initialize extensions.
1257
- * Creates Extension tracking objects and calls each factory with an ExtensionAPI.
1258
- */
1259
- loadExtensions(extensions: LoadedExtension[]): Promise<void>;
1260
- /**
1261
- * Get all registered tools from all extensions (first registration per name wins).
1262
- */
1263
- getAllRegisteredTools(): RegisteredTool[];
1264
- /**
1265
- * Get a tool definition by name. Returns undefined if not found.
1266
- */
1267
- getToolDefinition(toolName: string): RegisteredTool["definition"] | undefined;
1268
- /**
1269
- * Check if there are handlers registered for specified event type.
1270
- */
1271
- hasHandlers(eventType: HookEventType): boolean;
1272
- /**
1273
- * Get the number of handlers for specified event type.
1274
- */
1275
- handlerCount(eventType: HookEventType): number;
1276
- getPhase(id: string): Phase | undefined;
1277
- getPhases(): Phase[];
1278
- createPhaseRegistry(input?: {
1279
- entryPhaseId?: string | null;
1280
- }): PhaseRegistry;
1281
- /** Adapt an extension RegisteredPhase to the core Phase type. */
1282
- private adaptToPhase;
1283
- /**
1284
- * Bind the runner — flushes pending provider registrations and
1285
- * replaces runtime stubs with real implementations.
1286
- */
1287
- bind(): void;
1288
- /**
1289
- * Generic emit — fire-and-forget for any event type.
1290
- */
1291
- emit<K extends HookEventType>(eventType: K, event: Parameters<HookHandler<K>>[0]): Promise<void>;
1292
- /**
1293
- * Unified hook emission — returns the first non-undefined result.
1294
- */
1295
- private emitHook;
1296
- emitBeforePhase(phaseId: string, input: PhaseContext): Promise<{
1297
- abort?: any;
1298
- skip?: any;
1299
- input?: PhaseContext;
1300
- }>;
1301
- emitAfterPhase(phaseId: string, output: PhaseOutput): Promise<{
1302
- abort?: any;
1303
- retry?: PhaseContext;
1304
- output?: PhaseOutput;
1305
- }>;
1306
- emitBeforePrompt(phaseId: string, input: PhaseContext): Promise<PhaseContext>;
1307
- emitBeforeToolCall(tool: Tool, args: unknown): Promise<{
1308
- allow: boolean;
1309
- reason?: string;
1310
- }>;
1311
- emitAfterToolCall(tool: Tool, result: ToolResult): Promise<ToolResult>;
1312
- emitAgentStart(sessionId: string): Promise<void>;
1313
- emitAgentEnd(sessionId: string, outcome: any, messages: any[]): Promise<void>;
1314
- emitTurnStart(messages: any[]): Promise<void>;
1315
- emitTurnEnd(messages: any[], outcome?: any): Promise<void>;
1316
- emitMessageStart(message: any): Promise<void>;
1317
- emitMessageUpdate(message: any, delta: string): Promise<void>;
1318
- emitMessageEnd(message: any): Promise<void>;
1319
- emitToolExecutionStart(toolCallId: string, toolName: string, args: unknown): Promise<void>;
1320
- emitToolExecutionUpdate(toolCallId: string, toolName: string, _progress?: string): Promise<void>;
1321
- emitToolExecutionEnd(toolCallId: string, toolName: string, result: ToolResult): Promise<void>;
1322
- emitSavePoint(hadPendingMutations: boolean): Promise<void>;
1323
- emitAbort(reason?: string): Promise<void>;
1324
- emitSettled(): Promise<void>;
1325
- /**
1326
- * Emit an AgentEvent by routing to the appropriate typed hook.
1327
- */
1328
- emitAgentEvent(event: any): Promise<void>;
1329
- /**
1330
- * Create an ExtensionAPI for a specific extension.
1331
- * Registration methods write to the extension tracking object.
1332
- * Action methods delegate to the shared runtime.
1333
- */
1334
- private createExtensionAPI;
1335
- private registerTool;
1336
- private registerPhase;
1337
- private registerProvider;
1338
- private unregisterProvider;
1339
- private flushPendingProviders;
1340
- private getRegisteredPhase;
1341
- private collectRegisteredPhases;
1342
- }
1343
- declare function createExtensionRunner(options?: ExtensionRunnerOptions): ExtensionRunner;
1344
-
1345
- /**
1346
- * Extension loader — discovers and loads extensions from the filesystem.
1347
- *
1348
- * Uses the new LoadedExtension type that works with ExtensionRunner.
1349
- */
1350
-
1351
- /**
1352
- * Load a single extension from a factory function.
1353
- */
1354
- declare function loadExtensionFromFactory(factory: ExtensionFactory, cwd: string, extensionPath?: string): LoadedExtension;
1355
- /**
1356
- * Load extensions from file paths.
1357
- */
1358
- declare function loadExtensions(paths: string[], cwd: string): Promise<{
1359
- extensions: LoadedExtension[];
1360
- errors: Array<{
1361
- path: string;
1362
- error: string;
1363
- }>;
1364
- }>;
1365
- /**
1366
- * Discover and load extensions from .rowan/extensions directory.
1367
- */
1368
- declare function discoverAndLoadExtensions(cwd: string): Promise<{
1369
- extensions: LoadedExtension[];
1370
- errors: Array<{
1371
- path: string;
1372
- error: string;
1373
- }>;
1374
- }>;
1375
-
1376
- type ExtensionRunnerRef = {
1377
- current?: ExtensionRunner;
1378
- };
1379
- type AgentOptions = {
1380
- context: AgentContext;
1381
- model: LlmModelRef;
1382
- stream: StreamFn;
1383
- cwd?: string;
1384
- rowanDir?: string;
1385
- phases?: PhaseRegistry;
1386
- extensionRunnerRef?: ExtensionRunnerRef;
1387
- sessionId?: string;
1388
- maxAttempts?: number;
1389
- beforeToolCall?: BeforeToolCall;
1390
- afterToolCall?: AfterToolCall;
1391
- onMessage?: (message: AgentMessage) => Promise<void>;
1392
- onOutcome?: (outcome: Outcome) => Promise<void>;
1393
- onModelTranscript?: (transcript: ModelTranscript, meta: {
1394
- phase: string;
1395
- model: LlmModelRef;
1396
- }) => Promise<void>;
1397
- };
1398
- type RunOptions = Partial<AgentConfig> & Pick<AgentConfig, "context">;
1399
- type AgentStatus = {
1400
- sessionId?: string;
1401
- context: AgentContext;
1402
- model: LlmModelRef;
1403
- tools: Tool[];
1404
- isRunning: boolean;
1405
- currentResult?: RunResult;
1406
- error?: string;
1407
- };
1408
- declare class Agent {
1409
- readonly state: AgentStatus;
1410
- private options;
1411
- private readonly listeners;
1412
- private readonly pendingListenerTasks;
1413
- private readonly listenerErrors;
1414
- private activeRun?;
1415
- constructor(options: AgentOptions);
1416
- subscribe(listener: AgentEventListener): Unsubscribe;
1417
- private emitToListeners;
1418
- flushEvents(): Promise<void>;
1419
- private processEvents;
1420
- /**
1421
- * Hook for before_tool_call — called before a tool executes.
1422
- * Extensions can block execution by setting allow=false.
1423
- */
1424
- private handleBeforeToolCall;
1425
- /**
1426
- * Hook for after_tool_call — called after a tool executes.
1427
- * Extensions can mutate the result.
1428
- */
1429
- private handleAfterToolCall;
1430
- /**
1431
- * Hook for before_phase — called before a phase executes.
1432
- * Extensions can abort, skip, or replace the phase input.
1433
- */
1434
- private handleBeforePhase;
1435
- /**
1436
- * Hook for after_phase — called after a phase executes.
1437
- * Extensions can abort, retry, or replace the output.
1438
- */
1439
- private handleAfterPhase;
1440
- /**
1441
- * Hook for before_prompt — called before model request, allowing extensions to transform PhaseContext.
1442
- * Extensions can transform the PhaseContext (messages, tools, systemPrompt, etc.).
1443
- */
1444
- private handleBeforePrompt;
1445
- private handleRunFailure;
1446
- /**
1447
- * Discover and load phases and skills from the workspace.
1448
- *
1449
- * - Auto-discovers file-based phases from .rowan/phases/
1450
- * - Auto-discovers skills from .rowan/skills/
1451
- * - Merges with CLI-provided phases and skills
1452
- */
1453
- private discoverResources;
1454
- private runWithLifecycle;
1455
- private finishRun;
1456
- run(config?: RunOptions): Promise<RunResult>;
1457
- abort(reason?: string): void;
1458
- /**
1459
- * Get formatted skill content for LLM consumption.
1460
- *
1461
- * Finds the skill by name and returns the formatted content using `formatSkillInvocation`.
1462
- * This is a programmatic API for developers to invoke skills directly.
1463
- *
1464
- * @param name - The skill name to look up
1465
- * @param additionalInstructions - Optional additional instructions to append
1466
- * @returns Formatted skill content string
1467
- */
1468
- skill(name: string, additionalInstructions?: string): string;
1469
- /**
1470
- * Get formatted phase content for LLM consumption.
1471
- *
1472
- * Finds the phase by name and returns the formatted content.
1473
- * This is a programmatic API for developers to invoke phases directly.
1474
- *
1475
- * @param name - The phase name to look up
1476
- * @returns Formatted phase content string, or empty string if not found
1477
- */
1478
- phase(name: string): Promise<string>;
1479
- waitForIdle(): Promise<void>;
1480
- private resolveRunConfig;
1481
- private createContextSnapshot;
1482
- }
1483
-
1484
- declare function createId(prefix: string): string;
1485
- declare function createTimestamp(date?: Date): string;
1486
-
1487
- declare const SkillSchema: Type.TObject<{
1488
- name: Type.TString;
1489
- description: Type.TString;
1490
- filePath: Type.TString;
1491
- baseDir: Type.TString;
1492
- content: Type.TString;
1493
- disableModelInvocation: Type.TBoolean;
1494
- }>;
1495
- type Skill = Type.Static<typeof SkillSchema>;
1496
- type Session<TLogEvent = never> = {
1497
- version: string;
1498
- id: string;
1499
- parentSessionId?: string;
1500
- systemPrompt: string;
1501
- input: string;
1502
- messages: AgentMessage[];
1503
- log: TLogEvent[];
1504
- skills: Skill[];
1505
- createdAt: string;
1506
- updatedAt: string;
1507
- title?: string;
1508
- };
1509
- declare function createSession<TLogEvent = never>(input: {
1510
- id?: string;
1511
- systemPrompt: string;
1512
- input: string;
1513
- skills?: Skill[];
1514
- parentSessionId?: string;
1515
- title?: string;
1516
- }): Session<TLogEvent>;
1517
- declare function appendUserTurn<TLogEvent>(session: Session<TLogEvent>, input: string): Session<TLogEvent>;
1518
-
1519
- type SessionHeader = {
1520
- type: "header";
1521
- id: string;
1522
- version: string;
1523
- createdAt: string;
1524
- updatedAt: string;
1525
- systemPrompt: string;
1526
- input: string;
1527
- parentSessionId?: string;
1528
- skills: Skill[];
1529
- title?: string;
1530
- currentLeafId?: string | null;
1531
- };
1532
- type SessionEntryBase = {
1533
- id: string;
1534
- parentId: string | null;
1535
- timestamp: string;
1536
- };
1537
- type MessageSessionEntry = SessionEntryBase & {
1538
- type: "message";
1539
- message: AgentMessage;
1540
- };
1541
- type OutcomeSessionEntry = SessionEntryBase & {
1542
- type: "outcome";
1543
- outcome: Outcome;
1544
- };
1545
- type ExecutionTurnSessionEntry = SessionEntryBase & {
1546
- type: "execution_turn";
1547
- turn: ExecutionTurn;
1548
- };
1549
- type CompactionSessionEntry = SessionEntryBase & {
1550
- type: "compaction";
1551
- summary: string;
1552
- firstKeptEntryId: string;
1553
- };
1554
- type BranchSummarySessionEntry = SessionEntryBase & {
1555
- type: "branch_summary";
1556
- fromId: string;
1557
- summary: string;
1558
- };
1559
- type SessionInfoSessionEntry = SessionEntryBase & {
1560
- type: "session_info";
1561
- title: string;
1562
- };
1563
- type CustomSessionEntry = SessionEntryBase & {
1564
- type: "custom";
1565
- customType: string;
1566
- data: unknown;
1567
- };
1568
- type SessionStateSessionEntry = SessionEntryBase & {
1569
- type: "session_state";
1570
- state: SessionState;
1571
- };
1572
- type ModelTranscriptSessionEntry = SessionEntryBase & {
1573
- type: "model_transcript";
1574
- transcript: ModelTranscript;
1575
- phase?: string;
1576
- model?: LlmModelRef;
1577
- };
1578
- type SessionEntry = MessageSessionEntry | OutcomeSessionEntry | ExecutionTurnSessionEntry | CompactionSessionEntry | BranchSummarySessionEntry | SessionInfoSessionEntry | CustomSessionEntry | SessionStateSessionEntry | ModelTranscriptSessionEntry;
1579
- type SessionAgentContext<TTool = unknown> = {
1580
- systemPrompt: string;
1581
- messages: AgentMessage[];
1582
- tools: TTool[];
1583
- skills: Skill[];
1584
- };
1585
- type BuildAgentContextInput<TTool = unknown> = {
1586
- leafId?: string | null;
1587
- tools?: TTool[];
1588
- skills?: Skill[];
1589
- };
1590
- type CreateSessionManagerInput = {
1591
- id?: string;
1592
- systemPrompt: string;
1593
- input: string;
1594
- parentSessionId?: string;
1595
- skills?: Skill[];
1596
- title?: string;
1597
- };
1598
- type SessionListItem = {
1599
- id: string;
1600
- title?: string;
1601
- createdAt: string;
1602
- updatedAt: string;
1603
- messageCount: number;
1604
- latestMessage?: string;
1605
- };
1606
- type SessionManager = {
1607
- getSessionId(): string;
1608
- getSessionFile(): string | undefined;
1609
- getHeader(): Promise<SessionHeader>;
1610
- appendMessage(message: AgentMessage): Promise<string>;
1611
- appendOutcome(outcome: Outcome): Promise<string>;
1612
- appendExecutionTurn(turn: ExecutionTurn): Promise<string>;
1613
- appendCompaction(input: {
1614
- summary: string;
1615
- firstKeptEntryId: string;
1616
- }): Promise<string>;
1617
- appendBranchSummary(input: {
1618
- fromId: string;
1619
- summary: string;
1620
- }): Promise<string>;
1621
- appendSessionInfo(input: {
1622
- title: string;
1623
- }): Promise<string>;
1624
- appendCustom(input: {
1625
- customType: string;
1626
- data: unknown;
1627
- }): Promise<string>;
1628
- appendSessionState(state: SessionState): Promise<string>;
1629
- appendModelTranscript(transcript: ModelTranscript, meta?: {
1630
- phase?: string;
1631
- model?: LlmModelRef;
1632
- }): Promise<string>;
1633
- getSessionState(): Promise<SessionState | undefined>;
1634
- branch(entryId: string | null): Promise<void>;
1635
- buildAgentContext<TTool = unknown>(input?: BuildAgentContextInput<TTool>): Promise<SessionAgentContext<TTool>>;
1636
- listEntries(): Promise<SessionEntry[]>;
1637
- loadExecutionTurns(filter?: StepFilter): Promise<ExecutionTurn[]>;
1638
- };
1639
-
1640
- declare class LocalJsonlSessionManager implements SessionManager {
1641
- private readonly sessionsDir;
1642
- private readonly filePath;
1643
- private readonly inner;
1644
- private constructor();
1645
- static create(sessionsDir: string, input: CreateSessionManagerInput): Promise<LocalJsonlSessionManager>;
1646
- static open(sessionsDir: string, id: string): Promise<LocalJsonlSessionManager | undefined>;
1647
- static list(sessionsDir: string): Promise<SessionListItem[]>;
1648
- static delete(sessionsDir: string, id: string): Promise<boolean>;
1649
- getSessionId(): string;
1650
- getSessionFile(): string | undefined;
1651
- getHeader(): Promise<SessionHeader>;
1652
- appendMessage(message: AgentMessage): Promise<string>;
1653
- appendOutcome(outcome: Outcome): Promise<string>;
1654
- appendExecutionTurn(turn: ExecutionTurn): Promise<string>;
1655
- appendCompaction(input: {
1656
- summary: string;
1657
- firstKeptEntryId: string;
1658
- }): Promise<string>;
1659
- appendBranchSummary(input: {
1660
- fromId: string;
1661
- summary: string;
1662
- }): Promise<string>;
1663
- appendSessionInfo(input: {
1664
- title: string;
1665
- }): Promise<string>;
1666
- appendCustom(input: {
1667
- customType: string;
1668
- data: unknown;
1669
- }): Promise<string>;
1670
- appendSessionState(state: SessionState): Promise<string>;
1671
- appendModelTranscript(transcript: ModelTranscript, meta?: {
1672
- phase?: string;
1673
- model?: LlmModelRef;
1674
- }): Promise<string>;
1675
- getSessionState(): Promise<SessionState | undefined>;
1676
- branch(entryId: string | null): Promise<void>;
1677
- buildAgentContext<TTool = unknown>(input?: BuildAgentContextInput<TTool>): Promise<SessionAgentContext<TTool>>;
1678
- listEntries(): Promise<SessionEntry[]>;
1679
- loadExecutionTurns(filter?: StepFilter): Promise<ExecutionTurn[]>;
1680
- private appendThroughInner;
1681
- }
1682
-
1683
- type CoreToolContext = {
1684
- root?: string;
1685
- maxReadBytes?: number;
1686
- bashTimeoutMs?: number;
1687
- maxBashOutputBytes?: number;
1688
- };
1689
- declare function createCoreTools(input?: CoreToolContext): Tool[];
1690
-
1691
- type RuntimeMode = "source" | "binary";
1692
- type WorkspacePaths = {
1693
- mode: RuntimeMode;
1694
- cwd: string;
1695
- rowanDir: string;
1696
- };
1697
- type ResolveWorkspaceOptions = {
1698
- cwd?: string;
1699
- env?: NodeJS.ProcessEnv;
1700
- execPath?: string;
1701
- entrypoint?: string;
1702
- homeDir?: string;
1703
- mode?: RuntimeMode;
1704
- rowanDir?: string;
1705
- };
1706
- declare function resolveWorkspacePaths(options?: ResolveWorkspaceOptions): WorkspacePaths;
1707
- declare function resolveInWorkspace(path: string, rootOrPaths: string | Pick<WorkspacePaths, "cwd">): string;
1708
-
1709
- declare function resolveSkillPath(input: string, workspace?: WorkspacePaths): string;
1710
- declare function loadSkill(path: string, workspace?: WorkspacePaths): Promise<Skill$1>;
1711
- declare function loadSkills(workspace?: WorkspacePaths, paths?: string[]): Promise<Skill$1[]>;
1712
-
1713
- type ModelConfigFromFile = {
1714
- id: string;
1715
- name?: string;
1716
- primary?: boolean;
1717
- reasoning?: boolean;
1718
- input?: ("text" | "image")[];
1719
- contextWindow?: number;
1720
- maxTokens?: number;
1721
- cost?: Partial<ModelCost>;
1722
- };
1723
- type ProviderConfigFromFile = {
1724
- id: string;
1725
- name?: string;
1726
- baseUrl: string;
1727
- apiKey: string;
1728
- protocol: Protocol;
1729
- timeoutMs?: number;
1730
- maxRetries?: number;
1731
- retryDelayMs?: number;
1732
- headers?: Record<string, string>;
1733
- models: ModelConfigFromFile[];
1734
- };
1735
- type AgentConfigFile = {
1736
- model?: {
1737
- provider: string;
1738
- id: string;
1739
- };
1740
- logLevel?: "debug" | "info" | "warn" | "error" | "silent";
1741
- providers: ProviderConfigFromFile[];
1742
- };
1743
- declare function interpolateEnvVars(value: string): string;
1744
- declare function loadConfigFile(workspace: WorkspacePaths): Promise<AgentConfigFile | undefined>;
1745
- declare function resolveDefaultModel(config: AgentConfigFile): LlmModelRef | undefined;
1746
- declare function registerConfigModels(config: AgentConfigFile): void;
1747
- declare function parseModelRef(input?: string): LlmModelRef | undefined;
1748
-
1749
- /**
1750
- * Push-based async iterable with a final result.
1751
- *
1752
- * Producers call `push(event)` to deliver events. Consumers iterate with
1753
- * `for await (const event of stream)`. The stream terminates when an event
1754
- * matches the `isComplete` predicate; `result()` resolves with the extracted
1755
- * final value.
1756
- */
1757
- declare class EventStream<T, R = T> implements AsyncIterable<T> {
1758
- private queue;
1759
- private waiting;
1760
- private done;
1761
- private finalResultPromise;
1762
- private resolveFinalResult;
1763
- private isComplete;
1764
- private extractResult;
1765
- constructor(isComplete: (event: T) => boolean, extractResult: (event: T) => R);
1766
- push(event: T): void;
1767
- end(result?: R): void;
1768
- [Symbol.asyncIterator](): AsyncIterator<T>;
1769
- result(): Promise<R>;
1770
- }
1771
- /**
1772
- * Agent-level event stream that terminates on `agent_end`.
1773
- * `result()` resolves with the final messages array.
1774
- */
1775
- declare class AgentEventStream extends EventStream<AgentEvent, AgentMessage[]> {
1776
- constructor();
1777
- }
1778
-
1779
- /**
1780
- * Load all phases from .rowan/phases directory.
1781
- *
1782
- * Scans for subdirectories containing PHASE.md files.
1783
- * Returns PhaseRegistry with entryPhaseId:
1784
- * - null by default (caller must explicitly set to start from a specific phase)
1785
- * - Set to a specific phase id to start from that phase
1786
- *
1787
- * When entryPhaseId is null, AgentLoop starts from "none" phase.
1788
- */
1789
- declare function loadPhases(workspace?: WorkspacePaths, paths?: string[]): Promise<PhaseRegistry>;
1790
-
1791
- interface SystemPromptOptions {
1792
- /** Base system prompt. */
1793
- systemPrompt: string;
1794
- /** Additional guideline bullets appended to the default runtime instructions. */
1795
- promptGuidelines?: string[];
1796
- /** Text to append after the default runtime instructions. */
1797
- appendSystemPrompt?: string;
1798
- /** Active tools — snippets and guidelines are included in the prompt. */
1799
- tools?: Array<{
1800
- name: string;
1801
- description?: string;
1802
- promptSnippet?: string;
1803
- promptGuidelines?: string[];
1804
- }>;
1805
- /** Loaded skills — serialized into the prompt. */
1806
- skills?: Array<{
1807
- name: string;
1808
- description: string;
1809
- filePath: string;
1810
- disableModelInvocation?: boolean;
1811
- }>;
1812
- /** Working directory. */
1813
- cwd?: string;
1814
- }
1815
- declare function buildSystemPrompt(options: SystemPromptOptions): string;
1816
-
1817
- declare function serializeSkills(skills: Skill$1[]): Array<{
1818
- name: string;
1819
- description: string;
1820
- filePath: string;
1821
- disableModelInvocation?: boolean;
1822
- }>;
1823
- declare function latestUserInput(messages: AgentMessage[]): string;
1824
- declare function conversationMessages(messages: AgentMessage[]): LlmMessage[];
1825
- /** Input for building an LLM request — generic, not phase-specific. */
1826
- type ModelRequestInput = {
1827
- systemPrompt: string;
1828
- messages: AgentMessage[];
1829
- tools: Array<{
1830
- name: string;
1831
- description: string;
1832
- parameters: unknown;
1833
- promptSnippet?: string;
1834
- promptGuidelines?: string[];
1835
- }>;
1836
- skills: Skill$1[];
1837
- promptGuidelines?: string[];
1838
- appendSystemPrompt?: string;
1839
- };
1840
- declare function buildModelRequest(input: ModelRequestInput, options?: {
1841
- model?: LlmModelRef;
1842
- }): LlmRequest;
1843
-
1844
- export { type AbortEvent, type AfterPhaseEvent, type AfterPhaseHookResult, type AfterPhaseResult, type AfterToolCallEvent, type AfterToolCallResult, Agent, type AgentConfigFile, type AgentContext, type AgentEndEvent, AgentEventStream, type AgentOptions, type AgentStartEvent, type AgentStatus, type BeforePhaseEvent, type BeforePhaseHookResult, type BeforePhaseResult, type BeforePromptEvent, type BeforePromptResult, type BeforeToolCallEvent, type BeforeToolCallResult, type EventBus, EventStream, type ExecOptions, type ExecResult, type ExecutionTurn, type Extension, type ExtensionAPI, type ExtensionContext, type ExtensionError, type ExtensionErrorListener, type ExtensionFactory, type ExtensionManifest, type ExtensionPackageManifest, ExtensionRunner, type ExtensionRunnerOptions, type ExtensionRunnerRef, type ExtensionRuntime, type ExtensionUtils, HookError, type HookEvent, type HookEventType, type HookHandler, type HookResultMap, HooksManager, type LoadExtensionsResult, type LoadedExtension, LocalJsonlSessionManager, type LoopMetrics, type MessageEndEvent, type MessageStartEvent, type MessageUpdateEvent, type ModelConfigFromFile, type ModelTranscript, type Phase, type PhaseContext, type PhaseDefinition, type PhaseExecution, type PhaseOutput, type PhaseRegistration, type PhaseRegistry, type PhaseRun, type PhaseState, type ProviderConfigFromFile, type QueueUpdateEvent, type RegisteredPhase, type RegisteredTool, type RunOptions, type RunResult, type SavePointEvent, type Session, type SessionListItem, type SettledEvent, type SourceInfo, type Tool, type ToolDefinition, type ToolExecutionEndEvent, type ToolExecutionResult, type ToolExecutionStartEvent, type ToolExecutionUpdateEvent, type TurnEndEvent, type TurnStartEvent, type WorkspacePaths, appendUserTurn, buildModelRequest, buildSystemPrompt, conversationMessages, createCoreTools, createEventBus, createExtension, createExtensionAPI, createExtensionRunner, createExtensionRuntime, createId, createMessage, createSession, createSourceInfo, createTimestamp, discoverAndLoadExtensions, getGlobalHooks, interpolateEnvVars, latestUserInput, loadConfigFile, loadExtensionFromFactory, loadExtensions, loadPhases, loadSkill, loadSkills, messageContentText, parseModelRef, registerConfigModels, resetGlobalHooks, resolveDefaultModel, resolveInWorkspace, resolveSkillPath, resolveWorkspacePaths, serializeSkills };