@rowan-agent/agent 0.12.1 → 0.13.1

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.ts CHANGED
@@ -83,7 +83,8 @@ type ExecutionState = {
83
83
  metrics: LoopMetrics;
84
84
  status: "idle" | "running" | "suspended" | "completed" | "aborted" | "failed";
85
85
  continuation?: ExecutionContinuationState;
86
- phaseInteractions?: PhaseInteractionState;
86
+ runInteractions?: RunInteractionState;
87
+ phaseInteractions?: RunInteractionState;
87
88
  };
88
89
  type ExecutionContinuationState = {
89
90
  isContinuing: boolean;
@@ -96,36 +97,46 @@ type ExecutionContinuationState = {
96
97
  previousPhaseMessageId?: string;
97
98
  };
98
99
 
99
- type PhaseInteractionKind = "user_input" | "permission" | "elicitation" | "confirmation";
100
- type PhaseInteractionStatus = "pending" | "answered" | "denied" | "cancelled" | "expired";
101
- type PhaseInteractionOrigin = "tool_call" | "phase";
102
- type PhaseInteraction = Readonly<{
100
+ type RunInteractionKind = "user_input" | "permission" | "elicitation" | "confirmation";
101
+ type RunInteractionStatus = "pending" | "answered" | "replied" | "cancelled";
102
+ type RunInteraction = Readonly<{
103
103
  id: string;
104
104
  phase: string;
105
- kind: PhaseInteractionKind;
105
+ kind: RunInteractionKind;
106
106
  prompt: string;
107
107
  payload?: JsonValue;
108
108
  createdAt: string;
109
- status: PhaseInteractionStatus;
110
- origin?: PhaseInteractionOrigin;
109
+ status: RunInteractionStatus;
110
+ answer?: JsonValue;
111
+ reply?: string;
112
+ toolCallId?: string;
113
+ result?: Readonly<{
114
+ answered?: string;
115
+ replied?: string;
116
+ cancelled?: string;
117
+ }>;
118
+ }>;
119
+ type RunInteractionRequest = Readonly<{
120
+ id?: string;
121
+ kind: RunInteractionKind;
122
+ prompt: string;
123
+ payload?: JsonValue;
111
124
  toolCallId?: string;
125
+ result?: Readonly<{
126
+ answered?: string;
127
+ replied?: string;
128
+ cancelled?: string;
129
+ }>;
112
130
  }>;
113
- type PhaseInteractionState = Readonly<{
114
- requests: readonly PhaseInteraction[];
131
+ type RunInteractionState = Readonly<{
132
+ requests: readonly RunInteraction[];
115
133
  answers: Readonly<Record<string, JsonValue>>;
116
134
  checkpoint?: JsonValue;
117
135
  }>;
118
- type PhaseInteractionDriver = Readonly<{
136
+ type RunInteractionDriver = Readonly<{
119
137
  signal: AbortSignal;
120
- request(input: Readonly<{
121
- id?: string;
122
- kind: PhaseInteractionKind;
123
- prompt: string;
124
- payload?: JsonValue;
125
- origin?: PhaseInteractionOrigin;
126
- toolCallId?: string;
127
- }>): PhaseInteraction;
128
- pending(): readonly PhaseInteraction[];
138
+ request(input: RunInteractionRequest): RunInteraction;
139
+ pending(): readonly RunInteraction[];
129
140
  answers(): ReadonlyMap<string, JsonValue>;
130
141
  checkpoint(): JsonValue | undefined;
131
142
  clearCheckpoint(): void;
@@ -133,18 +144,16 @@ type PhaseInteractionDriver = Readonly<{
133
144
  checkpoint?: JsonValue;
134
145
  }>): never;
135
146
  }>;
136
- declare class PhaseInteractionCancelledError extends Error {
137
- readonly code: "phase_interaction_cancelled";
147
+ declare class RunInteractionCancelledError extends Error {
148
+ readonly code: "run_interaction_cancelled";
138
149
  constructor();
139
150
  }
140
- declare class PhaseInteractionBoundary extends Error {
151
+ declare class RunInteractionBoundary extends Error {
141
152
  readonly state: ExecutionState;
142
- readonly interactions: readonly PhaseInteraction[];
143
- constructor(state: ExecutionState, interactions: readonly PhaseInteraction[]);
153
+ readonly interactions: readonly RunInteraction[];
154
+ constructor(state: ExecutionState, interactions: readonly RunInteraction[]);
144
155
  }
145
156
 
146
- /** Durable and transient DTOs owned by the event-driven Agent Runtime. */
147
-
148
157
  declare const opaqueIdBrand: unique symbol;
149
158
  type OpaqueId<Kind extends string> = string & {
150
159
  readonly [opaqueIdBrand]: Kind;
@@ -152,7 +161,6 @@ type OpaqueId<Kind extends string> = string & {
152
161
  type AgentId = OpaqueId<"AgentId">;
153
162
  type RunId = OpaqueId<"RunId">;
154
163
  type MessageId = OpaqueId<"MessageId">;
155
- type InputRequestId = OpaqueId<"InputRequestId">;
156
164
  type ToolCallId = OpaqueId<"ToolCallId">;
157
165
  type EventId = OpaqueId<"EventId">;
158
166
  type ExecutionId = OpaqueId<"ExecutionId">;
@@ -236,7 +244,23 @@ type ToolMessage = MessageBase & Readonly<{
236
244
  role: "tool";
237
245
  content: ToolMessageContent;
238
246
  }>;
239
- type Message = UserMessage | AssistantMessage | ToolMessage;
247
+ type InteractionRecord = MessageBase & Readonly<{
248
+ role: "interaction";
249
+ interactionId: string;
250
+ kind: "user_input" | "permission" | "elicitation" | "confirmation";
251
+ prompt: string;
252
+ phase: string;
253
+ status: "answered" | "replied" | "cancelled";
254
+ answer?: JsonValue;
255
+ reply?: string;
256
+ toolCallId?: ToolCallId;
257
+ result?: Readonly<{
258
+ answered?: string;
259
+ replied?: string;
260
+ cancelled?: string;
261
+ }>;
262
+ }>;
263
+ type Message = UserMessage | AssistantMessage | ToolMessage | InteractionRecord;
240
264
  type Outcome = Readonly<{
241
265
  id: OutcomeId;
242
266
  message: string;
@@ -325,6 +349,12 @@ type DurableEventBase = Readonly<{
325
349
  metadata?: Metadata;
326
350
  createdAt: string;
327
351
  }>;
352
+ type PhaseEntered = DurableEventBase & Readonly<{
353
+ kind: "phase_entered";
354
+ executionId: ExecutionId;
355
+ phaseId: string;
356
+ visit: number;
357
+ }>;
328
358
  type MessageCommitted = DurableEventBase & Readonly<{
329
359
  kind: "message_committed";
330
360
  message: Message;
@@ -353,12 +383,7 @@ type RunStateChanged = DurableEventBase & (Readonly<{
353
383
  kind: "run_state_changed";
354
384
  from: "running";
355
385
  to: "input_required";
356
- request?: Readonly<{
357
- id: InputRequestId;
358
- phase: string;
359
- prompt?: AssistantMessage;
360
- }>;
361
- interactions: readonly PhaseInteraction[];
386
+ interactions: readonly RunInteraction[];
362
387
  answers: Readonly<Record<string, JsonValue>>;
363
388
  }> | Readonly<{
364
389
  kind: "run_state_changed";
@@ -409,6 +434,24 @@ type ToolStateChanged = DurableEventBase & (Readonly<{
409
434
  toolCall: Extract<ToolCallSnapshot, {
410
435
  state: "failed";
411
436
  }>;
437
+ }> | Readonly<{
438
+ kind: "tool_state_changed";
439
+ transition: Readonly<{
440
+ from: "running";
441
+ to: "pending";
442
+ }>;
443
+ toolCall: Extract<ToolCallSnapshot, {
444
+ state: "pending";
445
+ }>;
446
+ }> | Readonly<{
447
+ kind: "tool_state_changed";
448
+ transition: Readonly<{
449
+ from: "running";
450
+ to: "pending";
451
+ }>;
452
+ toolCall: Extract<ToolCallSnapshot, {
453
+ state: "pending";
454
+ }>;
412
455
  }> | Readonly<{
413
456
  kind: "tool_state_changed";
414
457
  transition: Readonly<{
@@ -437,7 +480,7 @@ type ToolStateChanged = DurableEventBase & (Readonly<{
437
480
  state: "indeterminate";
438
481
  }>;
439
482
  }>);
440
- type DurableRunEvent = MessageCommitted | MessageRevised | RunStateChanged | ToolStateChanged;
483
+ type DurableRunEvent = PhaseEntered | MessageCommitted | MessageRevised | RunStateChanged | ToolStateChanged;
441
484
  type MessageDelta = Readonly<{
442
485
  kind: "message_delta";
443
486
  durability: "transient";
@@ -500,7 +543,7 @@ type PhaseExecution = {
500
543
  reportStatus(status: PhaseStatus): Promise<void>;
501
544
  executeTool(context: AgentContext, toolCall: ToolCall): Promise<ToolResult>;
502
545
  executeTools(context: AgentContext, toolCalls: readonly ToolCall[]): Promise<readonly ToolResult[]>;
503
- interaction: PhaseInteractionDriver;
546
+ interaction: RunInteractionDriver;
504
547
  /** Message lifecycle manager for streaming updates from programmatic phases */
505
548
  messages: PhaseMessageManager;
506
549
  };
@@ -522,131 +565,108 @@ type PhaseMessageManager = {
522
565
  discard(messageId: string): void;
523
566
  };
524
567
 
525
- /**
526
- * Extension types — simplified for the new hook-based system.
527
- */
528
-
529
- interface SourceInfo {
530
- source: string;
531
- baseDir?: string;
532
- displayName?: string;
533
- }
534
- /** Register a Phase by directory path or Phase object; PHASE.md and direct child Skills are loaded atomically when a path is supplied. */
535
- type PhaseRegistration = string | Phase;
536
- /**
537
- * Tool definition for registering LLM-callable tools via `api.tool.register()`.
538
- *
539
- * @example
540
- * ```typescript
541
- * api.tool.register({
542
- * name: "search_docs",
543
- * description: "Search documentation",
544
- * parameters: { type: "object", properties: { query: { type: "string" } } },
545
- * execute: async (args, ctx) => {
546
- * return { content: [{ type: "text", text: "result" }] };
547
- * },
548
- * });
549
- * ```
550
- */
551
- interface ToolDefinition {
552
- /** Tool name (used in LLM tool calls) */
568
+ type PhaseRegistrySelection = Readonly<{
569
+ entryPhaseId: string | null;
570
+ phaseIds: readonly string[];
571
+ }>;
572
+ type AgentDefinition = Readonly<{
553
573
  name: string;
554
- /** Description for LLM */
555
574
  description: string;
556
- /** Parameter schema (JSON Schema) */
557
- parameters: Record<string, unknown>;
558
- /** Execute the tool */
559
- execute: (args: unknown, signal?: AbortSignal) => Promise<ToolExecutionResult>;
560
- /** Optional: per-tool execution mode override */
561
- executionMode?: "sequential" | "parallel";
562
- }
563
- /**
564
- * Result from tool execution.
565
- */
566
- interface ToolExecutionResult {
567
- /** Content blocks to return to the LLM */
568
- content: Array<{
569
- type: string;
570
- text?: string;
571
- [key: string]: unknown;
572
- }>;
573
- /** Whether this is an error result */
574
- isError?: boolean;
575
- }
576
- /**
577
- * Registered tool with source metadata.
578
- */
579
- interface RegisteredTool {
580
- definition: ToolDefinition;
581
- sourceInfo: SourceInfo;
582
- }
583
- /**
584
- * Structured extension error with attribution.
585
- */
586
- interface ExtensionError {
587
- /** Path of the extension that caused the error */
588
- extensionPath: string;
589
- /** Event or operation that caused the error */
590
- event: string;
591
- /** Error message */
592
- error: string;
593
- /** Optional stack trace */
594
- stack?: string;
575
+ prompt: string;
576
+ tools?: readonly string[];
577
+ skills?: readonly string[];
578
+ /** Host-supplied Skills private to this Agent Definition/Bundle. */
579
+ bundledSkills?: readonly Skill[];
580
+ phases?: PhaseRegistrySelection;
581
+ contexts?: readonly string[];
582
+ model?: ModelRef;
583
+ }>;
584
+ /** Parse one Markdown definition using the same frontmatter vocabulary as Phase resources. */
585
+ declare function parseAgentDefinition(raw: string): AgentDefinition;
586
+
587
+ type ResourceKind = "agent" | "tool" | "skill" | "phase";
588
+ type ResourceSourceId = string;
589
+ /** Rowan-native contribution aliases. Hosts may adapt their domain handlers to
590
+ * these existing Tool/Phase lifecycles without importing host Scope types. */
591
+ type ToolContribution = Tool$1;
592
+ type PhaseContribution = Phase;
593
+ type ResourceView = Readonly<{
594
+ agents: readonly ResourceSourceId[];
595
+ tools: readonly ResourceSourceId[];
596
+ skills: readonly ResourceSourceId[];
597
+ phases: readonly ResourceSourceId[];
598
+ }>;
599
+ type ResourceRef = Readonly<{
600
+ kind: ResourceKind;
601
+ sourceId: ResourceSourceId;
602
+ name: string;
603
+ }>;
604
+ type ResourceDiagnostic = Readonly<{
605
+ kind: "invalid" | "missing" | "collision";
606
+ sourceId: ResourceSourceId;
607
+ message: string;
608
+ path?: string;
609
+ }>;
610
+ type LoadResult = Readonly<{
611
+ revision: string;
612
+ registered: readonly ResourceRef[];
613
+ skipped: readonly ResourceDiagnostic[];
614
+ }>;
615
+ type LoadInput<T> = Readonly<{
616
+ sourceId: ResourceSourceId;
617
+ directory?: string;
618
+ values?: readonly T[];
619
+ }>;
620
+ type ResolvedResourceView = Readonly<{
621
+ agents: readonly AgentDefinition[];
622
+ tools: readonly Tool$1[];
623
+ skills: readonly Skill[];
624
+ phases: readonly Phase[];
625
+ revisions: Readonly<Record<ResourceKind, readonly string[]>>;
626
+ refs: Readonly<Record<ResourceKind, readonly ResourceRef[]>>;
627
+ }>;
628
+ type ResourceRegistryErrorCode = "invalid_source_id" | "invalid_resource_name" | "resource_collision" | "resource_input_missing" | "resource_directory_not_supported" | "unknown_resource_source" | "implicit_source_protected";
629
+ declare class ResourceRegistryError extends Error {
630
+ readonly code: ResourceRegistryErrorCode;
631
+ constructor(code: ResourceRegistryErrorCode, message: string);
595
632
  }
596
- /** Error listener callback type. */
597
- type ExtensionErrorListener = (error: ExtensionError) => void;
598
- type ExecOptions = {
599
- /** Working directory for the command. Defaults to cwd passed to runtime. */
600
- cwd?: string;
601
- /** Environment variables to add/override. */
602
- env?: Record<string, string>;
603
- /** Timeout in milliseconds. */
604
- timeout?: number;
605
- /** AbortSignal for cancellation. */
606
- signal?: AbortSignal;
607
- };
608
- type ExecResult = {
609
- exitCode: number;
610
- stdout: string;
611
- stderr: string;
612
- };
633
+ type RegistryValue = AgentDefinition | Tool$1 | Skill | Phase;
613
634
  /**
614
- * Shared runtime state created by loader, used during registration and runtime.
615
- * All ExtensionAPI instances reference this shared state.
635
+ * Runtime Resource Registry source transaction and view resolver.
616
636
  *
617
- * It only owns the lifetime guard shared by captured Extension API objects.
618
- */
619
- interface ExtensionRuntime {
620
- /** Throws when this extension instance is stale after runtime replacement. */
621
- assertActive: () => void;
622
- /** Marks this extension instance as stale after runtime replacement or reload. */
623
- invalidate: (message?: string) => void;
624
- }
625
- /**
626
- * Result of loading extensions from filesystem.
627
- * The runner takes these and creates Extension tracking objects.
628
- */
629
- type LoadExtensionsResult = {
630
- extensions: LoadedExtension[];
631
- errors: Array<{
632
- path: string;
633
- error: string;
634
- }>;
635
- };
636
- /**
637
- * Pre-initialization extension form — factory + metadata.
638
- * Runner.loadExtensions() calls the factory and creates the full Extension object.
637
+ * Directory normalization is intentionally added by the typed loader slice;
638
+ * this first module owns only the atomic source/revision/collision semantics.
639
639
  */
640
- interface LoadedExtension {
641
- path: string;
642
- name: string;
643
- factory: ExtensionFactory;
644
- manifest?: ExtensionManifest;
645
- }
646
- /** Extension manifest from package.json `rowan` field. */
647
- interface ExtensionManifest {
648
- entry?: string;
649
- name?: string;
640
+ declare class ResourceRegistry {
641
+ private readonly sources;
642
+ /** Sources registered by the bootstrap boundary (currently Extensions). */
643
+ private readonly implicitSources;
644
+ private revisionSequence;
645
+ loadAgents(input: LoadInput<AgentDefinition>): Promise<LoadResult>;
646
+ loadSkills(input: LoadInput<Skill>): Promise<LoadResult>;
647
+ loadPhases(input: LoadInput<Phase>): Promise<LoadResult>;
648
+ loadTools(input: Readonly<{
649
+ sourceId: ResourceSourceId;
650
+ values: readonly ToolContribution[];
651
+ }>): Promise<LoadResult>;
652
+ unload(input: Readonly<{
653
+ kind: ResourceKind;
654
+ sourceId: ResourceSourceId;
655
+ }>): Promise<LoadResult>;
656
+ resolveView(view: ResourceView): ResolvedResourceView;
657
+ /** Mark one already-loaded source as implicit for every Resource View. */
658
+ protected markImplicit(kind: ResourceKind, sourceId: ResourceSourceId): void;
659
+ /** Bootstrap-only helper for replacing an implicit contribution source. */
660
+ protected replaceImplicit<T extends RegistryValue>(kind: ResourceKind, sourceId: ResourceSourceId, values: readonly T[]): Promise<LoadResult>;
661
+ protected hasImplicit(kind: ResourceKind, sourceId: ResourceSourceId): boolean;
662
+ private withImplicit;
663
+ private collect;
664
+ private commit;
665
+ private resolveKind;
666
+ private resolveRevisions;
667
+ private resolveRefs;
668
+ private sourcesFor;
669
+ private nextRevision;
650
670
  }
651
671
 
652
672
  /**
@@ -772,1332 +792,1331 @@ interface ExtensionUtils {
772
792
  }
773
793
 
774
794
  /**
775
- * Extension API object passed to extension factory function.
795
+ * Extension runner — manages extension loading and hook execution.
776
796
  *
777
- * @example
778
- * ```typescript
779
- * export default function(api: ExtensionAPI) {
780
- * // api provides all extension APIs
781
- * }
797
+ * Architecture reference: PI's ExtensionRunner
798
+ * - Per-extension tracking via Extension objects
799
+ * - Shared ExtensionRuntime with invalidate/assertActive
800
+ * - Direct `on()` API for hook registration
801
+ * - Error listener pattern for structured error handling
802
+ * - Tool registration support
803
+ */
804
+
805
+ type ExtensionRunnerOptions = {
806
+ entryPhaseId?: string | null;
807
+ cwd?: string;
808
+ };
809
+ /**
810
+ * Manages extensions and provides hooks for the agent loop.
811
+ *
812
+ * Features:
813
+ * - Per-extension tracking (handlers, tools, phases)
814
+ * - Shared runtime with lifecycle protection (invalidate/assertActive)
815
+ * - Error listener pattern for structured error handling
816
+ * - Direct hook API and extension-loaded hook API
817
+ * - Tool registration for LLM-callable tools
818
+ * - EventBus for inter-extension communication
819
+ *
820
+ * @example
821
+ * ```ts
822
+ * const runner = createExtensionRunner();
823
+ *
824
+ * // Direct hook registration
825
+ * const unsub = runner.on("before_tool_call", (event) => {
826
+ * return { allow: false, reason: "Blocked" };
827
+ * });
828
+ *
829
+ * // Error handling
830
+ * runner.onError((error) => {
831
+ * console.error(`Extension error in ${error.extensionPath}:`, error.error);
832
+ * });
833
+ *
834
+ * // Load extensions
835
+ * await runner.loadExtensions(extensions);
836
+ * runner.bind();
782
837
  * ```
783
838
  */
784
- interface ExtensionAPI {
839
+ declare class ExtensionRunner {
840
+ readonly hooks: HooksManager;
841
+ readonly runtime: ExtensionRuntime;
842
+ readonly events: EventBus;
843
+ private readonly cwd;
844
+ private readonly abortController;
845
+ private _idle;
846
+ private readonly extensions;
847
+ private readonly phases;
848
+ private _phaseCache;
849
+ private readonly pendingProviders;
850
+ private bound;
851
+ private readonly errorListeners;
852
+ /** Current agent context — set by the agent before each phase */
853
+ currentContext?: AgentContext;
854
+ constructor(options?: ExtensionRunnerOptions);
855
+ /** Whether the agent is currently idle (not streaming). */
856
+ get isIdle(): boolean;
857
+ /** Set idle state — called by the agent loop. */
858
+ setIdle(idle: boolean): void;
859
+ /** Abort signal for the current runner instance. */
860
+ get signal(): AbortSignal;
861
+ /** Abort the current runner operation. */
862
+ abort(): void;
785
863
  /**
786
- * Subscribe to a hook event.
864
+ * Register an error listener.
865
+ * Returns an unsubscribe function.
866
+ */
867
+ onError(listener: ExtensionErrorListener): () => void;
868
+ /**
869
+ * Emit a structured extension error to all listeners.
870
+ */
871
+ emitError(error: ExtensionError): void;
872
+ /**
873
+ * Mark all extension contexts as stale.
874
+ * After calling this, any captured ExtensionAPI or ExtensionContext will throw
875
+ * on use. Used during runtime replacement or reload.
876
+ */
877
+ invalidate(message?: string): void;
878
+ /**
879
+ * Subscribe to a specific hook event type.
880
+ * Returns an unsubscribe function.
787
881
  *
788
- * @param eventType - Hook type, e.g. "before_tool_call"
789
- * @param handler - Hook handler, can return result to modify behavior
882
+ * @example
883
+ * ```ts
884
+ * const unsub = runner.on("before_tool_call", (event) => {
885
+ * return { allow: false, reason: "Blocked" };
886
+ * });
887
+ * unsub(); // Cancel subscription
888
+ * ```
790
889
  */
791
- on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
792
- /** Unsubscribe from a hook event. */
793
- off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
794
- /** Tool capabilities — register and unregister custom tools. */
795
- tool: {
796
- /** Register a custom LLM-callable tool. */
797
- register(tool: ToolDefinition): void;
798
- /** Unregister a previously registered tool by name. */
799
- unregister(toolName: string): void;
800
- };
801
- /** Register a model provider. */
802
- registerProvider(config: _rowan_agent_models.ProviderConfig): void;
803
- /** Unregister a model provider. */
804
- unregisterProvider(name: string): void;
805
- /** Extension manifest from package.json `rowan` field. */
806
- manifest?: ExtensionManifest;
807
- /** Utility functions. */
808
- utils: ExtensionUtils;
809
- /** Runtime context — cwd, signal, exec, message access, etc. */
810
- context: ExtensionContext;
811
- /** Shared event bus for inter-extension communication. */
812
- events: EventBus;
813
- /** Phase execution capabilities — provides Phase In/Out, phase identity, phase routing, and registration. */
814
- phase: {
815
- /** Register a Phase directory bundle or Phase object. */
816
- register(phase: PhaseRegistration): Promise<void>;
817
- /** Unregister a previously registered phase by name. */
818
- unregister(phaseName: string): void;
819
- /** Phase In: get payload from previous phase */
820
- getPayload(): unknown;
821
- /** Phase Out: set payload for next phase */
822
- setPayload(payload: unknown): void;
823
- /** Phase Out: set outcome message */
824
- setMessage(message: string): void;
825
- /** Get current phase name */
826
- getCurrentPhase(): string;
827
- /** Set next phase (lower priority than PHASE.md target) */
828
- setNextPhase(phaseName: string): void;
829
- /** Get the next phase set by setNextPhase */
830
- getNextPhase(): string | undefined;
831
- /** Get the message set by setMessage */
832
- getMessage(): string | undefined;
833
- /** Phase Settings contributions registered by the Phase extension. */
834
- settings: {
835
- register(provider: PhaseSettingsProvider): void;
836
- };
837
- };
890
+ on<K extends HookEventType>(type: K, handler: HookHandler<K>): () => void;
891
+ /**
892
+ * Load and initialize extensions.
893
+ * Creates Extension tracking objects and calls each factory with an ExtensionAPI.
894
+ */
895
+ loadExtensions(extensions: LoadedExtension[]): Promise<void>;
896
+ /** Dispose all active Extensions in reverse activation order. */
897
+ close(): Promise<void>;
898
+ /** Get all registered tools from all extensions. */
899
+ getAllRegisteredTools(): RegisteredTool[];
900
+ /**
901
+ * Get a tool definition by name. Returns undefined if not found.
902
+ */
903
+ getToolDefinition(toolName: string): RegisteredTool["definition"] | undefined;
904
+ getPhase(name: string): Phase | undefined;
905
+ getPhases(): Phase[];
906
+ createPhaseRegistry(input?: {
907
+ entryPhaseId?: string | null;
908
+ }): PhaseRegistry;
909
+ /** Adapt an extension RegisteredPhase to the core Phase type. */
910
+ private adaptToPhase;
911
+ /**
912
+ * Bind the runner — flushes pending provider registrations and
913
+ * replaces runtime stubs with real implementations.
914
+ */
915
+ bind(): void;
916
+ /**
917
+ * Generic emit — fire-and-forget for any event type.
918
+ */
919
+ emit<K extends HookEventType>(eventType: K, event: Parameters<HookHandler<K>>[0]): Promise<void>;
920
+ /**
921
+ * Unified hook emission — returns the first non-undefined result.
922
+ */
923
+ private emitHook;
924
+ emitBeforePhase(phaseId: string, input: PhaseContext): Promise<{
925
+ abort?: any;
926
+ skip?: any;
927
+ input?: PhaseContext;
928
+ }>;
929
+ emitAfterPhase(phaseId: string, output: PhaseOutput): Promise<{
930
+ abort?: any;
931
+ retry?: PhaseContext;
932
+ output?: PhaseOutput;
933
+ }>;
934
+ emitBeforePrompt(phaseId: string, input: PhaseContext): Promise<PhaseContext>;
935
+ emitBeforeToolCall(tool: Tool, args: unknown, context?: {
936
+ runId?: string;
937
+ agentId?: string;
938
+ toolCallId?: string;
939
+ metadata?: Readonly<Record<string, unknown>>;
940
+ answer?: unknown;
941
+ }): Promise<BeforeToolCallResult>;
942
+ emitAfterToolCall(tool: Tool, result: ToolResult, context?: {
943
+ runId?: string;
944
+ agentId?: string;
945
+ toolCallId?: string;
946
+ metadata?: Readonly<Record<string, unknown>>;
947
+ }): Promise<ToolResult>;
948
+ /**
949
+ * Create an ExtensionAPI for a specific extension.
950
+ * Registration methods write to the extension tracking object.
951
+ * Action methods delegate to the shared runtime.
952
+ */
953
+ private createExtensionAPI;
954
+ private registerTool;
955
+ private unregisterTool;
956
+ private registerPhase;
957
+ private registerPhaseDefinition;
958
+ private unregisterPhase;
959
+ private loadRegisteredPhase;
960
+ private registerProvider;
961
+ private unregisterProvider;
962
+ private flushPendingProviders;
963
+ private getRegisteredPhase;
964
+ private collectRegisteredPhases;
965
+ private rollbackExtension;
966
+ private disposeExtension;
838
967
  }
839
- /**
840
- * Extension factory function.
841
- * Receives ExtensionAPI for registering hooks, phases, and providers.
842
- */
843
- type ExtensionDisposer = () => void | Promise<void>;
844
- type ExtensionFactoryResult = void | ExtensionDisposer;
845
- type ExtensionFactory = (api: ExtensionAPI) => ExtensionFactoryResult | Promise<ExtensionFactoryResult>;
846
968
 
847
- type PhaseStatusState = "running" | "completed";
848
- /** Normalized status event exposed to Runtime consumers. */
849
- type PhaseStatus = Readonly<{
850
- state: PhaseStatusState;
851
- /** Stable consumer-facing status identifier, e.g. `compacting`. */
852
- kind: string;
853
- /** Optional human-readable detail for UI/status consumers. */
854
- message?: string;
855
- /** Structured status payload. */
856
- payload?: unknown;
969
+ type ExtensionContribution = LoadedExtension;
970
+ type ExtensionLoadInput = LoadInput<ExtensionContribution>;
971
+ type ExtensionActivationError = Readonly<{
972
+ path: string;
973
+ error: string;
857
974
  }>;
858
- /** Unified phase output — model-driven routing is optional; programmatic phases may normalize omission to stop. */
859
- type PhaseOutput = {
860
- /** User-visible assistant message. */
861
- message?: string;
862
- /** Final status update for non-conversational consumers. */
863
- status?: PhaseStatus;
864
- /** Route to next phase, or "continue" to re-execute current phase, or "stop" to end. Undefined means no model route. */
865
- route?: string;
866
- /** Phase name that produced this output */
867
- phase?: string;
868
- /** Tool calls from the model invocation (used by framework for route extraction) */
869
- toolCalls?: Array<{
870
- id: string;
871
- name: string;
872
- args: unknown;
873
- }>;
874
- /** Route reason extracted from route tool call (for hooks to inspect) */
875
- routeReason?: string;
876
- /** Structured data from this phase, passed to the next phase */
877
- payload?: unknown;
878
- };
879
- /** Phase machine state — tracks position and inter-phase data */
880
- interface PhaseState {
881
- current: string;
882
- available: string[];
883
- iterations: number;
884
- payload?: unknown;
885
- }
886
- type PhaseInvocation = {
887
- mode: "serial";
888
- instanceId: string;
889
- } | {
890
- mode: "parallel";
891
- instanceId: string;
892
- groupId: string;
893
- index: number;
894
- count: number;
895
- sourcePhaseId: string;
896
- };
897
- /** Durable identity of the Run execution currently invoking a Phase. */
898
- type PhaseExecutionIdentity = Readonly<{
899
- agentId: string;
900
- runId: string;
901
- executionId: string;
902
- /** Original durable Run input, before any Phase-local interpretation. */
903
- input?: UserContent;
904
- /** Opaque metadata captured at the durable boundary; Rowan does not decode it. */
905
- agentMetadata?: Readonly<Record<string, unknown>>;
906
- runMetadata?: Readonly<Record<string, unknown>>;
975
+ type ExtensionActivationResult = Readonly<{
976
+ active: readonly string[];
977
+ errors: readonly ExtensionActivationError[];
978
+ revision?: string;
979
+ registered?: readonly string[];
980
+ skipped?: readonly ResourceDiagnostic[];
907
981
  }>;
908
- /** Everything a phase needs to execute */
909
- interface PhaseContext {
910
- systemPrompt: string;
911
- messages: AgentMessage[];
912
- /** Phase-filtered tools */
913
- tools: Tool$1[];
914
- /** Phase-filtered skills */
915
- skills: Skill[];
916
- /** Phase machine state */
917
- state: PhaseState;
918
- /** Identity and dispatch metadata for this phase execution */
919
- readonly invocation: PhaseInvocation;
920
- /** Durable Run identity for cross-store integrations and idempotent commands. */
921
- readonly execution: PhaseExecutionIdentity;
922
- /** Additional guideline bullets appended to the system prompt */
923
- promptGuidelines?: string[];
924
- /** Text to append after the system prompt */
925
- appendSystemPrompt?: string;
926
- }
927
- /** JSON-safe structural defaults declared by a Phase's `input` mapping. */
928
- type PhaseInput = Readonly<Record<string, JsonValue>>;
929
- /** JSON-safe option metadata exposed by a Phase to a host Settings surface. */
930
- interface PhaseSettingsOption {
931
- value: string;
932
- label: string;
933
- description?: string;
934
- disabled?: boolean;
982
+ type ExtensionLifetimeErrorCode = "extensions_frozen" | "extensions_closed";
983
+ declare class ExtensionLifetimeError extends Error {
984
+ readonly code: ExtensionLifetimeErrorCode;
985
+ constructor(code: ExtensionLifetimeErrorCode, message: string);
935
986
  }
936
- interface PhaseSettingsBadge {
937
- label: string;
938
- tone?: "neutral" | "success" | "review" | "danger";
987
+ /** Runtime-global Extension activation and lifetime boundary. */
988
+ declare class RuntimeExtensionLifetime {
989
+ private readonly runner;
990
+ private frozen;
991
+ private closed;
992
+ constructor(options?: {
993
+ cwd?: string;
994
+ });
995
+ activate(extensions: readonly LoadedExtension[]): Promise<ExtensionActivationResult>;
996
+ tools(): readonly RegisteredTool[];
997
+ phases(): readonly Phase[];
998
+ get extensionRunner(): ExtensionRunner;
999
+ close(): Promise<void>;
939
1000
  }
940
- interface PhaseSettingsItem {
941
- id: string;
942
- title: string;
943
- description?: string;
944
- badges?: readonly PhaseSettingsBadge[];
1001
+ /** Bootstrap-only Registry facade; its Extension method disappears after init. */
1002
+ declare class RuntimeBootstrapRegistry extends ResourceRegistry {
1003
+ private readonly extensions;
1004
+ private readonly extensionSourceId;
1005
+ constructor(extensions?: RuntimeExtensionLifetime);
1006
+ /** Install Rowan-owned implicit resources before any host source is read. */
1007
+ ensureCoreResources(): Promise<void>;
1008
+ loadExtensions(input: readonly LoadedExtension[] | ExtensionLoadInput): Promise<ExtensionActivationResult>;
1009
+ get extensionRunner(): ExtensionRunner;
1010
+ get extensionTools(): readonly RegisteredTool[];
1011
+ get extensionPhases(): readonly Phase[];
1012
+ closeExtensions(): Promise<void>;
945
1013
  }
946
- type PhaseSettingsControl = {
947
- type: "boolean";
948
- path: string;
949
- label: string;
950
- description?: string;
951
- } | {
952
- type: "number";
953
- path: string;
954
- label: string;
955
- description?: string;
956
- min?: number;
957
- max?: number;
958
- step?: number;
959
- unit?: string;
960
- scale?: number;
961
- } | {
962
- type: "select";
963
- path: string;
964
- label: string;
965
- description?: string;
966
- options: readonly PhaseSettingsOption[];
967
- } | {
968
- type: "text";
969
- path: string;
970
- label: string;
971
- description?: string;
972
- placeholder?: string;
973
- format?: "string" | "string-array" | "key-value";
974
- multiline?: boolean;
975
- } | {
976
- type: "collection";
977
- path: string;
978
- label: string;
1014
+
1015
+ type DefinitionLayer = Readonly<{
979
1016
  description?: string;
980
- items: readonly PhaseSettingsItem[];
981
- fields: readonly PhaseSettingsControl[];
982
- add?: {
983
- label: string;
984
- idLabel?: string;
985
- fields: readonly PhaseSettingsControl[];
986
- };
987
- removeLabel?: string;
988
- };
989
- interface PhaseSettingsSection {
1017
+ prompt?: string;
1018
+ model?: ModelRef;
1019
+ tools?: readonly string[];
1020
+ skills?: readonly string[];
1021
+ phases?: PhaseRegistrySelection;
1022
+ }>;
1023
+ type AgentConfiguration = Readonly<{
1024
+ identity: string;
1025
+ definition: Readonly<{
1026
+ name: string;
1027
+ layer?: DefinitionLayer;
1028
+ }>;
1029
+ resourceView: ResourceView;
1030
+ contexts?: readonly ContextCandidate[];
1031
+ /** Trusted Host-owned Contexts rendered as durable user messages. */
1032
+ additionalContexts?: readonly ContextCandidate[];
1033
+ cwd?: string;
1034
+ maxAttempts?: number;
1035
+ model: ModelConfig | ModelRef;
1036
+ stream?: StreamFn;
1037
+ }>;
1038
+ type ConfigurationSnapshot = Readonly<{
1039
+ identity: string;
1040
+ definition: AgentDefinition;
1041
+ resources: Readonly<{
1042
+ tools: readonly Tool$1[];
1043
+ skills: readonly Skill[];
1044
+ phases?: PhaseRegistry;
1045
+ revisions: Readonly<Record<ResourceKind, readonly string[]>>;
1046
+ refs: Readonly<Record<ResourceKind, readonly ResourceRef[]>>;
1047
+ }>;
1048
+ contexts: readonly ContextCandidate[];
1049
+ additionalContexts: readonly ContextCandidate[];
1050
+ resourceView: ResourceView;
1051
+ cwd?: string;
1052
+ maxAttempts?: number;
1053
+ model: ModelConfig | ModelRef;
1054
+ stream?: StreamFn;
1055
+ }>;
1056
+ /** Resolve one Definition request into one immutable, source-qualified snapshot. */
1057
+ declare function resolveConfigurationSnapshot(registry: ResourceRegistry, input: AgentConfiguration): ConfigurationSnapshot;
1058
+ /** Whether one stored configuration is already a resolved snapshot. A snapshot
1059
+ * is used as it stands; a request is resolved against the current sources. */
1060
+ declare function isConfigurationSnapshot(config: AgentConfiguration | ConfigurationSnapshot): config is ConfigurationSnapshot;
1061
+
1062
+ type UserInput = string | Readonly<{
1063
+ content: UserContent;
1064
+ metadata?: Metadata;
1065
+ }>;
1066
+ type HistorySeed = readonly Message[];
1067
+ type ContextStatus = Readonly<{
1068
+ tokens: number;
1069
+ contextWindow: number;
1070
+ percent: number;
1071
+ thresholdTokens: number;
1072
+ estimated: boolean;
1073
+ coveredThrough?: Readonly<{
1074
+ messageId: MessageId;
1075
+ sequence: number;
1076
+ }>;
1077
+ }>;
1078
+ type ContextCompactionRecord = Readonly<{
990
1079
  id: string;
991
- title: string;
992
- description?: string;
993
- controls: readonly PhaseSettingsControl[];
994
- }
995
- /** Declarative, host-neutral Settings surface contributed by a Phase. */
996
- interface PhaseSettingsDefinition {
997
- description?: string;
998
- sections: readonly PhaseSettingsSection[];
999
- }
1000
- /** Host context is intentionally opaque beyond the effective configuration. */
1001
- interface PhaseSettingsContext {
1002
- configuration: Readonly<Record<string, unknown>>;
1003
- metadata?: Readonly<Record<string, unknown>>;
1004
- }
1005
- type PhaseSettingsProvider = (context: PhaseSettingsContext) => PhaseSettingsDefinition | Promise<PhaseSettingsDefinition>;
1006
- /**
1007
- * Loaded Phase object
1008
- */
1009
- interface Phase {
1010
- /** Unique phase identity and display name. */
1080
+ agentId: AgentId;
1081
+ summary: string;
1082
+ coveredThrough?: Readonly<{
1083
+ messageId: MessageId;
1084
+ sequence: number;
1085
+ }>;
1086
+ instructions?: string;
1087
+ createdAt: string;
1088
+ }>;
1089
+ /** Who is calling which tool, without the ability to ask or suspend. Hosts that
1090
+ * describe a call before it runs (for example to build a confirmation) only
1091
+ * have this much. */
1092
+ type ToolCallContext = Readonly<{
1093
+ agentId: AgentId;
1094
+ runId: RunId;
1095
+ /** Opaque JSON metadata captured from the Agent and Run records. Rowan does
1096
+ * not interpret host/domain fields. */
1097
+ agentMetadata?: Metadata;
1098
+ runMetadata?: Metadata;
1099
+ toolCallId: ToolCallId;
1100
+ reportProgress(progress: JsonValue): void;
1101
+ }>;
1102
+ type ToolInvocationContext = ToolCallContext & Readonly<{
1103
+ interaction: RunInteractionDriver;
1104
+ }>;
1105
+ type Tool$1 = Readonly<{
1011
1106
  name: string;
1012
- /** Rowan-owned built-in Phase; built-ins are never filtered or disabled. */
1013
- core?: boolean;
1014
- /** Description */
1015
- description: string;
1016
- /** Restricted tools (undefined = all tools available) */
1017
- tools?: string[];
1018
- /** Skills bundled directly inside this phase directory. Inline phases may omit this (equivalent to []). */
1019
- skills?: Skill[];
1020
- /** Forced next phase */
1021
- target?: string;
1022
- /** Structural JSON-safe input defaults */
1023
- input?: PhaseInput;
1024
- /** If true, phase gets a fresh context when executed in parallel */
1025
- isolated?: boolean;
1026
- /** Path to PHASE.md file */
1027
- filePath: string;
1028
- /** Phase directory path */
1029
- baseDir: string;
1030
- /** PHASE.md body content */
1031
- content: string;
1032
- /** Model override for this phase (resolved from frontmatter) */
1033
- model?: ModelRef;
1034
- /** Do not automatically inject this Phase into the model route catalog/context. */
1035
- disableAutoInvocation?: boolean;
1036
- /** Do not expose this Phase to direct user invocation. */
1037
- disableImplicitInvocation?: boolean;
1038
- /** ExtensionAPI factory function used for registration or programmatic execution. */
1039
- factory?: (api: ExtensionAPI) => Promise<void>;
1040
- /** Direct run function */
1041
- run?: (context: PhaseContext, execution: PhaseExecution) => Promise<PhaseOutput | void>;
1042
- }
1043
- /**
1044
- * Phase registry containing all loaded phases
1045
- */
1046
- interface PhaseRegistry {
1047
- /** Map of phase name to Phase object */
1048
- phases: Map<string, Phase>;
1049
- /** Entry phase name (null until Agent applies its default phase) */
1050
- entryPhaseId: string | null;
1051
- }
1052
-
1053
- type ToolCallInteractionKind = PhaseInteractionKind;
1054
- interface ToolCallInteractionRequest$1 {
1055
- id?: string;
1056
- kind: ToolCallInteractionKind;
1057
- prompt: string;
1058
- payload?: JsonValue;
1059
- }
1060
- interface BeforePhaseEvent {
1061
- type: "before_phase";
1062
- phaseId: string;
1063
- input: PhaseContext;
1064
- }
1065
- interface AfterPhaseEvent {
1066
- type: "after_phase";
1067
- phaseId: string;
1068
- output: PhaseOutput;
1069
- }
1070
- interface BeforePromptEvent {
1071
- type: "before_prompt";
1072
- phaseId: string;
1073
- input: PhaseContext;
1074
- }
1075
- interface BeforeToolCallEvent {
1076
- type: "before_tool_call";
1077
- tool: Tool$1;
1078
- args: unknown;
1079
- readonly runId?: string;
1080
- readonly agentId?: string;
1081
- readonly toolCallId?: string;
1082
- readonly metadata?: Readonly<Record<string, unknown>>;
1083
- readonly answer?: unknown;
1084
- }
1085
- interface AfterToolCallEvent {
1086
- type: "after_tool_call";
1087
- tool: Tool$1;
1088
- result: ToolResult;
1089
- readonly runId?: string;
1090
- readonly agentId?: string;
1091
- readonly toolCallId?: string;
1092
- readonly metadata?: Readonly<Record<string, unknown>>;
1093
- }
1094
- type HookEvent = BeforePhaseEvent | AfterPhaseEvent | BeforePromptEvent | BeforeToolCallEvent | AfterToolCallEvent;
1095
- interface BeforePhaseResult {
1096
- abort?: Outcome$1;
1097
- skip?: {
1098
- route: string;
1099
- message: string;
1100
- };
1101
- input?: PhaseContext;
1102
- }
1103
- interface AfterPhaseResult {
1104
- abort?: Outcome$1;
1105
- retry?: PhaseContext;
1106
- output?: PhaseOutput;
1107
- }
1108
- interface BeforePromptResult {
1109
- input?: PhaseContext;
1110
- }
1111
- interface BeforeToolCallResult {
1112
- allow?: boolean;
1113
- reason?: string;
1114
- interaction?: ToolCallInteractionRequest$1;
1115
- }
1116
- interface AfterToolCallResult {
1117
- result?: ToolResult;
1118
- }
1119
- interface HookResultMap {
1120
- before_phase: BeforePhaseResult | undefined;
1121
- after_phase: AfterPhaseResult | undefined;
1122
- before_prompt: BeforePromptResult | undefined;
1123
- before_tool_call: BeforeToolCallResult | undefined;
1124
- after_tool_call: AfterToolCallResult | undefined;
1125
- }
1126
- type HookEventType = HookEvent["type"];
1127
- type HookHandler<K extends HookEventType> = (event: Extract<HookEvent, {
1128
- type: K;
1129
- }>) => HookResultMap[K] | Promise<HookResultMap[K]> | void | Promise<void>;
1130
- declare class HooksManager {
1131
- private handlers;
1132
- on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
1133
- off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
1134
- emit<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
1135
- type: K;
1136
- }>): Promise<void>;
1137
- emitFirst<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
1138
- type: K;
1139
- }>): Promise<HookResultMap[K] | undefined>;
1140
- }
1141
-
1142
- type ToolContext = Pick<AgentContext, "skills"> & {
1143
- toolCallId: string;
1144
- };
1145
- type ToolExecutionMode = "sequential" | "parallel";
1146
- type Tool$1<TArgs = unknown> = {
1147
- name: string;
1148
- /** Rowan-owned Core Tool; Core Tools bypass Phase filtering. */
1107
+ /** Rowan-owned Core Tool; Core Tools bypass Definition/Phase filtering. */
1149
1108
  core?: boolean;
1150
1109
  description: string;
1151
1110
  parameters: Type.TSchema;
1152
- /** One-line snippet shown in the system prompt tool list. */
1153
- promptSnippet?: string;
1154
- /** Additional guidelines appended to the system prompt when this tool is active. */
1155
- promptGuidelines?: string[];
1156
- /** Whether this tool can run concurrently with others. Default: "parallel". */
1157
- executionMode?: ToolExecutionMode;
1158
- execute(args: TArgs, context: ToolContext, signal?: AbortSignal): Promise<ToolResult>;
1159
- };
1160
- /** Context snapshot passed into the low-level agent loop. */
1161
- type AgentContext = {
1162
- /** System prompt included with the request. */
1163
- systemPrompt: string;
1164
- /** Transcript visible to the model. */
1165
- messages: AgentMessage[];
1166
- /** Tools available for this run. */
1167
- tools: Tool$1[];
1168
- /** Skills available for this run. */
1169
- skills: Skill[];
1170
- /** Custom phases for this run. Agent normalizes this with the built-in default phase. */
1171
- phases?: PhaseRegistry;
1172
- };
1173
-
1174
- /**
1175
- * `root` anchors relative paths and the Bash working directory. It is not a
1176
- * filesystem sandbox: core Tools use the permissions of the host process.
1177
- */
1178
- type CoreToolContext = {
1179
- root?: string;
1180
- /** Directory for complete Tool Result spill files. */
1181
- archiveDir?: string;
1182
- maxReadBytes?: number;
1183
- maxReadLines?: number;
1184
- bashTimeoutMs?: number;
1185
- maxBashOutputBytes?: number;
1186
- };
1187
-
1188
- type PhaseRegistrySelection = Readonly<{
1189
- entryPhaseId: string | null;
1190
- phaseIds: readonly string[];
1111
+ execute(args: JsonValue, context: ToolInvocationContext, signal: AbortSignal): Promise<ToolExecutionResult$1>;
1191
1112
  }>;
1192
- type AgentDefinition = Readonly<{
1113
+ type ContextCandidate = Readonly<{
1193
1114
  name: string;
1194
- description: string;
1195
- prompt: string;
1196
- tools?: readonly string[];
1197
- skills?: readonly string[];
1198
- /** Host-supplied Skills private to this Agent Definition/Bundle. */
1199
- bundledSkills?: readonly Skill[];
1200
- phases?: PhaseRegistrySelection;
1201
- contexts?: readonly string[];
1202
- model?: ModelRef;
1115
+ value: JsonValue;
1203
1116
  }>;
1204
- /** Parse one Markdown definition using the same frontmatter vocabulary as Phase resources. */
1205
- declare function parseAgentDefinition(raw: string): AgentDefinition;
1206
-
1207
- type ResourceKind = "agent" | "tool" | "skill" | "phase";
1208
- type ResourceSourceId = string;
1209
- /** Rowan-native contribution aliases. Hosts may adapt their domain handlers to
1210
- * these existing Tool/Phase lifecycles without importing host Scope types. */
1211
- type ToolContribution = Tool;
1212
- type PhaseContribution = Phase;
1213
- type ResourceView = Readonly<{
1214
- agents: readonly ResourceSourceId[];
1215
- tools: readonly ResourceSourceId[];
1216
- skills: readonly ResourceSourceId[];
1217
- phases: readonly ResourceSourceId[];
1117
+ type BeforeToolCallDecision = Readonly<{
1118
+ allow: true;
1119
+ }> | Readonly<{
1120
+ allow: false;
1121
+ reason: string;
1122
+ }> | Readonly<{
1123
+ interaction: RunInteractionRequest;
1218
1124
  }>;
1219
- type ResourceRef = Readonly<{
1220
- kind: ResourceKind;
1221
- sourceId: ResourceSourceId;
1125
+ type BeforeToolCall = (input: Readonly<{
1126
+ tool: Tool$1;
1127
+ args: JsonValue;
1128
+ context: ToolInvocationContext;
1129
+ signal: AbortSignal;
1130
+ answer?: JsonValue;
1131
+ }>) => BeforeToolCallDecision | Promise<BeforeToolCallDecision>;
1132
+ type AfterToolCall = (input: Readonly<{
1133
+ tool: Tool$1;
1134
+ result: ToolExecutionResult$1;
1135
+ context: ToolInvocationContext;
1136
+ signal: AbortSignal;
1137
+ }>) => ToolExecutionResult$1 | Promise<ToolExecutionResult$1>;
1138
+ type InvocationSource = "auto" | "implicit" | "external";
1139
+ type InvocationCatalogEntry = Readonly<{
1140
+ kind: "phase" | "skill";
1222
1141
  name: string;
1142
+ description: string;
1143
+ input?: Phase["input"];
1144
+ core?: boolean;
1145
+ disableAutoInvocation: boolean;
1146
+ disableImplicitInvocation: boolean;
1147
+ filePath: string;
1223
1148
  }>;
1224
- type ResourceDiagnostic = Readonly<{
1225
- kind: "invalid" | "missing" | "collision";
1226
- sourceId: ResourceSourceId;
1227
- message: string;
1228
- path?: string;
1149
+ type AgentRecord = Readonly<{
1150
+ id: AgentId;
1151
+ metadata?: Metadata;
1152
+ currentConfigToken?: ConfigToken;
1153
+ currentConfigIdentity?: string;
1154
+ createdAt: string;
1155
+ activatedAt?: string;
1156
+ updatedAt: string;
1229
1157
  }>;
1230
- type LoadResult = Readonly<{
1231
- revision: string;
1232
- registered: readonly ResourceRef[];
1233
- skipped: readonly ResourceDiagnostic[];
1158
+ type AgentDeletionRequest = Readonly<{
1159
+ agentId: AgentId;
1160
+ expectedRunIds: readonly RunId[];
1161
+ confirmation: "agent-delete-v1";
1234
1162
  }>;
1235
- type LoadInput<T> = Readonly<{
1236
- sourceId: ResourceSourceId;
1237
- directory?: string;
1238
- values?: readonly T[];
1163
+ type ExecutionToken = Readonly<{
1164
+ runId: RunId;
1165
+ ownerEpoch: number;
1166
+ executionId: ExecutionId;
1239
1167
  }>;
1240
- type ResolvedResourceView = Readonly<{
1241
- agents: readonly AgentDefinition[];
1242
- tools: readonly Tool[];
1243
- skills: readonly Skill[];
1244
- phases: readonly Phase[];
1245
- revisions: Readonly<Record<ResourceKind, readonly string[]>>;
1246
- refs: Readonly<Record<ResourceKind, readonly ResourceRef[]>>;
1168
+ type ExecutionCheckpoint = Readonly<{
1169
+ codec: string;
1170
+ version: number;
1171
+ data: JsonValue;
1247
1172
  }>;
1248
- type ResourceRegistryErrorCode = "invalid_source_id" | "invalid_resource_name" | "resource_collision" | "resource_input_missing" | "resource_directory_not_supported" | "unknown_resource_source" | "implicit_source_protected";
1249
- declare class ResourceRegistryError extends Error {
1250
- readonly code: ResourceRegistryErrorCode;
1251
- constructor(code: ResourceRegistryErrorCode, message: string);
1252
- }
1253
- type RegistryValue = AgentDefinition | Tool | Skill | Phase;
1254
- /**
1255
- * Runtime Resource Registry source transaction and view resolver.
1256
- *
1257
- * Directory normalization is intentionally added by the typed loader slice;
1258
- * this first module owns only the atomic source/revision/collision semantics.
1259
- */
1260
- declare class ResourceRegistry {
1261
- private readonly sources;
1262
- /** Sources registered by the bootstrap boundary (currently Extensions). */
1263
- private readonly implicitSources;
1264
- private revisionSequence;
1265
- loadAgents(input: LoadInput<AgentDefinition>): Promise<LoadResult>;
1266
- loadSkills(input: LoadInput<Skill>): Promise<LoadResult>;
1267
- loadPhases(input: LoadInput<Phase>): Promise<LoadResult>;
1268
- loadTools(input: Readonly<{
1269
- sourceId: ResourceSourceId;
1270
- values: readonly ToolContribution[];
1271
- }>): Promise<LoadResult>;
1272
- unload(input: Readonly<{
1273
- kind: ResourceKind;
1274
- sourceId: ResourceSourceId;
1275
- }>): Promise<LoadResult>;
1276
- resolveView(view: ResourceView): ResolvedResourceView;
1277
- /** Mark one already-loaded source as implicit for every Resource View. */
1278
- protected markImplicit(kind: ResourceKind, sourceId: ResourceSourceId): void;
1279
- /** Bootstrap-only helper for replacing an implicit contribution source. */
1280
- protected replaceImplicit<T extends RegistryValue>(kind: ResourceKind, sourceId: ResourceSourceId, values: readonly T[]): Promise<LoadResult>;
1281
- protected hasImplicit(kind: ResourceKind, sourceId: ResourceSourceId): boolean;
1282
- private withImplicit;
1283
- private collect;
1284
- private commit;
1285
- private resolveKind;
1286
- private resolveRevisions;
1287
- private resolveRefs;
1288
- private sourcesFor;
1289
- private nextRevision;
1290
- }
1291
-
1292
- /**
1293
- * Extension runner — manages extension loading and hook execution.
1294
- *
1295
- * Architecture reference: PI's ExtensionRunner
1296
- * - Per-extension tracking via Extension objects
1297
- * - Shared ExtensionRuntime with invalidate/assertActive
1298
- * - Direct `on()` API for hook registration
1299
- * - Error listener pattern for structured error handling
1300
- * - Tool registration support
1301
- */
1302
-
1303
- type ExtensionRunnerOptions = {
1304
- entryPhaseId?: string | null;
1305
- cwd?: string;
1306
- };
1307
- /**
1308
- * Manages extensions and provides hooks for the agent loop.
1309
- *
1310
- * Features:
1311
- * - Per-extension tracking (handlers, tools, phases)
1312
- * - Shared runtime with lifecycle protection (invalidate/assertActive)
1313
- * - Error listener pattern for structured error handling
1314
- * - Direct hook API and extension-loaded hook API
1315
- * - Tool registration for LLM-callable tools
1316
- * - EventBus for inter-extension communication
1317
- *
1318
- * @example
1319
- * ```ts
1320
- * const runner = createExtensionRunner();
1321
- *
1322
- * // Direct hook registration
1323
- * const unsub = runner.on("before_tool_call", (event) => {
1324
- * return { allow: false, reason: "Blocked" };
1325
- * });
1326
- *
1327
- * // Error handling
1328
- * runner.onError((error) => {
1329
- * console.error(`Extension error in ${error.extensionPath}:`, error.error);
1330
- * });
1331
- *
1332
- * // Load extensions
1333
- * await runner.loadExtensions(extensions);
1334
- * runner.bind();
1335
- * ```
1336
- */
1337
- declare class ExtensionRunner {
1338
- readonly hooks: HooksManager;
1339
- readonly runtime: ExtensionRuntime;
1340
- readonly events: EventBus;
1341
- private readonly cwd;
1342
- private readonly abortController;
1343
- private _idle;
1344
- private readonly extensions;
1345
- private readonly phases;
1346
- private _phaseCache;
1347
- private readonly pendingProviders;
1348
- private bound;
1349
- private readonly errorListeners;
1350
- /** Current agent context — set by the agent before each phase */
1351
- currentContext?: AgentContext;
1352
- constructor(options?: ExtensionRunnerOptions);
1353
- /** Whether the agent is currently idle (not streaming). */
1354
- get isIdle(): boolean;
1355
- /** Set idle state — called by the agent loop. */
1356
- setIdle(idle: boolean): void;
1357
- /** Abort signal for the current runner instance. */
1358
- get signal(): AbortSignal;
1359
- /** Abort the current runner operation. */
1360
- abort(): void;
1361
- /**
1362
- * Register an error listener.
1363
- * Returns an unsubscribe function.
1364
- */
1365
- onError(listener: ExtensionErrorListener): () => void;
1366
- /**
1367
- * Emit a structured extension error to all listeners.
1368
- */
1369
- emitError(error: ExtensionError): void;
1370
- /**
1371
- * Mark all extension contexts as stale.
1372
- * After calling this, any captured ExtensionAPI or ExtensionContext will throw
1373
- * on use. Used during runtime replacement or reload.
1374
- */
1375
- invalidate(message?: string): void;
1376
- /**
1377
- * Subscribe to a specific hook event type.
1378
- * Returns an unsubscribe function.
1379
- *
1380
- * @example
1381
- * ```ts
1382
- * const unsub = runner.on("before_tool_call", (event) => {
1383
- * return { allow: false, reason: "Blocked" };
1384
- * });
1385
- * unsub(); // Cancel subscription
1386
- * ```
1387
- */
1388
- on<K extends HookEventType>(type: K, handler: HookHandler<K>): () => void;
1389
- /**
1390
- * Load and initialize extensions.
1391
- * Creates Extension tracking objects and calls each factory with an ExtensionAPI.
1392
- */
1393
- loadExtensions(extensions: LoadedExtension[]): Promise<void>;
1394
- /** Dispose all active Extensions in reverse activation order. */
1395
- close(): Promise<void>;
1396
- /** Get all registered tools from all extensions. */
1397
- getAllRegisteredTools(): RegisteredTool[];
1398
- /**
1399
- * Get a tool definition by name. Returns undefined if not found.
1400
- */
1401
- getToolDefinition(toolName: string): RegisteredTool["definition"] | undefined;
1402
- getPhase(name: string): Phase | undefined;
1403
- getPhases(): Phase[];
1404
- createPhaseRegistry(input?: {
1405
- entryPhaseId?: string | null;
1406
- }): PhaseRegistry;
1407
- /** Adapt an extension RegisteredPhase to the core Phase type. */
1408
- private adaptToPhase;
1409
- /**
1410
- * Bind the runner — flushes pending provider registrations and
1411
- * replaces runtime stubs with real implementations.
1412
- */
1413
- bind(): void;
1414
- /**
1415
- * Generic emit — fire-and-forget for any event type.
1416
- */
1417
- emit<K extends HookEventType>(eventType: K, event: Parameters<HookHandler<K>>[0]): Promise<void>;
1418
- /**
1419
- * Unified hook emission — returns the first non-undefined result.
1420
- */
1421
- private emitHook;
1422
- emitBeforePhase(phaseId: string, input: PhaseContext): Promise<{
1423
- abort?: any;
1424
- skip?: any;
1425
- input?: PhaseContext;
1426
- }>;
1427
- emitAfterPhase(phaseId: string, output: PhaseOutput): Promise<{
1428
- abort?: any;
1429
- retry?: PhaseContext;
1430
- output?: PhaseOutput;
1431
- }>;
1432
- emitBeforePrompt(phaseId: string, input: PhaseContext): Promise<PhaseContext>;
1433
- emitBeforeToolCall(tool: Tool$1, args: unknown, context?: {
1434
- runId?: string;
1435
- agentId?: string;
1436
- toolCallId?: string;
1437
- metadata?: Readonly<Record<string, unknown>>;
1438
- answer?: unknown;
1439
- }): Promise<BeforeToolCallResult>;
1440
- emitAfterToolCall(tool: Tool$1, result: ToolResult, context?: {
1441
- runId?: string;
1442
- agentId?: string;
1443
- toolCallId?: string;
1444
- metadata?: Readonly<Record<string, unknown>>;
1445
- }): Promise<ToolResult>;
1446
- /**
1447
- * Create an ExtensionAPI for a specific extension.
1448
- * Registration methods write to the extension tracking object.
1449
- * Action methods delegate to the shared runtime.
1450
- */
1451
- private createExtensionAPI;
1452
- private registerTool;
1453
- private unregisterTool;
1454
- private registerPhase;
1455
- private registerPhaseDefinition;
1456
- private unregisterPhase;
1457
- private loadRegisteredPhase;
1458
- private registerProvider;
1459
- private unregisterProvider;
1460
- private flushPendingProviders;
1461
- private getRegisteredPhase;
1462
- private collectRegisteredPhases;
1463
- private rollbackExtension;
1464
- private disposeExtension;
1465
- }
1466
-
1467
- type ExtensionContribution = LoadedExtension;
1468
- type ExtensionLoadInput = LoadInput<ExtensionContribution>;
1469
- type ExtensionActivationError = Readonly<{
1470
- path: string;
1471
- error: string;
1472
- }>;
1473
- type ExtensionActivationResult = Readonly<{
1474
- active: readonly string[];
1475
- errors: readonly ExtensionActivationError[];
1476
- revision?: string;
1477
- registered?: readonly string[];
1478
- skipped?: readonly ResourceDiagnostic[];
1479
- }>;
1480
- type ExtensionLifetimeErrorCode = "extensions_frozen" | "extensions_closed";
1481
- declare class ExtensionLifetimeError extends Error {
1482
- readonly code: ExtensionLifetimeErrorCode;
1483
- constructor(code: ExtensionLifetimeErrorCode, message: string);
1484
- }
1485
- /** Runtime-global Extension activation and lifetime boundary. */
1486
- declare class RuntimeExtensionLifetime {
1487
- private readonly runner;
1488
- private frozen;
1489
- private closed;
1490
- constructor(options?: {
1491
- cwd?: string;
1492
- });
1493
- activate(extensions: readonly LoadedExtension[]): Promise<ExtensionActivationResult>;
1494
- tools(): readonly RegisteredTool[];
1495
- phases(): readonly Phase[];
1496
- get extensionRunner(): ExtensionRunner;
1497
- close(): Promise<void>;
1498
- }
1499
- /** Bootstrap-only Registry facade; its Extension method disappears after init. */
1500
- declare class RuntimeBootstrapRegistry extends ResourceRegistry {
1501
- private readonly extensions;
1502
- private readonly extensionSourceId;
1503
- constructor(extensions?: RuntimeExtensionLifetime);
1504
- /** Install Rowan-owned implicit resources before any host source is read. */
1505
- ensureCoreResources(): Promise<void>;
1506
- loadExtensions(input: readonly LoadedExtension[] | ExtensionLoadInput): Promise<ExtensionActivationResult>;
1507
- get extensionRunner(): ExtensionRunner;
1508
- get extensionTools(): readonly RegisteredTool[];
1509
- get extensionPhases(): readonly Phase[];
1510
- closeExtensions(): Promise<void>;
1511
- }
1512
-
1513
- type DefinitionLayer = Readonly<{
1514
- description?: string;
1515
- prompt?: string;
1516
- model?: ModelRef;
1517
- tools?: readonly string[];
1518
- skills?: readonly string[];
1519
- phases?: PhaseRegistrySelection;
1173
+ type OwnerLease = Readonly<{
1174
+ ownerId: string;
1175
+ token: OwnerToken;
1176
+ epoch: number;
1177
+ expiresAt: string;
1520
1178
  }>;
1521
- type AgentConfiguration = Readonly<{
1522
- identity: string;
1523
- definition: Readonly<{
1524
- name: string;
1525
- layer?: DefinitionLayer;
1526
- }>;
1527
- resourceView: ResourceView;
1528
- contexts?: readonly ContextCandidate[];
1529
- /** Trusted Host-owned Contexts rendered as durable user messages. */
1530
- additionalContexts?: readonly ContextCandidate[];
1531
- cwd?: string;
1532
- maxAttempts?: number;
1533
- model: ModelConfig | ModelRef;
1534
- stream?: StreamFn;
1179
+ type RunClaim = Readonly<{
1180
+ run: RunRecord;
1181
+ execution: ExecutionToken;
1182
+ history: readonly Message[];
1535
1183
  }>;
1536
- type ConfigurationSnapshot = Readonly<{
1537
- identity: string;
1538
- definition: AgentDefinition;
1539
- resources: Readonly<{
1540
- tools: readonly Tool[];
1541
- skills: readonly Skill[];
1542
- phases?: PhaseRegistry;
1543
- revisions: Readonly<Record<ResourceKind, readonly string[]>>;
1544
- refs: Readonly<Record<ResourceKind, readonly ResourceRef[]>>;
1545
- }>;
1546
- contexts: readonly ContextCandidate[];
1547
- additionalContexts: readonly ContextCandidate[];
1548
- resourceView: ResourceView;
1549
- cwd?: string;
1550
- maxAttempts?: number;
1551
- model: ModelConfig | ModelRef;
1552
- stream?: StreamFn;
1184
+ type ToolCallReservation = Readonly<{
1185
+ providerToolCallId: string;
1186
+ name: string;
1187
+ args: JsonValue;
1188
+ toolCallId?: ToolCallId;
1553
1189
  }>;
1554
- /** Resolve one Definition request into one immutable, source-qualified snapshot. */
1555
- declare function resolveConfigurationSnapshot(registry: ResourceRegistry, input: AgentConfiguration): ConfigurationSnapshot;
1556
- /** Whether one stored configuration is already a resolved snapshot. A snapshot
1557
- * is used as it stands; a request is resolved against the current sources. */
1558
- declare function isConfigurationSnapshot(config: AgentConfiguration | ConfigurationSnapshot): config is ConfigurationSnapshot;
1559
-
1560
- type UserInput = string | Readonly<{
1561
- content: UserContent;
1562
- metadata?: Metadata;
1190
+ type ToolCommit = Readonly<{
1191
+ run: RunRecord;
1192
+ toolCall: ToolCallSnapshot;
1563
1193
  }>;
1564
- type HistorySeed = readonly Message[];
1565
- type ContextStatus = Readonly<{
1566
- tokens: number;
1567
- contextWindow: number;
1568
- percent: number;
1569
- thresholdTokens: number;
1570
- estimated: boolean;
1571
- coveredThrough?: Readonly<{
1572
- messageId: MessageId;
1573
- sequence: number;
1574
- }>;
1194
+ type ToolBatchCommit = Readonly<{
1195
+ run: RunRecord;
1196
+ toolCalls: readonly ToolCallSnapshot[];
1575
1197
  }>;
1576
- type ContextCompactionRecord = Readonly<{
1577
- id: string;
1198
+ type RunRecord = Readonly<{
1199
+ id: RunId;
1578
1200
  agentId: AgentId;
1579
- summary: string;
1580
- coveredThrough?: Readonly<{
1201
+ agentSequence: number;
1202
+ readySequence: number;
1203
+ revision: number;
1204
+ state: RunState;
1205
+ input: UserInput;
1206
+ initialMessageId?: MessageId;
1207
+ invalidatedBy?: Readonly<{
1581
1208
  messageId: MessageId;
1582
- sequence: number;
1209
+ messageRevision: number;
1583
1210
  }>;
1584
- instructions?: string;
1585
- createdAt: string;
1586
- }>;
1587
- type ToolInvocationContext = Readonly<{
1588
- agentId: AgentId;
1589
- runId: RunId;
1590
- /** Opaque JSON metadata captured from the Agent and Run records. Rowan does
1591
- * not interpret host/domain fields. */
1592
- agentMetadata?: Metadata;
1593
- runMetadata?: Metadata;
1594
- toolCallId: ToolCallId;
1595
- reportProgress(progress: JsonValue): void;
1596
- }>;
1597
- type Tool = Readonly<{
1598
- name: string;
1599
- /** Rowan-owned Core Tool; Core Tools bypass Definition/Phase filtering. */
1600
- core?: boolean;
1601
- description: string;
1602
- parameters: Type.TSchema;
1603
- execute(args: JsonValue, context: ToolInvocationContext, signal: AbortSignal): Promise<ToolExecutionResult$1>;
1604
- }>;
1605
- type ContextCandidate = Readonly<{
1606
- name: string;
1607
- value: JsonValue;
1608
- }>;
1609
- type ToolCallInteractionRequest = Readonly<{
1610
- id?: string;
1611
- kind: PhaseInteractionKind;
1612
- prompt: string;
1613
- payload?: JsonValue;
1614
- }>;
1615
- type BeforeToolCallDecision = Readonly<{
1616
- allow: true;
1617
- }> | Readonly<{
1618
- allow: false;
1619
- reason: string;
1620
- }> | Readonly<{
1621
- interaction: ToolCallInteractionRequest;
1622
- }>;
1623
- type BeforeToolCall = (input: Readonly<{
1624
- tool: Tool;
1625
- args: JsonValue;
1626
- context: ToolInvocationContext;
1627
- signal: AbortSignal;
1628
- answer?: JsonValue;
1629
- }>) => BeforeToolCallDecision | Promise<BeforeToolCallDecision>;
1630
- type AfterToolCall = (input: Readonly<{
1631
- tool: Tool;
1632
- result: ToolExecutionResult$1;
1633
- context: ToolInvocationContext;
1634
- signal: AbortSignal;
1635
- }>) => ToolExecutionResult$1 | Promise<ToolExecutionResult$1>;
1636
- type InvocationSource = "auto" | "implicit" | "external";
1637
- type InvocationCatalogEntry = Readonly<{
1638
- kind: "phase" | "skill";
1639
- name: string;
1640
- description: string;
1641
- input?: Phase["input"];
1642
- core?: boolean;
1643
- disableAutoInvocation: boolean;
1644
- disableImplicitInvocation: boolean;
1645
- filePath: string;
1211
+ metadata?: Metadata;
1212
+ pinnedConfigToken?: ConfigToken;
1213
+ checkpoint?: ExecutionCheckpoint;
1214
+ currentPhaseId?: string;
1215
+ openInteractions?: readonly RunInteraction[];
1216
+ interactionAnswers?: Readonly<Record<string, JsonValue>>;
1217
+ execution?: ExecutionToken;
1218
+ outcome?: Outcome;
1219
+ failure?: RunFailure;
1220
+ cancellationReason?: string;
1221
+ createdAt: string;
1222
+ updatedAt: string;
1646
1223
  }>;
1647
- type AgentRecord = Readonly<{
1224
+ type MessageRevisionResult = Readonly<{
1225
+ message: UserMessage & Readonly<{
1226
+ messageRevision: number;
1227
+ }>;
1228
+ replacementRun: RunRecord;
1229
+ invalidatedRunIds: readonly RunId[];
1230
+ affectedToolCallIds: readonly ToolCallId[];
1231
+ effectDigest?: string;
1232
+ }>;
1233
+ type RetentionResult = Readonly<{
1234
+ deletedRunIds: readonly RunId[];
1235
+ deletedToolCallIds: readonly ToolCallId[];
1236
+ deletedEventCount: number;
1237
+ retentionFloor: EventCursor;
1238
+ skipped?: "active_consumers" | "no_eligible_events";
1239
+ }>;
1240
+ type AgentSummary = Readonly<{
1648
1241
  id: AgentId;
1649
1242
  metadata?: Metadata;
1650
- currentConfigToken?: ConfigToken;
1651
1243
  currentConfigIdentity?: string;
1652
1244
  createdAt: string;
1653
- activatedAt?: string;
1245
+ activatedAt: string;
1654
1246
  updatedAt: string;
1655
1247
  }>;
1656
- type AgentDeletionRequest = Readonly<{
1248
+ type RunSummary = Readonly<{
1249
+ id: RunId;
1657
1250
  agentId: AgentId;
1658
- expectedRunIds: readonly RunId[];
1659
- confirmation: "agent-delete-v1";
1660
- }>;
1661
- type ExecutionToken = Readonly<{
1662
- runId: RunId;
1663
- ownerEpoch: number;
1664
- executionId: ExecutionId;
1251
+ agentSequence: number;
1252
+ state: RunState;
1253
+ metadata?: Metadata;
1254
+ createdAt: string;
1255
+ updatedAt: string;
1665
1256
  }>;
1666
- type ExecutionCheckpoint = Readonly<{
1667
- codec: string;
1668
- version: number;
1669
- data: JsonValue;
1257
+ type Page<T, Cursor> = Readonly<{
1258
+ items: readonly T[];
1259
+ next?: Cursor;
1670
1260
  }>;
1671
- type InputRequest = Readonly<{
1672
- id: InputRequestId;
1673
- phase: string;
1674
- messageId?: MessageId;
1261
+ type RunSnapshotBase = Readonly<{
1262
+ runId: RunId;
1263
+ agentId: AgentId;
1264
+ agentSequence: number;
1265
+ revision: number;
1266
+ input: UserInput;
1267
+ metadata?: Metadata;
1268
+ messageCount: number;
1269
+ toolCallCount: number;
1270
+ currentPhaseId?: string;
1675
1271
  createdAt: string;
1272
+ updatedAt: string;
1273
+ cursor: EventCursor;
1676
1274
  }>;
1677
- type OwnerLease = Readonly<{
1678
- ownerId: string;
1679
- token: OwnerToken;
1680
- epoch: number;
1681
- expiresAt: string;
1682
- }>;
1683
- type RunClaim = Readonly<{
1684
- run: RunRecord;
1685
- execution: ExecutionToken;
1686
- history: readonly Message[];
1275
+ type RunSnapshot = RunSnapshotBase & (Readonly<{
1276
+ state: "queued" | "running";
1277
+ currentPhaseId?: string;
1278
+ }> | Readonly<{
1279
+ state: "input_required";
1280
+ interactions: readonly RunInteraction[];
1281
+ answers: Readonly<Record<string, JsonValue>>;
1282
+ }> | Readonly<{
1283
+ state: "completed";
1284
+ outcome: Outcome;
1285
+ output?: AssistantMessage;
1286
+ }> | Readonly<{
1287
+ state: "failed";
1288
+ failure: RunFailure;
1289
+ }> | Readonly<{
1290
+ state: "cancelled";
1291
+ reason?: string;
1292
+ }>);
1293
+ type RunBoundary = Readonly<{
1294
+ type: "input_required";
1295
+ interactions: readonly RunInteraction[];
1296
+ answers: Readonly<Record<string, JsonValue>>;
1297
+ }> | Readonly<{
1298
+ type: "completed";
1299
+ outcome: Outcome;
1300
+ output?: AssistantMessage;
1301
+ }> | Readonly<{
1302
+ type: "failed";
1303
+ failure: RunFailure;
1304
+ }> | Readonly<{
1305
+ type: "cancelled";
1306
+ reason?: string;
1687
1307
  }>;
1688
- type InputRequiredCommit = Readonly<{
1689
- run: RunRecord;
1690
- prompt?: AssistantMessage;
1691
- request: InputRequest;
1692
- interactions: readonly PhaseInteraction[];
1308
+ type ConfigResolution = Readonly<{
1309
+ kind: "available";
1310
+ config: AgentConfiguration | ConfigurationSnapshot;
1311
+ } | {
1312
+ kind: "deferred";
1313
+ retryAfterMs?: number;
1314
+ } | {
1315
+ kind: "unavailable";
1316
+ reason: string;
1693
1317
  }>;
1694
- type ToolCallReservation = Readonly<{
1695
- providerToolCallId: string;
1696
- name: string;
1697
- args: JsonValue;
1698
- toolCallId?: ToolCallId;
1318
+ type ConfigPutResult = Readonly<{
1319
+ kind: "stored";
1320
+ token: string;
1321
+ } | {
1322
+ kind: "identity_conflict";
1699
1323
  }>;
1700
- type ToolCommit = Readonly<{
1701
- run: RunRecord;
1702
- toolCall: ToolCallSnapshot;
1324
+ interface ConfigProvider {
1325
+ put(input: {
1326
+ agentId: AgentId;
1327
+ agentMetadata?: Metadata;
1328
+ config: AgentConfiguration | ConfigurationSnapshot;
1329
+ operationId: string;
1330
+ signal: AbortSignal;
1331
+ }): Promise<ConfigPutResult>;
1332
+ resolve(input: {
1333
+ agentId: AgentId;
1334
+ agentMetadata?: Metadata;
1335
+ token: ConfigToken;
1336
+ signal: AbortSignal;
1337
+ }): Promise<ConfigResolution>;
1338
+ }
1339
+ interface OwnedStore {
1340
+ readonly lease: OwnerLease;
1341
+ reserveAgent(input: {
1342
+ idempotencyKey: string;
1343
+ metadata?: Metadata;
1344
+ configIdentity?: string;
1345
+ historySeed?: HistorySeed;
1346
+ }): Promise<AgentRecord>;
1347
+ activateAgent(agentId: AgentId, configToken?: ConfigToken, configIdentity?: string): Promise<AgentRecord>;
1348
+ updateAgentConfigToken(input: {
1349
+ agentId: AgentId;
1350
+ token: ConfigToken;
1351
+ configIdentity?: string;
1352
+ idempotencyKey: string;
1353
+ }): Promise<AgentRecord>;
1354
+ deleteAgent(input: AgentDeletionRequest): Promise<void>;
1355
+ reviseMessage(input: {
1356
+ agentId: AgentId;
1357
+ messageId: MessageId;
1358
+ expectedMessageRevision: number;
1359
+ content: UserContent;
1360
+ operationId: string;
1361
+ effectDigestConfirmation?: string;
1362
+ }): Promise<MessageRevisionResult>;
1363
+ compact(input?: {
1364
+ now?: string;
1365
+ retentionMs?: number;
1366
+ }): Promise<RetentionResult>;
1367
+ contextStatus(agentId: AgentId, contextWindow: number): Promise<ContextStatus>;
1368
+ contextMessages(agentId: AgentId, recentTokenBudget?: number): Promise<readonly Message[]>;
1369
+ commitContextCompaction(record: ContextCompactionRecord): Promise<ContextCompactionRecord>;
1370
+ createRun(input: {
1371
+ agentId: AgentId;
1372
+ input: UserInput;
1373
+ metadata?: Metadata;
1374
+ idempotencyKey: string;
1375
+ }): Promise<RunRecord>;
1376
+ claimRun(input: {
1377
+ runId: RunId;
1378
+ expectedRevision: number;
1379
+ executionId?: ExecutionId;
1380
+ messageId?: MessageId;
1381
+ configToken?: ConfigToken;
1382
+ }): Promise<RunClaim>;
1383
+ failQueuedRun(input: {
1384
+ runId: RunId;
1385
+ expectedRevision: number;
1386
+ failure: QueuedRunFailure;
1387
+ }): Promise<RunRecord>;
1388
+ commitPhaseEntered(input: {
1389
+ runId: RunId;
1390
+ execution: ExecutionToken;
1391
+ expectedRevision: number;
1392
+ phaseId: string;
1393
+ visit: number;
1394
+ }): Promise<RunRecord>;
1395
+ commitInputRequired(input: {
1396
+ runId: RunId;
1397
+ execution: ExecutionToken;
1398
+ expectedRevision: number;
1399
+ phase: string;
1400
+ prompt?: AssistantMessage;
1401
+ checkpoint: ExecutionCheckpoint;
1402
+ interactions?: readonly RunInteraction[];
1403
+ interactionAnswers?: Readonly<Record<string, JsonValue>>;
1404
+ pendingToolCallIds?: readonly ToolCallId[];
1405
+ }): Promise<RunRecord>;
1406
+ answerInteraction(input: {
1407
+ runId: RunId;
1408
+ interactionId: string;
1409
+ expectedRevision: number;
1410
+ input?: JsonValue;
1411
+ cancel?: boolean;
1412
+ }): Promise<RunRecord>;
1413
+ commitOutcome(input: {
1414
+ runId: RunId;
1415
+ execution: ExecutionToken;
1416
+ expectedRevision: number;
1417
+ outcome?: Outcome;
1418
+ failure?: RunFailure;
1419
+ output?: AssistantMessage;
1420
+ }): Promise<RunRecord>;
1421
+ reserveToolCall(input: {
1422
+ runId: RunId;
1423
+ execution: ExecutionToken;
1424
+ expectedRevision: number;
1425
+ requestMessageId: MessageId;
1426
+ name: string;
1427
+ args: JsonValue;
1428
+ toolCallId?: ToolCallId;
1429
+ providerToolCallId?: string;
1430
+ }): Promise<ToolCommit>;
1431
+ reserveToolCalls(input: {
1432
+ runId: RunId;
1433
+ execution: ExecutionToken;
1434
+ expectedRevision: number;
1435
+ requestMessageId: MessageId;
1436
+ calls: readonly ToolCallReservation[];
1437
+ }): Promise<ToolBatchCommit>;
1438
+ startToolCall(input: {
1439
+ runId: RunId;
1440
+ execution: ExecutionToken;
1441
+ expectedRevision: number;
1442
+ toolCallId: ToolCallId;
1443
+ }): Promise<ToolCommit>;
1444
+ suspendToolCall(input: {
1445
+ runId: RunId;
1446
+ execution: ExecutionToken;
1447
+ expectedRevision: number;
1448
+ toolCallId: ToolCallId;
1449
+ }): Promise<ToolCommit>;
1450
+ commitToolResult(input: {
1451
+ runId: RunId;
1452
+ execution: ExecutionToken;
1453
+ expectedRevision: number;
1454
+ toolCallId: ToolCallId;
1455
+ result: ToolExecutionResult$1;
1456
+ state: "completed" | "failed" | "indeterminate";
1457
+ reason?: string;
1458
+ }): Promise<ToolCommit>;
1459
+ cancelRun(input: {
1460
+ runId: RunId;
1461
+ expectedRevision?: number;
1462
+ reason?: string;
1463
+ output?: AssistantMessage;
1464
+ }): Promise<RunRecord>;
1465
+ snapshotRun(runId: RunId): Promise<RunSnapshot>;
1466
+ history(agentId: AgentId): Promise<readonly Message[]>;
1467
+ listAgents(): Promise<readonly AgentRecord[]>;
1468
+ listRuns(input?: {
1469
+ agentId?: AgentId;
1470
+ states?: readonly RunState[];
1471
+ }): Promise<readonly RunRecord[]>;
1472
+ listEvents(input?: {
1473
+ after?: EventCursor;
1474
+ }): Promise<readonly DurableRunEvent[]>;
1475
+ openConsumer(consumerId: string): Promise<ConsumerRegistration>;
1476
+ advanceConsumerCheckpoint(input: {
1477
+ consumerId: string;
1478
+ cursor: EventCursor;
1479
+ }): Promise<void>;
1480
+ renewOwner(leaseMs: number): Promise<OwnerLease>;
1481
+ sealAndReleaseOwner(): Promise<void>;
1482
+ }
1483
+ interface DurableStore {
1484
+ openOwner(input: {
1485
+ ownerId: string;
1486
+ leaseMs: number;
1487
+ }): Promise<OwnedStore>;
1488
+ }
1489
+ type AgentRuntimeOptions = Readonly<{
1490
+ store: DurableStore;
1491
+ configs?: ConfigProvider;
1492
+ concurrency?: number;
1493
+ bootstrap?: (registry: RuntimeBootstrapRegistry) => void | Promise<void>;
1703
1494
  }>;
1704
- type ToolBatchCommit = Readonly<{
1705
- run: RunRecord;
1706
- toolCalls: readonly ToolCallSnapshot[];
1495
+ type DurableConsumer = Readonly<{
1496
+ caughtUp: Promise<void>;
1497
+ done: Promise<void>;
1498
+ stop(): void;
1707
1499
  }>;
1708
- type RunRecord = Readonly<{
1709
- id: RunId;
1710
- agentId: AgentId;
1711
- agentSequence: number;
1712
- readySequence: number;
1713
- revision: number;
1714
- state: RunState;
1715
- input: UserInput;
1716
- initialMessageId?: MessageId;
1717
- invalidatedBy?: Readonly<{
1500
+ interface AgentRun {
1501
+ readonly id: RunId;
1502
+ snapshot(): Promise<RunSnapshot>;
1503
+ observe(options?: {
1504
+ after?: EventCursor;
1505
+ signal?: AbortSignal;
1506
+ }): AsyncIterable<RunEvent>;
1507
+ wait(options?: {
1508
+ signal?: AbortSignal;
1509
+ }): Promise<RunBoundary>;
1510
+ respondInteraction(input: {
1511
+ interactionId: string;
1512
+ input?: JsonValue;
1513
+ cancel?: boolean;
1514
+ }): Promise<void>;
1515
+ cancel(reason?: string): Promise<RunBoundary>;
1516
+ }
1517
+ interface AgentRuntime$1 {
1518
+ loadAgents(input: LoadInput<AgentDefinition>): Promise<LoadResult>;
1519
+ loadSkills(input: LoadInput<Skill>): Promise<LoadResult>;
1520
+ loadPhases(input: LoadInput<Phase>): Promise<LoadResult>;
1521
+ loadTools(input: Readonly<{
1522
+ sourceId: string;
1523
+ values: readonly Tool$1[];
1524
+ }>): Promise<LoadResult>;
1525
+ unload(input: Readonly<{
1526
+ kind: ResourceKind;
1527
+ sourceId: string;
1528
+ }>): Promise<LoadResult>;
1529
+ createAgent(config: AgentConfiguration, options?: {
1530
+ idempotencyKey?: string;
1531
+ metadata?: Metadata;
1532
+ historySeed?: HistorySeed;
1533
+ }): Promise<AgentId>;
1534
+ updateAgentConfig(agentId: AgentId, config: AgentConfiguration, options: {
1535
+ idempotencyKey: string;
1536
+ }): Promise<void>;
1537
+ deleteAgent(input: AgentDeletionRequest): Promise<void>;
1538
+ revise(agentId: AgentId, input: {
1718
1539
  messageId: MessageId;
1719
- messageRevision: number;
1720
- }>;
1721
- metadata?: Metadata;
1722
- pinnedConfigToken?: ConfigToken;
1723
- checkpoint?: ExecutionCheckpoint;
1724
- openInputRequest?: InputRequest;
1725
- openInteractions?: readonly PhaseInteraction[];
1726
- interactionAnswers?: Readonly<Record<string, JsonValue>>;
1727
- execution?: ExecutionToken;
1728
- outcome?: Outcome;
1729
- failure?: RunFailure;
1730
- cancellationReason?: string;
1731
- createdAt: string;
1732
- updatedAt: string;
1540
+ expectedMessageRevision: number;
1541
+ content: UserContent;
1542
+ operationId: string;
1543
+ effectDigestConfirmation?: string;
1544
+ }): Promise<MessageRevisionResult>;
1545
+ compact(input?: {
1546
+ now?: string;
1547
+ retentionMs?: number;
1548
+ }): Promise<RetentionResult>;
1549
+ start(agentId: AgentId, input: UserInput, options: {
1550
+ idempotencyKey: string;
1551
+ metadata?: Metadata;
1552
+ }): Promise<AgentRun>;
1553
+ run(runId: RunId): AgentRun;
1554
+ contextStatus(agentId: AgentId, options?: {
1555
+ contextWindow?: number;
1556
+ }): Promise<ContextStatus>;
1557
+ compactContext(agentId: AgentId, options?: {
1558
+ input?: UserInput;
1559
+ instructions?: string;
1560
+ idempotencyKey?: string;
1561
+ }): Promise<AgentRun>;
1562
+ listInvocations(agentId: AgentId, options: {
1563
+ source: InvocationSource;
1564
+ }): Promise<readonly InvocationCatalogEntry[]>;
1565
+ history(agentId: AgentId): Promise<readonly Message[]>;
1566
+ listAgents(input?: {
1567
+ after?: AgentListCursor;
1568
+ limit?: number;
1569
+ }): Promise<Page<AgentSummary, AgentListCursor>>;
1570
+ listRuns(input?: {
1571
+ agentId?: AgentId;
1572
+ states?: readonly RunState[];
1573
+ after?: RunListCursor;
1574
+ limit?: number;
1575
+ }): Promise<Page<RunSummary, RunListCursor>>;
1576
+ consume(input: {
1577
+ consumerId: string;
1578
+ signal: AbortSignal;
1579
+ onEvent(event: DurableRunEvent, context: Readonly<{
1580
+ signal: AbortSignal;
1581
+ }>): void | Promise<void>;
1582
+ }): Promise<DurableConsumer>;
1583
+ close(): Promise<void>;
1584
+ }
1585
+ type ConsumerRegistration = Readonly<{
1586
+ cursor?: EventCursor;
1587
+ waterline: EventCursor;
1733
1588
  }>;
1734
- type MessageRevisionResult = Readonly<{
1735
- message: UserMessage & Readonly<{
1736
- messageRevision: number;
1589
+
1590
+ interface SourceInfo {
1591
+ source: string;
1592
+ baseDir?: string;
1593
+ displayName?: string;
1594
+ }
1595
+ /** Register a Phase by directory path or Phase object; PHASE.md and direct child Skills are loaded atomically when a path is supplied. */
1596
+ type PhaseRegistration = string | Phase;
1597
+ /**
1598
+ * Tool definition for registering LLM-callable tools via `api.tool.register()`.
1599
+ *
1600
+ * @example
1601
+ * ```typescript
1602
+ * api.tool.register({
1603
+ * name: "search_docs",
1604
+ * description: "Search documentation",
1605
+ * parameters: { type: "object", properties: { query: { type: "string" } } },
1606
+ * execute: async (args, ctx) => {
1607
+ * return { content: [{ type: "text", text: "result" }] };
1608
+ * },
1609
+ * });
1610
+ * ```
1611
+ */
1612
+ interface ToolDefinition {
1613
+ /** Tool name (used in LLM tool calls) */
1614
+ name: string;
1615
+ /** Description for LLM */
1616
+ description: string;
1617
+ /** Parameter schema (JSON Schema) */
1618
+ parameters: Record<string, unknown>;
1619
+ /** Execute the tool */
1620
+ execute: (args: unknown, context: ToolInvocationContext, signal?: AbortSignal) => Promise<ToolExecutionResult>;
1621
+ /** Optional: per-tool execution mode override */
1622
+ executionMode?: "sequential" | "parallel";
1623
+ }
1624
+ /**
1625
+ * Result from tool execution.
1626
+ */
1627
+ interface ToolExecutionResult {
1628
+ /** Content blocks to return to the LLM */
1629
+ content: Array<{
1630
+ type: string;
1631
+ text?: string;
1632
+ [key: string]: unknown;
1737
1633
  }>;
1738
- replacementRun: RunRecord;
1739
- invalidatedRunIds: readonly RunId[];
1740
- affectedToolCallIds: readonly ToolCallId[];
1741
- effectDigest?: string;
1742
- }>;
1743
- type RetentionResult = Readonly<{
1744
- deletedRunIds: readonly RunId[];
1745
- deletedToolCallIds: readonly ToolCallId[];
1746
- deletedEventCount: number;
1747
- retentionFloor: EventCursor;
1748
- skipped?: "active_consumers" | "no_eligible_events";
1749
- }>;
1750
- type AgentSummary = Readonly<{
1751
- id: AgentId;
1752
- metadata?: Metadata;
1753
- currentConfigIdentity?: string;
1754
- createdAt: string;
1755
- activatedAt: string;
1756
- updatedAt: string;
1757
- }>;
1758
- type RunSummary = Readonly<{
1759
- id: RunId;
1760
- agentId: AgentId;
1761
- agentSequence: number;
1762
- state: RunState;
1763
- metadata?: Metadata;
1764
- createdAt: string;
1765
- updatedAt: string;
1766
- }>;
1767
- type Page<T, Cursor> = Readonly<{
1768
- items: readonly T[];
1769
- next?: Cursor;
1770
- }>;
1771
- type RunSnapshotBase = Readonly<{
1772
- runId: RunId;
1773
- agentId: AgentId;
1774
- agentSequence: number;
1775
- revision: number;
1776
- input: UserInput;
1777
- metadata?: Metadata;
1778
- messageCount: number;
1779
- toolCallCount: number;
1780
- createdAt: string;
1781
- updatedAt: string;
1782
- cursor: EventCursor;
1634
+ /** Whether this is an error result */
1635
+ isError?: boolean;
1636
+ }
1637
+ /**
1638
+ * Registered tool with source metadata.
1639
+ */
1640
+ interface RegisteredTool {
1641
+ definition: ToolDefinition;
1642
+ sourceInfo: SourceInfo;
1643
+ }
1644
+ /**
1645
+ * Structured extension error with attribution.
1646
+ */
1647
+ interface ExtensionError {
1648
+ /** Path of the extension that caused the error */
1649
+ extensionPath: string;
1650
+ /** Event or operation that caused the error */
1651
+ event: string;
1652
+ /** Error message */
1653
+ error: string;
1654
+ /** Optional stack trace */
1655
+ stack?: string;
1656
+ }
1657
+ /** Error listener callback type. */
1658
+ type ExtensionErrorListener = (error: ExtensionError) => void;
1659
+ type ExecOptions = {
1660
+ /** Working directory for the command. Defaults to cwd passed to runtime. */
1661
+ cwd?: string;
1662
+ /** Environment variables to add/override. */
1663
+ env?: Record<string, string>;
1664
+ /** Timeout in milliseconds. */
1665
+ timeout?: number;
1666
+ /** AbortSignal for cancellation. */
1667
+ signal?: AbortSignal;
1668
+ };
1669
+ type ExecResult = {
1670
+ exitCode: number;
1671
+ stdout: string;
1672
+ stderr: string;
1673
+ };
1674
+ /**
1675
+ * Shared runtime state created by loader, used during registration and runtime.
1676
+ * All ExtensionAPI instances reference this shared state.
1677
+ *
1678
+ * It only owns the lifetime guard shared by captured Extension API objects.
1679
+ */
1680
+ interface ExtensionRuntime {
1681
+ /** Throws when this extension instance is stale after runtime replacement. */
1682
+ assertActive: () => void;
1683
+ /** Marks this extension instance as stale after runtime replacement or reload. */
1684
+ invalidate: (message?: string) => void;
1685
+ }
1686
+ /**
1687
+ * Result of loading extensions from filesystem.
1688
+ * The runner takes these and creates Extension tracking objects.
1689
+ */
1690
+ type LoadExtensionsResult = {
1691
+ extensions: LoadedExtension[];
1692
+ errors: Array<{
1693
+ path: string;
1694
+ error: string;
1695
+ }>;
1696
+ };
1697
+ /**
1698
+ * Pre-initialization extension form — factory + metadata.
1699
+ * Runner.loadExtensions() calls the factory and creates the full Extension object.
1700
+ */
1701
+ interface LoadedExtension {
1702
+ path: string;
1703
+ name: string;
1704
+ factory: ExtensionFactory;
1705
+ manifest?: ExtensionManifest;
1706
+ }
1707
+ /** Extension manifest from package.json `rowan` field. */
1708
+ interface ExtensionManifest {
1709
+ entry?: string;
1710
+ name?: string;
1711
+ }
1712
+
1713
+ /**
1714
+ * Extension API object passed to extension factory function.
1715
+ *
1716
+ * @example
1717
+ * ```typescript
1718
+ * export default function(api: ExtensionAPI) {
1719
+ * // api provides all extension APIs
1720
+ * }
1721
+ * ```
1722
+ */
1723
+ interface ExtensionAPI {
1724
+ /**
1725
+ * Subscribe to a hook event.
1726
+ *
1727
+ * @param eventType - Hook type, e.g. "before_tool_call"
1728
+ * @param handler - Hook handler, can return result to modify behavior
1729
+ */
1730
+ on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
1731
+ /** Unsubscribe from a hook event. */
1732
+ off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
1733
+ /** Tool capabilities — register and unregister custom tools. */
1734
+ tool: {
1735
+ /** Register a custom LLM-callable tool. */
1736
+ register(tool: ToolDefinition): void;
1737
+ /** Unregister a previously registered tool by name. */
1738
+ unregister(toolName: string): void;
1739
+ };
1740
+ /** Register a model provider. */
1741
+ registerProvider(config: _rowan_agent_models.ProviderConfig): void;
1742
+ /** Unregister a model provider. */
1743
+ unregisterProvider(name: string): void;
1744
+ /** Extension manifest from package.json `rowan` field. */
1745
+ manifest?: ExtensionManifest;
1746
+ /** Utility functions. */
1747
+ utils: ExtensionUtils;
1748
+ /** Runtime context — cwd, signal, exec, message access, etc. */
1749
+ context: ExtensionContext;
1750
+ /** Shared event bus for inter-extension communication. */
1751
+ events: EventBus;
1752
+ /** Phase execution capabilities — provides Phase In/Out, phase identity, phase routing, and registration. */
1753
+ phase: {
1754
+ /** Register a Phase directory bundle or Phase object. */
1755
+ register(phase: PhaseRegistration): Promise<void>;
1756
+ /** Unregister a previously registered phase by name. */
1757
+ unregister(phaseName: string): void;
1758
+ /** Phase In: get payload from previous phase */
1759
+ getPayload(): unknown;
1760
+ /** Phase Out: set payload for next phase */
1761
+ setPayload(payload: unknown): void;
1762
+ /** Phase Out: set outcome message */
1763
+ setMessage(message: string): void;
1764
+ /** Get current phase name */
1765
+ getCurrentPhase(): string;
1766
+ /** Set next phase (lower priority than PHASE.md target) */
1767
+ setNextPhase(phaseName: string): void;
1768
+ /** Get the next phase set by setNextPhase */
1769
+ getNextPhase(): string | undefined;
1770
+ /** Get the message set by setMessage */
1771
+ getMessage(): string | undefined;
1772
+ /** Phase Settings contributions registered by the Phase extension. */
1773
+ settings: {
1774
+ register(provider: PhaseSettingsProvider): void;
1775
+ };
1776
+ };
1777
+ }
1778
+ /**
1779
+ * Extension factory function.
1780
+ * Receives ExtensionAPI for registering hooks, phases, and providers.
1781
+ */
1782
+ type ExtensionDisposer = () => void | Promise<void>;
1783
+ type ExtensionFactoryResult = void | ExtensionDisposer;
1784
+ type ExtensionFactory = (api: ExtensionAPI) => ExtensionFactoryResult | Promise<ExtensionFactoryResult>;
1785
+
1786
+ type PhaseStatusState = "running" | "completed";
1787
+ /** Normalized status event exposed to Runtime consumers. */
1788
+ type PhaseStatus = Readonly<{
1789
+ state: PhaseStatusState;
1790
+ /** Stable consumer-facing status identifier, e.g. `compacting`. */
1791
+ kind: string;
1792
+ /** Optional human-readable detail for UI/status consumers. */
1793
+ message?: string;
1794
+ /** Structured status payload. */
1795
+ payload?: unknown;
1783
1796
  }>;
1784
- type RunSnapshot = RunSnapshotBase & (Readonly<{
1785
- state: "queued" | "running";
1786
- }> | Readonly<{
1787
- state: "input_required";
1788
- request: Readonly<{
1789
- id: InputRequestId;
1790
- phase: string;
1791
- prompt?: AssistantMessage;
1797
+ /** Unified phase output — model-driven routing is optional; programmatic phases may normalize omission to stop. */
1798
+ type PhaseOutput = {
1799
+ /** User-visible assistant message. */
1800
+ message?: string;
1801
+ /** Final status update for non-conversational consumers. */
1802
+ status?: PhaseStatus;
1803
+ /** Route to next phase, or "continue" to re-execute current phase, or "stop" to end. Undefined means no model route. */
1804
+ route?: string;
1805
+ /** Phase name that produced this output */
1806
+ phase?: string;
1807
+ /** Tool calls from the model invocation (used by framework for route extraction) */
1808
+ toolCalls?: Array<{
1809
+ id: string;
1810
+ name: string;
1811
+ args: unknown;
1792
1812
  }>;
1793
- interactions: readonly PhaseInteraction[];
1794
- answers: Readonly<Record<string, JsonValue>>;
1795
- }> | Readonly<{
1796
- state: "completed";
1797
- outcome: Outcome;
1798
- output?: AssistantMessage;
1799
- }> | Readonly<{
1800
- state: "failed";
1801
- failure: RunFailure;
1802
- }> | Readonly<{
1803
- state: "cancelled";
1804
- reason?: string;
1805
- }>);
1806
- type RunBoundary = Readonly<{
1807
- type: "input_required";
1808
- requestId: InputRequestId;
1809
- phase: string;
1810
- prompt?: AssistantMessage;
1811
- interactions: readonly PhaseInteraction[];
1812
- answers: Readonly<Record<string, JsonValue>>;
1813
- }> | Readonly<{
1814
- type: "completed";
1815
- outcome: Outcome;
1816
- output?: AssistantMessage;
1817
- }> | Readonly<{
1818
- type: "failed";
1819
- failure: RunFailure;
1820
- }> | Readonly<{
1821
- type: "cancelled";
1822
- reason?: string;
1813
+ /** Route reason extracted from route tool call (for hooks to inspect) */
1814
+ routeReason?: string;
1815
+ /** Structured data from this phase, passed to the next phase */
1816
+ payload?: unknown;
1817
+ };
1818
+ /** Phase machine state — tracks position and inter-phase data */
1819
+ interface PhaseState {
1820
+ current: string;
1821
+ available: string[];
1822
+ iterations: number;
1823
+ payload?: unknown;
1824
+ }
1825
+ type PhaseInvocation = {
1826
+ mode: "serial";
1827
+ instanceId: string;
1828
+ } | {
1829
+ mode: "parallel";
1830
+ instanceId: string;
1831
+ groupId: string;
1832
+ index: number;
1833
+ count: number;
1834
+ sourcePhaseId: string;
1835
+ };
1836
+ /** Durable identity of the Run execution currently invoking a Phase. */
1837
+ type PhaseExecutionIdentity = Readonly<{
1838
+ agentId: string;
1839
+ runId: string;
1840
+ executionId: string;
1841
+ /** Original durable Run input, before any Phase-local interpretation. */
1842
+ input?: UserContent;
1843
+ /** Opaque metadata captured at the durable boundary; Rowan does not decode it. */
1844
+ agentMetadata?: Readonly<Record<string, unknown>>;
1845
+ runMetadata?: Readonly<Record<string, unknown>>;
1823
1846
  }>;
1824
- type ConfigResolution = Readonly<{
1825
- kind: "available";
1826
- config: AgentConfiguration | ConfigurationSnapshot;
1847
+ /** Everything a phase needs to execute */
1848
+ interface PhaseContext {
1849
+ systemPrompt: string;
1850
+ messages: AgentMessage[];
1851
+ /** Phase-filtered tools */
1852
+ tools: Tool[];
1853
+ /** Phase-filtered skills */
1854
+ skills: Skill[];
1855
+ /** Phase machine state */
1856
+ state: PhaseState;
1857
+ /** Identity and dispatch metadata for this phase execution */
1858
+ readonly invocation: PhaseInvocation;
1859
+ /** Durable Run identity for cross-store integrations and idempotent commands. */
1860
+ readonly execution: PhaseExecutionIdentity;
1861
+ /** Additional guideline bullets appended to the system prompt */
1862
+ promptGuidelines?: string[];
1863
+ /** Text to append after the system prompt */
1864
+ appendSystemPrompt?: string;
1865
+ }
1866
+ /** JSON-safe structural defaults declared by a Phase's `input` mapping. */
1867
+ type PhaseInput = Readonly<Record<string, JsonValue>>;
1868
+ /** JSON-safe option metadata exposed by a Phase to a host Settings surface. */
1869
+ interface PhaseSettingsOption {
1870
+ value: string;
1871
+ label: string;
1872
+ description?: string;
1873
+ disabled?: boolean;
1874
+ }
1875
+ interface PhaseSettingsBadge {
1876
+ label: string;
1877
+ tone?: "neutral" | "success" | "review" | "danger";
1878
+ }
1879
+ interface PhaseSettingsItem {
1880
+ id: string;
1881
+ title: string;
1882
+ description?: string;
1883
+ badges?: readonly PhaseSettingsBadge[];
1884
+ }
1885
+ type PhaseSettingsControl = {
1886
+ type: "boolean";
1887
+ path: string;
1888
+ label: string;
1889
+ description?: string;
1827
1890
  } | {
1828
- kind: "deferred";
1829
- retryAfterMs?: number;
1891
+ type: "number";
1892
+ path: string;
1893
+ label: string;
1894
+ description?: string;
1895
+ min?: number;
1896
+ max?: number;
1897
+ step?: number;
1898
+ unit?: string;
1899
+ scale?: number;
1830
1900
  } | {
1831
- kind: "unavailable";
1832
- reason: string;
1833
- }>;
1834
- type ConfigPutResult = Readonly<{
1835
- kind: "stored";
1836
- token: string;
1901
+ type: "select";
1902
+ path: string;
1903
+ label: string;
1904
+ description?: string;
1905
+ options: readonly PhaseSettingsOption[];
1837
1906
  } | {
1838
- kind: "identity_conflict";
1839
- }>;
1840
- interface ConfigProvider {
1841
- put(input: {
1842
- agentId: AgentId;
1843
- agentMetadata?: Metadata;
1844
- config: AgentConfiguration | ConfigurationSnapshot;
1845
- operationId: string;
1846
- signal: AbortSignal;
1847
- }): Promise<ConfigPutResult>;
1848
- resolve(input: {
1849
- agentId: AgentId;
1850
- agentMetadata?: Metadata;
1851
- token: ConfigToken;
1852
- signal: AbortSignal;
1853
- }): Promise<ConfigResolution>;
1907
+ type: "text";
1908
+ path: string;
1909
+ label: string;
1910
+ description?: string;
1911
+ placeholder?: string;
1912
+ format?: "string" | "string-array" | "key-value";
1913
+ multiline?: boolean;
1914
+ } | {
1915
+ type: "collection";
1916
+ path: string;
1917
+ label: string;
1918
+ description?: string;
1919
+ items: readonly PhaseSettingsItem[];
1920
+ fields: readonly PhaseSettingsControl[];
1921
+ add?: {
1922
+ label: string;
1923
+ idLabel?: string;
1924
+ fields: readonly PhaseSettingsControl[];
1925
+ };
1926
+ removeLabel?: string;
1927
+ };
1928
+ interface PhaseSettingsSection {
1929
+ id: string;
1930
+ title: string;
1931
+ description?: string;
1932
+ controls: readonly PhaseSettingsControl[];
1854
1933
  }
1855
- interface OwnedStore {
1856
- readonly lease: OwnerLease;
1857
- reserveAgent(input: {
1858
- idempotencyKey: string;
1859
- metadata?: Metadata;
1860
- configIdentity?: string;
1861
- historySeed?: HistorySeed;
1862
- }): Promise<AgentRecord>;
1863
- activateAgent(agentId: AgentId, configToken?: ConfigToken, configIdentity?: string): Promise<AgentRecord>;
1864
- updateAgentConfigToken(input: {
1865
- agentId: AgentId;
1866
- token: ConfigToken;
1867
- configIdentity?: string;
1868
- idempotencyKey: string;
1869
- }): Promise<AgentRecord>;
1870
- deleteAgent(input: AgentDeletionRequest): Promise<void>;
1871
- reviseMessage(input: {
1872
- agentId: AgentId;
1873
- messageId: MessageId;
1874
- expectedMessageRevision: number;
1875
- content: UserContent;
1876
- operationId: string;
1877
- effectDigestConfirmation?: string;
1878
- }): Promise<MessageRevisionResult>;
1879
- compact(input?: {
1880
- now?: string;
1881
- retentionMs?: number;
1882
- }): Promise<RetentionResult>;
1883
- contextStatus(agentId: AgentId, contextWindow: number): Promise<ContextStatus>;
1884
- contextMessages(agentId: AgentId, recentTokenBudget?: number): Promise<readonly Message[]>;
1885
- commitContextCompaction(record: ContextCompactionRecord): Promise<ContextCompactionRecord>;
1886
- createRun(input: {
1887
- agentId: AgentId;
1888
- input: UserInput;
1889
- metadata?: Metadata;
1890
- idempotencyKey: string;
1891
- }): Promise<RunRecord>;
1892
- claimRun(input: {
1893
- runId: RunId;
1894
- expectedRevision: number;
1895
- executionId?: ExecutionId;
1896
- messageId?: MessageId;
1897
- configToken?: ConfigToken;
1898
- }): Promise<RunClaim>;
1899
- failQueuedRun(input: {
1900
- runId: RunId;
1901
- expectedRevision: number;
1902
- failure: QueuedRunFailure;
1903
- }): Promise<RunRecord>;
1904
- commitInputRequired(input: {
1905
- runId: RunId;
1906
- execution: ExecutionToken;
1907
- expectedRevision: number;
1908
- requestId?: InputRequestId;
1909
- phase: string;
1910
- prompt?: AssistantMessage;
1911
- checkpoint: ExecutionCheckpoint;
1912
- interactions?: readonly PhaseInteraction[];
1913
- interactionAnswers?: Readonly<Record<string, JsonValue>>;
1914
- }): Promise<InputRequiredCommit>;
1915
- answerInput(input: {
1916
- runId: RunId;
1917
- requestId: InputRequestId;
1918
- expectedRevision: number;
1919
- input: UserInput;
1920
- messageId?: MessageId;
1921
- }): Promise<RunRecord>;
1922
- answerInteraction(input: {
1923
- runId: RunId;
1924
- interactionId: string;
1925
- expectedRevision: number;
1926
- input: JsonValue;
1927
- }): Promise<RunRecord>;
1928
- commitOutcome(input: {
1929
- runId: RunId;
1930
- execution: ExecutionToken;
1931
- expectedRevision: number;
1932
- outcome?: Outcome;
1933
- failure?: RunFailure;
1934
- output?: AssistantMessage;
1935
- }): Promise<RunRecord>;
1936
- reserveToolCall(input: {
1937
- runId: RunId;
1938
- execution: ExecutionToken;
1939
- expectedRevision: number;
1940
- requestMessageId: MessageId;
1941
- name: string;
1942
- args: JsonValue;
1943
- toolCallId?: ToolCallId;
1944
- providerToolCallId?: string;
1945
- }): Promise<ToolCommit>;
1946
- reserveToolCalls(input: {
1947
- runId: RunId;
1948
- execution: ExecutionToken;
1949
- expectedRevision: number;
1950
- requestMessageId: MessageId;
1951
- calls: readonly ToolCallReservation[];
1952
- }): Promise<ToolBatchCommit>;
1953
- startToolCall(input: {
1954
- runId: RunId;
1955
- execution: ExecutionToken;
1956
- expectedRevision: number;
1957
- toolCallId: ToolCallId;
1958
- }): Promise<ToolCommit>;
1959
- commitToolResult(input: {
1960
- runId: RunId;
1961
- execution: ExecutionToken;
1962
- expectedRevision: number;
1963
- toolCallId: ToolCallId;
1964
- result: ToolExecutionResult$1;
1965
- state: "completed" | "failed" | "indeterminate";
1966
- reason?: string;
1967
- }): Promise<ToolCommit>;
1968
- cancelRun(input: {
1969
- runId: RunId;
1970
- expectedRevision?: number;
1971
- reason?: string;
1972
- output?: AssistantMessage;
1973
- }): Promise<RunRecord>;
1974
- snapshotRun(runId: RunId): Promise<RunSnapshot>;
1975
- history(agentId: AgentId): Promise<readonly Message[]>;
1976
- listAgents(): Promise<readonly AgentRecord[]>;
1977
- listRuns(input?: {
1978
- agentId?: AgentId;
1979
- states?: readonly RunState[];
1980
- }): Promise<readonly RunRecord[]>;
1981
- listEvents(input?: {
1982
- after?: EventCursor;
1983
- }): Promise<readonly DurableRunEvent[]>;
1984
- openConsumer(consumerId: string): Promise<ConsumerRegistration>;
1985
- advanceConsumerCheckpoint(input: {
1986
- consumerId: string;
1987
- cursor: EventCursor;
1988
- }): Promise<void>;
1989
- renewOwner(leaseMs: number): Promise<OwnerLease>;
1990
- sealAndReleaseOwner(): Promise<void>;
1934
+ /** Declarative, host-neutral Settings surface contributed by a Phase. */
1935
+ interface PhaseSettingsDefinition {
1936
+ description?: string;
1937
+ sections: readonly PhaseSettingsSection[];
1938
+ }
1939
+ /** Host context is intentionally opaque beyond the effective configuration. */
1940
+ interface PhaseSettingsContext {
1941
+ configuration: Readonly<Record<string, unknown>>;
1942
+ metadata?: Readonly<Record<string, unknown>>;
1943
+ }
1944
+ type PhaseSettingsProvider = (context: PhaseSettingsContext) => PhaseSettingsDefinition | Promise<PhaseSettingsDefinition>;
1945
+ /**
1946
+ * Loaded Phase object
1947
+ */
1948
+ interface Phase {
1949
+ /** Unique phase identity and display name. */
1950
+ name: string;
1951
+ /** Rowan-owned built-in Phase; built-ins are never filtered or disabled. */
1952
+ core?: boolean;
1953
+ /** Description */
1954
+ description: string;
1955
+ /** Restricted tools (undefined = all tools available) */
1956
+ tools?: string[];
1957
+ /** Skills bundled directly inside this phase directory. Inline phases may omit this (equivalent to []). */
1958
+ skills?: Skill[];
1959
+ /** Forced next phase */
1960
+ target?: string;
1961
+ /** Structural JSON-safe input defaults */
1962
+ input?: PhaseInput;
1963
+ /** If true, phase gets a fresh context when executed in parallel */
1964
+ isolated?: boolean;
1965
+ /** Path to PHASE.md file */
1966
+ filePath: string;
1967
+ /** Phase directory path */
1968
+ baseDir: string;
1969
+ /** PHASE.md body content */
1970
+ content: string;
1971
+ /** Model override for this phase (resolved from frontmatter) */
1972
+ model?: ModelRef;
1973
+ /** Do not automatically inject this Phase into the model route catalog/context. */
1974
+ disableAutoInvocation?: boolean;
1975
+ /** Do not expose this Phase to direct user invocation. */
1976
+ disableImplicitInvocation?: boolean;
1977
+ /** ExtensionAPI factory function used for registration or programmatic execution. */
1978
+ factory?: (api: ExtensionAPI) => Promise<void>;
1979
+ /** Direct run function */
1980
+ run?: (context: PhaseContext, execution: PhaseExecution) => Promise<PhaseOutput | void>;
1981
+ }
1982
+ /**
1983
+ * Phase registry containing all loaded phases
1984
+ */
1985
+ interface PhaseRegistry {
1986
+ /** Map of phase name to Phase object */
1987
+ phases: Map<string, Phase>;
1988
+ /** Entry phase name (null until Agent applies its default phase) */
1989
+ entryPhaseId: string | null;
1991
1990
  }
1992
- interface DurableStore {
1993
- openOwner(input: {
1994
- ownerId: string;
1995
- leaseMs: number;
1996
- }): Promise<OwnedStore>;
1991
+
1992
+ interface BeforePhaseEvent {
1993
+ type: "before_phase";
1994
+ phaseId: string;
1995
+ input: PhaseContext;
1997
1996
  }
1998
- type AgentRuntimeOptions = Readonly<{
1999
- store: DurableStore;
2000
- configs?: ConfigProvider;
2001
- concurrency?: number;
2002
- bootstrap?: (registry: RuntimeBootstrapRegistry) => void | Promise<void>;
2003
- }>;
2004
- type DurableConsumer = Readonly<{
2005
- caughtUp: Promise<void>;
2006
- done: Promise<void>;
2007
- stop(): void;
2008
- }>;
2009
- interface AgentRun {
2010
- readonly id: RunId;
2011
- snapshot(): Promise<RunSnapshot>;
2012
- observe(options?: {
2013
- after?: EventCursor;
2014
- signal?: AbortSignal;
2015
- }): AsyncIterable<RunEvent>;
2016
- wait(options?: {
2017
- signal?: AbortSignal;
2018
- }): Promise<RunBoundary>;
2019
- respond(input: {
2020
- requestId: InputRequestId;
2021
- input: UserInput;
2022
- }): Promise<void>;
2023
- respondInteraction(input: {
2024
- interactionId: string;
2025
- input: JsonValue;
2026
- }): Promise<void>;
2027
- cancel(reason?: string): Promise<RunBoundary>;
1997
+ interface AfterPhaseEvent {
1998
+ type: "after_phase";
1999
+ phaseId: string;
2000
+ output: PhaseOutput;
2028
2001
  }
2029
- interface AgentRuntime$1 {
2030
- loadAgents(input: LoadInput<AgentDefinition>): Promise<LoadResult>;
2031
- loadSkills(input: LoadInput<Skill>): Promise<LoadResult>;
2032
- loadPhases(input: LoadInput<Phase>): Promise<LoadResult>;
2033
- loadTools(input: Readonly<{
2034
- sourceId: string;
2035
- values: readonly Tool[];
2036
- }>): Promise<LoadResult>;
2037
- unload(input: Readonly<{
2038
- kind: ResourceKind;
2039
- sourceId: string;
2040
- }>): Promise<LoadResult>;
2041
- createAgent(config: AgentConfiguration, options?: {
2042
- idempotencyKey?: string;
2043
- metadata?: Metadata;
2044
- historySeed?: HistorySeed;
2045
- }): Promise<AgentId>;
2046
- updateAgentConfig(agentId: AgentId, config: AgentConfiguration, options: {
2047
- idempotencyKey: string;
2048
- }): Promise<void>;
2049
- deleteAgent(input: AgentDeletionRequest): Promise<void>;
2050
- revise(agentId: AgentId, input: {
2051
- messageId: MessageId;
2052
- expectedMessageRevision: number;
2053
- content: UserContent;
2054
- operationId: string;
2055
- effectDigestConfirmation?: string;
2056
- }): Promise<MessageRevisionResult>;
2057
- compact(input?: {
2058
- now?: string;
2059
- retentionMs?: number;
2060
- }): Promise<RetentionResult>;
2061
- start(agentId: AgentId, input: UserInput, options: {
2062
- idempotencyKey: string;
2063
- metadata?: Metadata;
2064
- }): Promise<AgentRun>;
2065
- run(runId: RunId): AgentRun;
2066
- contextStatus(agentId: AgentId, options?: {
2067
- contextWindow?: number;
2068
- }): Promise<ContextStatus>;
2069
- compactContext(agentId: AgentId, options?: {
2070
- input?: UserInput;
2071
- instructions?: string;
2072
- idempotencyKey?: string;
2073
- }): Promise<AgentRun>;
2074
- listInvocations(agentId: AgentId, options: {
2075
- source: InvocationSource;
2076
- }): Promise<readonly InvocationCatalogEntry[]>;
2077
- history(agentId: AgentId): Promise<readonly Message[]>;
2078
- listAgents(input?: {
2079
- after?: AgentListCursor;
2080
- limit?: number;
2081
- }): Promise<Page<AgentSummary, AgentListCursor>>;
2082
- listRuns(input?: {
2083
- agentId?: AgentId;
2084
- states?: readonly RunState[];
2085
- after?: RunListCursor;
2086
- limit?: number;
2087
- }): Promise<Page<RunSummary, RunListCursor>>;
2088
- consume(input: {
2089
- consumerId: string;
2090
- signal: AbortSignal;
2091
- onEvent(event: DurableRunEvent, context: Readonly<{
2092
- signal: AbortSignal;
2093
- }>): void | Promise<void>;
2094
- }): Promise<DurableConsumer>;
2095
- close(): Promise<void>;
2002
+ interface BeforePromptEvent {
2003
+ type: "before_prompt";
2004
+ phaseId: string;
2005
+ input: PhaseContext;
2096
2006
  }
2097
- type ConsumerRegistration = Readonly<{
2098
- cursor?: EventCursor;
2099
- waterline: EventCursor;
2100
- }>;
2007
+ interface BeforeToolCallEvent {
2008
+ type: "before_tool_call";
2009
+ tool: Tool;
2010
+ args: unknown;
2011
+ readonly runId?: string;
2012
+ readonly agentId?: string;
2013
+ readonly toolCallId?: string;
2014
+ readonly metadata?: Readonly<Record<string, unknown>>;
2015
+ readonly answer?: unknown;
2016
+ }
2017
+ interface AfterToolCallEvent {
2018
+ type: "after_tool_call";
2019
+ tool: Tool;
2020
+ result: ToolResult;
2021
+ readonly runId?: string;
2022
+ readonly agentId?: string;
2023
+ readonly toolCallId?: string;
2024
+ readonly metadata?: Readonly<Record<string, unknown>>;
2025
+ }
2026
+ type HookEvent = BeforePhaseEvent | AfterPhaseEvent | BeforePromptEvent | BeforeToolCallEvent | AfterToolCallEvent;
2027
+ interface BeforePhaseResult {
2028
+ abort?: Outcome$1;
2029
+ skip?: {
2030
+ route: string;
2031
+ message: string;
2032
+ };
2033
+ input?: PhaseContext;
2034
+ }
2035
+ interface AfterPhaseResult {
2036
+ abort?: Outcome$1;
2037
+ retry?: PhaseContext;
2038
+ output?: PhaseOutput;
2039
+ }
2040
+ interface BeforePromptResult {
2041
+ input?: PhaseContext;
2042
+ }
2043
+ interface BeforeToolCallResult {
2044
+ allow?: boolean;
2045
+ reason?: string;
2046
+ interaction?: RunInteractionRequest;
2047
+ }
2048
+ interface AfterToolCallResult {
2049
+ result?: ToolResult;
2050
+ }
2051
+ interface HookResultMap {
2052
+ before_phase: BeforePhaseResult | undefined;
2053
+ after_phase: AfterPhaseResult | undefined;
2054
+ before_prompt: BeforePromptResult | undefined;
2055
+ before_tool_call: BeforeToolCallResult | undefined;
2056
+ after_tool_call: AfterToolCallResult | undefined;
2057
+ }
2058
+ type HookEventType = HookEvent["type"];
2059
+ type HookHandler<K extends HookEventType> = (event: Extract<HookEvent, {
2060
+ type: K;
2061
+ }>) => HookResultMap[K] | Promise<HookResultMap[K]> | void | Promise<void>;
2062
+ declare class HooksManager {
2063
+ private handlers;
2064
+ on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
2065
+ off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
2066
+ emit<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
2067
+ type: K;
2068
+ }>): Promise<void>;
2069
+ emitFirst<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
2070
+ type: K;
2071
+ }>): Promise<HookResultMap[K] | undefined>;
2072
+ }
2073
+
2074
+ type ToolContext = Pick<AgentContext, "skills"> & {
2075
+ toolCallId: string;
2076
+ interaction?: RunInteractionDriver;
2077
+ };
2078
+ type ToolExecutionMode = "sequential" | "parallel";
2079
+ type Tool<TArgs = unknown> = {
2080
+ name: string;
2081
+ /** Rowan-owned Core Tool; Core Tools bypass Phase filtering. */
2082
+ core?: boolean;
2083
+ description: string;
2084
+ parameters: Type.TSchema;
2085
+ /** One-line snippet shown in the system prompt tool list. */
2086
+ promptSnippet?: string;
2087
+ /** Additional guidelines appended to the system prompt when this tool is active. */
2088
+ promptGuidelines?: string[];
2089
+ /** Whether this tool can run concurrently with others. Default: "parallel". */
2090
+ executionMode?: ToolExecutionMode;
2091
+ execute(args: TArgs, context: ToolContext, signal?: AbortSignal): Promise<ToolResult>;
2092
+ };
2093
+ /** Context snapshot passed into the low-level agent loop. */
2094
+ type AgentContext = {
2095
+ /** System prompt included with the request. */
2096
+ systemPrompt: string;
2097
+ /** Transcript visible to the model. */
2098
+ messages: AgentMessage[];
2099
+ /** Tools available for this run. */
2100
+ tools: Tool[];
2101
+ /** Skills available for this run. */
2102
+ skills: Skill[];
2103
+ /** Custom phases for this run. Agent normalizes this with the built-in default phase. */
2104
+ phases?: PhaseRegistry;
2105
+ };
2106
+
2107
+ /**
2108
+ * `root` anchors relative paths and the Bash working directory. It is not a
2109
+ * filesystem sandbox: core Tools use the permissions of the host process.
2110
+ */
2111
+ type CoreToolContext = {
2112
+ root?: string;
2113
+ /** Directory for complete Tool Result spill files. */
2114
+ archiveDir?: string;
2115
+ maxReadBytes?: number;
2116
+ maxReadLines?: number;
2117
+ bashTimeoutMs?: number;
2118
+ maxBashOutputBytes?: number;
2119
+ };
2101
2120
 
2102
2121
  declare class AgentRuntime implements AgentRuntime$1 {
2103
2122
  private readonly concurrency;
@@ -2123,7 +2142,7 @@ declare class AgentRuntime implements AgentRuntime$1 {
2123
2142
  loadPhases(input: LoadInput<Phase>): Promise<LoadResult>;
2124
2143
  loadTools(input: Readonly<{
2125
2144
  sourceId: string;
2126
- values: readonly Tool[];
2145
+ values: readonly Tool$1[];
2127
2146
  }>): Promise<LoadResult>;
2128
2147
  unload(input: Readonly<{
2129
2148
  kind: ResourceKind;
@@ -2191,13 +2210,10 @@ declare class AgentRuntime implements AgentRuntime$1 {
2191
2210
  close(): Promise<void>;
2192
2211
  snapshot(runId: RunId): Promise<RunSnapshot>;
2193
2212
  history(agentId: AgentId): Promise<readonly Message[]>;
2194
- respond(runId: RunId, input: {
2195
- requestId: InputRequestId;
2196
- input: UserInput;
2197
- }): Promise<void>;
2198
2213
  respondInteraction(runId: RunId, input: {
2199
2214
  interactionId: string;
2200
- input: JsonValue;
2215
+ input?: JsonValue;
2216
+ cancel?: boolean;
2201
2217
  }): Promise<void>;
2202
2218
  cancel(runId: RunId, reason?: string): Promise<RunBoundary>;
2203
2219
  private pump;
@@ -2206,6 +2222,7 @@ declare class AgentRuntime implements AgentRuntime$1 {
2206
2222
  private resolveContextWindow;
2207
2223
  private executeTool;
2208
2224
  private executeToolBatch;
2225
+ private foldToolInteractionRecords;
2209
2226
  private requireAgent;
2210
2227
  private archiveDirFor;
2211
2228
  private runConsumer;
@@ -2298,6 +2315,7 @@ declare class InMemoryStore implements DurableStore {
2298
2315
  operationId: string;
2299
2316
  effectDigestConfirmation?: string;
2300
2317
  }): MessageRevisionResult;
2318
+ private commitInteractionRecord;
2301
2319
  createRun(lease: OwnerLease, input: {
2302
2320
  agentId: AgentId;
2303
2321
  input: UserInput;
@@ -2318,29 +2336,30 @@ declare class InMemoryStore implements DurableStore {
2318
2336
  code: "configuration_unavailable" | "checkpoint_incompatible";
2319
2337
  }>;
2320
2338
  }): RunRecord;
2339
+ commitPhaseEntered(lease: OwnerLease, input: {
2340
+ runId: RunId;
2341
+ execution: ExecutionToken;
2342
+ expectedRevision: number;
2343
+ phaseId: string;
2344
+ visit: number;
2345
+ }): RunRecord;
2321
2346
  commitInputRequired(lease: OwnerLease, input: {
2322
2347
  runId: RunId;
2323
2348
  execution: ExecutionToken;
2324
2349
  expectedRevision: number;
2325
- requestId?: InputRequestId;
2326
2350
  phase: string;
2327
2351
  prompt?: AssistantMessage;
2328
2352
  checkpoint: ExecutionCheckpoint;
2329
- interactions?: readonly PhaseInteraction[];
2353
+ interactions?: readonly RunInteraction[];
2330
2354
  interactionAnswers?: Readonly<Record<string, JsonValue>>;
2331
- }): InputRequiredCommit;
2332
- answerInput(lease: OwnerLease, input: {
2333
- runId: RunId;
2334
- requestId: InputRequestId;
2335
- expectedRevision: number;
2336
- input: UserInput;
2337
- messageId?: MessageId;
2355
+ pendingToolCallIds?: readonly ToolCallId[];
2338
2356
  }): RunRecord;
2339
2357
  answerInteraction(lease: OwnerLease, input: {
2340
2358
  runId: RunId;
2341
2359
  interactionId: string;
2342
2360
  expectedRevision: number;
2343
- input: JsonValue;
2361
+ input?: JsonValue;
2362
+ cancel?: boolean;
2344
2363
  }): RunRecord;
2345
2364
  reserveToolCall(lease: OwnerLease, input: {
2346
2365
  runId: RunId;
@@ -2370,6 +2389,12 @@ declare class InMemoryStore implements DurableStore {
2370
2389
  expectedRevision: number;
2371
2390
  toolCallId: ToolCallId;
2372
2391
  }): ToolCommit;
2392
+ suspendToolCall(lease: OwnerLease, input: {
2393
+ runId: RunId;
2394
+ execution: ExecutionToken;
2395
+ expectedRevision: number;
2396
+ toolCallId: ToolCallId;
2397
+ }): ToolCommit;
2373
2398
  commitToolResult(lease: OwnerLease, input: {
2374
2399
  runId: RunId;
2375
2400
  execution: ExecutionToken;
@@ -2514,29 +2539,30 @@ declare class SqliteStore implements DurableStore {
2514
2539
  code: "configuration_unavailable" | "checkpoint_incompatible";
2515
2540
  }>;
2516
2541
  }): Promise<RunRecord>;
2542
+ commitPhaseEntered(lease: OwnerLease, input: {
2543
+ runId: RunId;
2544
+ execution: ExecutionToken;
2545
+ expectedRevision: number;
2546
+ phaseId: string;
2547
+ visit: number;
2548
+ }): Promise<RunRecord>;
2517
2549
  commitInputRequired(lease: OwnerLease, input: {
2518
2550
  runId: RunId;
2519
2551
  execution: ExecutionToken;
2520
2552
  expectedRevision: number;
2521
- requestId?: InputRequestId;
2522
2553
  phase: string;
2523
2554
  prompt?: AssistantMessage;
2524
2555
  checkpoint: ExecutionCheckpoint;
2525
- interactions?: readonly PhaseInteraction[];
2556
+ interactions?: readonly RunInteraction[];
2526
2557
  interactionAnswers?: Readonly<Record<string, JsonValue>>;
2527
- }): Promise<InputRequiredCommit>;
2528
- answerInput(lease: OwnerLease, input: {
2529
- runId: RunId;
2530
- requestId: InputRequestId;
2531
- expectedRevision: number;
2532
- input: UserInput;
2533
- messageId?: MessageId;
2558
+ pendingToolCallIds?: readonly ToolCallId[];
2534
2559
  }): Promise<RunRecord>;
2535
2560
  answerInteraction(lease: OwnerLease, input: {
2536
2561
  runId: RunId;
2537
2562
  interactionId: string;
2538
2563
  expectedRevision: number;
2539
- input: JsonValue;
2564
+ input?: JsonValue;
2565
+ cancel?: boolean;
2540
2566
  }): Promise<RunRecord>;
2541
2567
  commitOutcome(lease: OwnerLease, input: {
2542
2568
  runId: RunId;
@@ -2574,6 +2600,12 @@ declare class SqliteStore implements DurableStore {
2574
2600
  expectedRevision: number;
2575
2601
  toolCallId: ToolCallId;
2576
2602
  }): Promise<ToolCommit>;
2603
+ suspendToolCall(lease: OwnerLease, input: {
2604
+ runId: RunId;
2605
+ execution: ExecutionToken;
2606
+ expectedRevision: number;
2607
+ toolCallId: ToolCallId;
2608
+ }): Promise<ToolCommit>;
2577
2609
  commitToolResult(lease: OwnerLease, input: {
2578
2610
  runId: RunId;
2579
2611
  execution: ExecutionToken;
@@ -2699,7 +2731,8 @@ type RuntimeErrorDetails = {
2699
2731
  }>;
2700
2732
  input_request_conflict: Readonly<{
2701
2733
  runId: RunId;
2702
- requestId: InputRequestId;
2734
+ interactionId?: string;
2735
+ requestId?: string;
2703
2736
  reason: "not_found" | "wrong_run" | "different_answer";
2704
2737
  }>;
2705
2738
  idempotency_conflict: Readonly<{
@@ -2816,6 +2849,6 @@ interface FrontmatterResult<T = Record<string, unknown>> {
2816
2849
  */
2817
2850
  declare function parseFrontmatter<T = Record<string, unknown>>(raw: string): FrontmatterResult<T>;
2818
2851
 
2819
- declare function createCoreTools(input?: CoreToolContext): Tool[];
2852
+ declare function createCoreTools(input?: CoreToolContext): Tool$1[];
2820
2853
 
2821
- export { type AfterToolCall, type AgentConfiguration, type AgentDefinition, type AgentId, type AgentListCursor, type AgentRecord, type AgentRun, AgentRuntime, type AgentRuntimeOptions, type AgentSummary, type AnyRuntimeError, type AssistantContent, type AssistantMessage, type BeforeToolCall, COMPACT_PHASE_ID, type ConfigProvider, type ConfigPutResult, type ConfigResolution, type ConfigToken, type ConfigurationSnapshot, type ContextCandidate, type ContextCompactionRecord, type ContextStatus, type CoreToolContext, DEFAULT_PHASE_ID, type DefinitionLayer, type DurableConsumer, type DurableRunEvent, type DurableStore, type DurableToolResult, type EventCursor, type EventId, type ExecutionCheckpoint, type ExecutionId, type ExecutionToken, type ExtensionAPI, type ExtensionActivationError, type ExtensionActivationResult, type ExtensionContribution, type ExtensionDisposer, type ExtensionFactory, type ExtensionFactoryResult, ExtensionLifetimeError, type ExtensionLifetimeErrorCode, type ExtensionLoadInput, type FrontmatterResult, type HistorySeed, type HookEvent, type HookEventType, type HookHandler, InMemoryConfigProvider, InMemoryStore, type InputRequest, type InputRequestId, type InputRequiredCommit, type InvocationCatalogEntry, type InvocationSource, type JsonObject, type JsonPrimitive, type JsonValue, type LoadExtensionsResult, type LoadInput, type LoadResult, type LoadedExtension, type Message, type MessageBase, type MessageCommitted, type MessageContent, type MessageDelta, type MessageId, type MessageRevised, type MessageRevisionResult, type Metadata, type OpaqueId, type Outcome, type OwnerLease, type OwnerToken, type Page, type Phase, type PhaseContext, type PhaseContribution, type PhaseExecution, type PhaseExecutionIdentity, type PhaseInput, type PhaseInteraction, PhaseInteractionBoundary, PhaseInteractionCancelledError, type PhaseInteractionDriver, type PhaseInteractionKind, type PhaseInteractionOrigin, type PhaseInteractionState, type PhaseInteractionStatus, type PhaseInvocation, type PhaseMessageManager, type PhaseOutput, type PhaseRegistry, type PhaseRegistrySelection, type PhaseSettingsBadge, type PhaseSettingsContext, type PhaseSettingsControl, type PhaseSettingsDefinition, type PhaseSettingsItem, type PhaseSettingsOption, type PhaseSettingsProvider, type PhaseSettingsSection, type PhaseState, type PhaseStatus, type PhaseStatusState, type ResolvedResourceView, type ResourceDiagnostic, type ResourceKind, type ResourceRef, ResourceRegistry, ResourceRegistryError, type ResourceRegistryErrorCode, type ResourceSourceId, type ResourceView, type RetentionResult, type RunBoundary, type RunClaim, type RunEvent, type RunFailure, type RunId, type RunListCursor, type RunRecord, type RunSnapshot, type RunState, type RunStateChanged, type RunSummary, RuntimeBootstrapRegistry, RuntimeError, type RuntimeErrorCode, type RuntimeErrorDetails, RuntimeExtensionLifetime, STOP_PHASE_ID, type Skill, SqliteStore, type TextContent, type ThinkingContent, type ThinkingDelta, type Tool, type ToolCallId, type ToolCallInteractionRequest, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult$1 as ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolProgress, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, brandConfigToken, createCompactPhase, createCorePhases, createCoreTools, createDefaultPhase, createStopPhase, isConfigurationSnapshot, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhaseSettings, loadPhases, loadSkill, loadSkills, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };
2854
+ export { type AfterToolCall, type AgentConfiguration, type AgentDefinition, type AgentId, type AgentListCursor, type AgentRecord, type AgentRun, AgentRuntime, type AgentRuntimeOptions, type AgentSummary, type AnyRuntimeError, type AssistantContent, type AssistantMessage, type BeforeToolCall, COMPACT_PHASE_ID, type ConfigProvider, type ConfigPutResult, type ConfigResolution, type ConfigToken, type ConfigurationSnapshot, type ContextCandidate, type ContextCompactionRecord, type ContextStatus, type CoreToolContext, DEFAULT_PHASE_ID, type DefinitionLayer, type DurableConsumer, type DurableRunEvent, type DurableStore, type DurableToolResult, type EventCursor, type EventId, type ExecutionCheckpoint, type ExecutionId, type ExecutionToken, type ExtensionAPI, type ExtensionActivationError, type ExtensionActivationResult, type ExtensionContribution, type ExtensionDisposer, type ExtensionFactory, type ExtensionFactoryResult, ExtensionLifetimeError, type ExtensionLifetimeErrorCode, type ExtensionLoadInput, type FrontmatterResult, type HistorySeed, type HookEvent, type HookEventType, type HookHandler, InMemoryConfigProvider, InMemoryStore, type InteractionRecord, type InvocationCatalogEntry, type InvocationSource, type JsonObject, type JsonPrimitive, type JsonValue, type LoadExtensionsResult, type LoadInput, type LoadResult, type LoadedExtension, type Message, type MessageBase, type MessageCommitted, type MessageContent, type MessageDelta, type MessageId, type MessageRevised, type MessageRevisionResult, type Metadata, type OpaqueId, type Outcome, type OwnerLease, type OwnerToken, type Page, type Phase, type PhaseContext, type PhaseContribution, type PhaseExecution, type PhaseExecutionIdentity, type PhaseInput, type PhaseInvocation, type PhaseMessageManager, type PhaseOutput, type PhaseRegistry, type PhaseRegistrySelection, type PhaseSettingsBadge, type PhaseSettingsContext, type PhaseSettingsControl, type PhaseSettingsDefinition, type PhaseSettingsItem, type PhaseSettingsOption, type PhaseSettingsProvider, type PhaseSettingsSection, type PhaseState, type PhaseStatus, type PhaseStatusState, type ResolvedResourceView, type ResourceDiagnostic, type ResourceKind, type ResourceRef, ResourceRegistry, ResourceRegistryError, type ResourceRegistryErrorCode, type ResourceSourceId, type ResourceView, type RetentionResult, type RunBoundary, type RunClaim, type RunEvent, type RunFailure, type RunId, type RunInteraction, RunInteractionBoundary, RunInteractionCancelledError, type RunInteractionDriver, type RunInteractionKind, type RunInteractionRequest, type RunInteractionState, type RunInteractionStatus, type RunListCursor, type RunRecord, type RunSnapshot, type RunState, type RunStateChanged, type RunSummary, RuntimeBootstrapRegistry, RuntimeError, type RuntimeErrorCode, type RuntimeErrorDetails, RuntimeExtensionLifetime, STOP_PHASE_ID, type Skill, SqliteStore, type TextContent, type ThinkingContent, type ThinkingDelta, type Tool$1 as Tool, type ToolCallContext, type ToolCallId, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult$1 as ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolProgress, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, brandConfigToken, createCompactPhase, createCorePhases, createCoreTools, createDefaultPhase, createStopPhase, isConfigurationSnapshot, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhaseSettings, loadPhases, loadSkill, loadSkills, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };