@rowan-agent/agent 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +1613 -1625
  2. package/dist/index.js +60 -32
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,8 +1,27 @@
1
1
  import * as _rowan_agent_models from '@rowan-agent/models';
2
- import { ContentBlock, ModelRef, LlmTokenUsage, LlmContentPart, ScopeRef, ToolCallStatus, JsonValue as JsonValue$1, ToolProgress, ToolCallContent, ToolCallLocation, JsonObject as JsonObject$1, ToolKind, ModelConfig, StreamFn, ToolAnnotations, ThinkingLevel, ToolCall as ToolCall$1, ToolCallUpdate } from '@rowan-agent/models';
2
+ import { ModelRef, ContentBlock, LlmTokenUsage, LlmContentPart, ScopeRef, ToolKind, ToolAnnotations, ToolCallStatus, ToolProgress, ToolCallContent, ToolCallLocation, JsonValue as JsonValue$1, JsonObject as JsonObject$1, ModelConfig, StreamFn, ThinkingLevel, ToolCall as ToolCall$1, ToolCallUpdate } from '@rowan-agent/models';
3
3
  export { ModelConfig, ModelRef, ProviderCallContext, ProviderConfig, ProviderModelConfig, ProviderStreamFn, ScopeRef, StreamFn, ThinkingLevel, ToolAnnotations, ToolCall, ToolCallContent, ToolCallLocation, ToolCallOptions, ToolCallOutcome, ToolCallStatus, ToolCallUpdate, ToolDefinitionSummary, ToolKind, ToolProgress } from '@rowan-agent/models';
4
4
  import Type from 'typebox';
5
5
 
6
+ type PhaseRegistrySelection = Readonly<{
7
+ entryPhaseId: string | null;
8
+ phaseIds: readonly string[];
9
+ }>;
10
+ type AgentDefinition = Readonly<{
11
+ name: string;
12
+ description: string;
13
+ prompt: string;
14
+ tools?: readonly string[];
15
+ skills?: readonly string[];
16
+ /** Host-supplied Skills private to this Agent Definition/Bundle. */
17
+ bundledSkills?: readonly Skill[];
18
+ phases?: PhaseRegistrySelection;
19
+ contexts?: readonly string[];
20
+ model?: ModelRef;
21
+ }>;
22
+ /** Parse one Markdown definition using the same frontmatter vocabulary as Phase resources. */
23
+ declare function parseAgentDefinition(raw: string): AgentDefinition;
24
+
6
25
  type ModelInvokeOutput = {
7
26
  text: string;
8
27
  contentBlocks: ContentBlock[];
@@ -16,25 +35,13 @@ type InternalModelLoopOptions = {
16
35
  tools?: readonly string[];
17
36
  maxToolRounds?: number;
18
37
  };
19
- /** Snapshot of phase-level context for restore */
20
- type PhaseContextSnapshot = {
21
- systemPrompt: string;
22
- messages: AgentMessage[];
23
- currentPhase: string;
24
- availablePhases: string[];
25
- turnNumber: number;
26
- payload?: unknown;
27
- };
28
38
  /** Execution capabilities for a phase — operates on PhaseContext. */
29
39
  type PhaseExecution = {
30
- snapshot(): PhaseContextSnapshot;
31
- restore(snapshot: PhaseContextSnapshot): void;
32
40
  invokeModel(context: PhaseContext, options?: {
33
41
  output?: "reply" | "internal";
34
42
  }): Promise<ModelInvokeOutput>;
35
43
  runInternalModelLoop(context: PhaseContext, options: InternalModelLoopOptions): Promise<ModelInvokeOutput>;
36
44
  reportStatus(status: PhaseStatus): Promise<void>;
37
- executeTool(context: AgentContext, toolCall: ToolCall): Promise<ToolResult>;
38
45
  executeTools(context: AgentContext, toolCalls: readonly ToolCall[], contentBlocks?: readonly ContentBlock[], meta?: {
39
46
  model?: ModelRef;
40
47
  usage?: LlmTokenUsage;
@@ -64,150 +71,241 @@ type PhaseMessageManager = {
64
71
  discard(messageId: string): void;
65
72
  };
66
73
 
67
- type PhaseRegistrySelection = Readonly<{
68
- entryPhaseId: string | null;
69
- phaseIds: readonly string[];
70
- }>;
71
- type AgentDefinition = Readonly<{
74
+ interface ExtensionStateStore {
75
+ get(key: string): Promise<JsonValue | undefined>;
76
+ set(key: string, value: JsonValue): Promise<void>;
77
+ delete(key: string): Promise<void>;
78
+ }
79
+ interface ExtensionHost {
80
+ getConfig(extensionId: string, scope?: ScopeRef): Promise<JsonObject | null> | JsonObject | null;
81
+ onConfigChanged?(listener: (extensionId: string, scope: ScopeRef) => void): (() => void) | void;
82
+ getAgentState(extensionId: string, agentId: string, key: string): Promise<JsonValue | undefined> | JsonValue | undefined;
83
+ setAgentState(extensionId: string, agentId: string, key: string, value: JsonValue): Promise<void> | void;
84
+ deleteAgentState(extensionId: string, agentId: string, key: string): Promise<void> | void;
85
+ getGlobalState(extensionId: string, key: string): Promise<JsonValue | undefined> | JsonValue | undefined;
86
+ setGlobalState(extensionId: string, key: string, value: JsonValue): Promise<void> | void;
87
+ deleteGlobalState(extensionId: string, key: string): Promise<void> | void;
88
+ /**
89
+ * Called once per extension load. The returned namespaces are merged into that extension's `api`
90
+ * (a name already used by Rowan's own API is an error). `dispose` runs when the extension is
91
+ * unloaded, reloaded or fails activation, so the host can drop everything that extension registered.
92
+ */
93
+ extendApi?(extensionId: string): HostApiExtension | undefined;
94
+ }
95
+ interface HostApiExtension {
96
+ readonly namespaces: Readonly<Record<string, unknown>>;
97
+ dispose?(): void;
98
+ }
99
+ type ExtensionToolContribution = {
100
+ kind: "tool";
72
101
  name: string;
73
102
  description: string;
74
- prompt: string;
75
- tools?: readonly string[];
76
- skills?: readonly string[];
77
- /** Host-supplied Skills private to this Agent Definition/Bundle. */
78
- bundledSkills?: readonly Skill[];
79
- phases?: PhaseRegistrySelection;
80
- contexts?: readonly string[];
81
- model?: ModelRef;
82
- }>;
83
- /** Parse one Markdown definition using the same frontmatter vocabulary as Phase resources. */
84
- declare function parseAgentDefinition(raw: string): AgentDefinition;
85
-
86
- type ResourceKind = "agent" | "tool" | "skill" | "phase";
87
- type ResourceSourceId = string;
88
- /** Rowan-native contribution aliases. Hosts may adapt their domain handlers to
89
- * these existing Tool/Phase lifecycles without importing host Scope types. */
90
- type ToolContribution = Tool$1;
91
- type PhaseContribution = Phase;
92
- type ResourceView = Readonly<{
93
- agents: readonly ResourceSourceId[];
94
- tools: readonly ResourceSourceId[];
95
- skills: readonly ResourceSourceId[];
96
- phases: readonly ResourceSourceId[];
97
- }>;
98
- type ResourceRef = Readonly<{
99
- kind: ResourceKind;
100
- sourceId: ResourceSourceId;
103
+ };
104
+ type ExtensionCapabilityContribution = ExtensionToolContribution;
105
+ type ExtensionCapability = {
106
+ extensionId: string;
107
+ kind: "tool";
101
108
  name: string;
102
- }>;
103
- type ResourceDiagnostic = Readonly<{
104
- kind: "invalid" | "missing" | "collision";
105
- sourceId: ResourceSourceId;
106
- message: string;
107
- path?: string;
108
- }>;
109
- type LoadResult = Readonly<{
110
- revision: string;
111
- registered: readonly ResourceRef[];
112
- skipped: readonly ResourceDiagnostic[];
113
- }>;
114
- type LoadInput<T> = Readonly<{
115
- sourceId: ResourceSourceId;
116
- directory?: string;
117
- values?: readonly T[];
118
- }>;
119
- type ResolvedResourceView = Readonly<{
120
- agents: readonly AgentDefinition[];
121
- tools: readonly Tool$1[];
122
- skills: readonly Skill[];
123
- phases: readonly Phase[];
124
- revisions: Readonly<Record<ResourceKind, readonly string[]>>;
125
- refs: Readonly<Record<ResourceKind, readonly ResourceRef[]>>;
126
- }>;
127
- type ResourceRegistryErrorCode = "invalid_source_id" | "invalid_resource_name" | "resource_collision" | "resource_input_missing" | "resource_directory_not_supported" | "unknown_resource_source" | "implicit_source_protected";
128
- declare class ResourceRegistryError extends Error {
129
- readonly code: ResourceRegistryErrorCode;
130
- constructor(code: ResourceRegistryErrorCode, message: string);
131
- }
132
- type RegistryValue = AgentDefinition | Tool$1 | Skill | Phase;
133
- /**
134
- * Runtime Resource Registry source transaction and view resolver.
135
- *
136
- * Directory normalization is intentionally added by the typed loader slice;
137
- * this first module owns only the atomic source/revision/collision semantics.
138
- */
139
- declare class ResourceRegistry {
140
- private readonly sources;
141
- /** Sources registered by the bootstrap boundary (currently Extensions). */
142
- private readonly implicitSources;
143
- private revisionSequence;
144
- loadAgents(input: LoadInput<AgentDefinition>): Promise<LoadResult>;
145
- loadSkills(input: LoadInput<Skill>): Promise<LoadResult>;
146
- loadPhases(input: LoadInput<Phase>): Promise<LoadResult>;
147
- loadTools(input: Readonly<{
148
- sourceId: ResourceSourceId;
149
- values: readonly ToolContribution[];
150
- }>): Promise<LoadResult>;
151
- unload(input: Readonly<{
152
- kind: ResourceKind;
153
- sourceId: ResourceSourceId;
154
- }>): Promise<LoadResult>;
155
- resolveView(view: ResourceView): ResolvedResourceView;
156
- /** Mark one already-loaded source as implicit for every Resource View. */
157
- protected markImplicit(kind: ResourceKind, sourceId: ResourceSourceId): void;
158
- /** Bootstrap-only helper for replacing an implicit contribution source. */
159
- protected replaceImplicit<T extends RegistryValue>(kind: ResourceKind, sourceId: ResourceSourceId, values: readonly T[]): Promise<LoadResult>;
160
- protected hasImplicit(kind: ResourceKind, sourceId: ResourceSourceId): boolean;
161
- private withImplicit;
162
- private collect;
163
- private commit;
164
- private resolveKind;
165
- private resolveRevisions;
166
- private resolveRefs;
167
- private sourcesFor;
168
- private nextRevision;
109
+ description: string;
110
+ };
111
+ interface SourceInfo {
112
+ source: string;
113
+ baseDir?: string;
114
+ displayName?: string;
169
115
  }
170
-
116
+ /** A loaded directory Bundle used by an extension. */
117
+ type PhaseDefinition = Phase;
118
+ /** Register a Phase by directory path or Phase object; PHASE.md and direct child Skills are loaded atomically when a path is supplied. */
119
+ type PhaseRegistration = string | Phase;
120
+ type RegisteredPhase = {
121
+ definition: PhaseDefinition;
122
+ source: {
123
+ extensionPath: string;
124
+ };
125
+ sourceId: string;
126
+ scope?: ScopeRef;
127
+ };
128
+ /** Register a Skill directory (containing SKILL.md) or a Skill object. Registering an existing name replaces it. */
129
+ type SkillRegistration = string | Skill;
130
+ type RegisteredSkill = {
131
+ definition: Skill;
132
+ source: {
133
+ extensionPath: string;
134
+ };
135
+ sourceId: string;
136
+ scope?: ScopeRef;
137
+ };
171
138
  /**
172
- * EventBus — simple pub/sub for inter-extension communication.
173
- *
174
- * Extensions can emit and subscribe to arbitrary events via `api.events`.
175
- * This allows extensions to coordinate without direct coupling.
139
+ * Tool definition for registering LLM-callable tools via `api.tools.register()`.
176
140
  *
177
141
  * @example
178
142
  * ```typescript
179
- * // Extension A
180
- * api.events.on("my-plugin:ready", (data) => {
181
- * console.log("Plugin ready:", data);
143
+ * api.tools.register({
144
+ * name: "search_docs",
145
+ * description: "Search documentation",
146
+ * parameters: { type: "object", properties: { query: { type: "string" } } },
147
+ * execute: async (args, ctx) => {
148
+ * return { content: [{ type: "text", text: "result" }] };
149
+ * },
182
150
  * });
183
- *
184
- * // Extension B
185
- * api.events.emit("my-plugin:ready", { version: "1.0" });
186
151
  * ```
187
152
  */
188
- type Listener = (...args: unknown[]) => void;
189
- interface EventBus {
190
- /** Subscribe to an event. Returns unsubscribe function. */
191
- on(event: string, listener: Listener): () => void;
192
- /** Emit an event to all subscribers. */
193
- emit(event: string, ...args: unknown[]): void;
194
- /** Remove all listeners for an event, or all listeners if no event specified. */
195
- off(event?: string): void;
196
- /** Check if there are listeners for an event. */
197
- has(event: string): boolean;
198
- /** Get listener count for an event. */
199
- count(event: string): number;
153
+ interface ToolDefinition {
154
+ /** Tool name (used in LLM tool calls) */
155
+ name: string;
156
+ /** Description for LLM */
157
+ description: string;
158
+ /** Parameter schema (JSON Schema) */
159
+ parameters: Record<string, unknown>;
160
+ /** Optional: one-line snippet shown in the system prompt tool list */
161
+ promptSnippet?: string;
162
+ /** Optional: additional guidelines appended to system prompt */
163
+ promptGuidelines?: string[];
164
+ kind?: ToolKind;
165
+ annotations?: ToolAnnotations;
166
+ _meta?: JsonObject;
167
+ present?: (call: {
168
+ status: ToolCallStatus;
169
+ args: JsonValue;
170
+ progress?: ToolProgress;
171
+ result?: ToolExecutionResult;
172
+ }) => {
173
+ title?: string;
174
+ content?: ToolCallContent[];
175
+ locations?: ToolCallLocation[];
176
+ _meta?: JsonObject;
177
+ } | undefined | void | Promise<{
178
+ title?: string;
179
+ content?: ToolCallContent[];
180
+ locations?: ToolCallLocation[];
181
+ _meta?: JsonObject;
182
+ } | undefined | void>;
183
+ /** Execute the tool */
184
+ execute: (args: unknown, context: ToolInvocationContext, signal?: AbortSignal) => Promise<ToolExecutionResult>;
185
+ /** Optional: per-tool execution mode override */
186
+ executionMode?: "sequential" | "parallel";
200
187
  }
201
188
 
202
189
  /**
203
- * @module extensions/context
204
- *
205
- * Extension context types — runtime state and phase execution context.
206
- *
207
- * For ExtensionAPI and createExtensionAPI, see ./api.ts
190
+ * Registered tool with source metadata.
208
191
  */
209
-
210
- /**
192
+ interface RegisteredTool {
193
+ definition: ToolDefinition;
194
+ sourceInfo: SourceInfo;
195
+ sourceId: string;
196
+ scope?: ScopeRef;
197
+ }
198
+ /**
199
+ * Structured extension error with attribution.
200
+ */
201
+ interface ExtensionError {
202
+ /** Path of the extension that caused the error */
203
+ extensionPath: string;
204
+ /** Event or operation that caused the error */
205
+ event: string;
206
+ /** Error message */
207
+ error: string;
208
+ /** Optional stack trace */
209
+ stack?: string;
210
+ }
211
+ /** Error listener callback type. */
212
+ type ExtensionErrorListener = (error: ExtensionError) => void;
213
+ type ExecOptions = {
214
+ /** Working directory for the command. Defaults to cwd passed to runtime. */
215
+ cwd?: string;
216
+ /** Environment variables to add/override. */
217
+ env?: Record<string, string>;
218
+ /** Timeout in milliseconds. */
219
+ timeout?: number;
220
+ /** AbortSignal for cancellation. */
221
+ signal?: AbortSignal;
222
+ };
223
+ type ExecResult = {
224
+ exitCode: number;
225
+ stdout: string;
226
+ stderr: string;
227
+ };
228
+ /**
229
+ * Shared runtime state created by loader, used during registration and runtime.
230
+ * All ExtensionAPI instances reference this shared state.
231
+ *
232
+ * It only owns the lifetime guard shared by captured Extension API objects.
233
+ */
234
+ interface ExtensionRuntime {
235
+ /** Throws when this extension instance is stale after runtime replacement. */
236
+ assertActive: () => void;
237
+ /** Marks this extension instance as stale after runtime replacement or reload. */
238
+ invalidate: (message?: string) => void;
239
+ }
240
+ /**
241
+ * Result of loading extensions from filesystem.
242
+ * The runner takes these and creates Extension tracking objects.
243
+ */
244
+ type LoadExtensionsResult = {
245
+ extensions: LoadedExtension[];
246
+ errors: Array<{
247
+ path: string;
248
+ error: string;
249
+ }>;
250
+ };
251
+ /**
252
+ * Pre-initialization extension form — factory + metadata.
253
+ * Runner.loadExtensions() calls the factory and creates the full Extension object.
254
+ */
255
+ interface LoadedExtension {
256
+ id?: string;
257
+ path: string;
258
+ name: string;
259
+ factory: ExtensionFactory;
260
+ manifest?: ExtensionManifest;
261
+ }
262
+ /** Extension manifest from package.json `rowan` field. */
263
+ interface ExtensionManifest {
264
+ id?: string;
265
+ entry?: string;
266
+ name?: string;
267
+ }
268
+
269
+ /**
270
+ * EventBus — simple pub/sub for inter-extension communication.
271
+ *
272
+ * Extensions can emit and subscribe to arbitrary events via `api.events`.
273
+ * This allows extensions to coordinate without direct coupling.
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * // Extension A
278
+ * api.events.on("my-plugin:ready", (data) => {
279
+ * console.log("Plugin ready:", data);
280
+ * });
281
+ *
282
+ * // Extension B
283
+ * api.events.emit("my-plugin:ready", { version: "1.0" });
284
+ * ```
285
+ */
286
+ type Listener = (...args: unknown[]) => void;
287
+ interface EventBus {
288
+ /** Subscribe to an event. Returns unsubscribe function. */
289
+ on(event: string, listener: Listener): () => void;
290
+ /** Emit an event to all subscribers. */
291
+ emit(event: string, ...args: unknown[]): void;
292
+ /** Remove all listeners for an event, or all listeners if no event specified. */
293
+ off(event?: string): void;
294
+ /** Check if there are listeners for an event. */
295
+ has(event: string): boolean;
296
+ /** Get listener count for an event. */
297
+ count(event: string): number;
298
+ }
299
+
300
+ /**
301
+ * @module extensions/context
302
+ *
303
+ * Extension context types — runtime state and phase execution context.
304
+ *
305
+ * For ExtensionAPI and createExtensionAPI, see ./api.ts
306
+ */
307
+
308
+ /**
211
309
  * Runtime context available to extensions during event handler execution.
212
310
  *
213
311
  * Provides access to agent state, working directory, and utility methods.
@@ -290,1534 +388,1422 @@ interface ExtensionUtils {
290
388
  formatJson(value: unknown): string;
291
389
  }
292
390
 
293
- declare class InMemoryExtensionHost implements ExtensionHost {
294
- private readonly configs;
295
- private readonly agentState;
296
- private readonly globalState;
297
- private readonly listeners;
298
- extendApi?(extensionId: string): HostApiExtension | undefined;
299
- constructor(options?: {
300
- configs?: Record<string, Record<string, JsonObject>>;
301
- agentState?: Record<string, Record<string, Record<string, JsonValue>>>;
302
- globalState?: Record<string, Record<string, JsonValue>>;
303
- extendApi?: (extensionId: string) => HostApiExtension | undefined;
304
- });
305
- setConfig(extensionId: string, config: JsonObject | null, scope?: ScopeRef): void;
306
- getConfig(extensionId: string, scope?: ScopeRef): JsonObject | null;
307
- onConfigChanged(listener: (extensionId: string, scope: ScopeRef) => void): () => void;
308
- notifyConfigChanged(extensionId: string, scope?: ScopeRef): void;
309
- getAgentState(extensionId: string, agentId: string, key: string): JsonValue | undefined;
310
- setAgentState(extensionId: string, agentId: string, key: string, value: JsonValue): void;
311
- deleteAgentState(extensionId: string, agentId: string, key: string): void;
312
- getGlobalState(extensionId: string, key: string): JsonValue | undefined;
313
- setGlobalState(extensionId: string, key: string, value: JsonValue): void;
314
- deleteGlobalState(extensionId: string, key: string): void;
315
- }
316
-
317
- /**
318
- * Extension runner — manages extension loading and hook execution.
319
- *
320
- * Architecture reference: PI's ExtensionRunner
321
- * - Per-extension tracking via Extension objects
322
- * - Shared ExtensionRuntime with invalidate/assertActive
323
- * - Direct `on()` API for hook registration
324
- * - Error listener pattern for structured error handling
325
- * - Tool registration support
326
- */
327
-
328
- /** The Resource Source an Extension registration lands in: Global (`[]`) is `rowan.extensions`, any other Scope `rowan.extensions:<scopeToKey(scope)>`. */
329
- declare function extensionSourceId(scope?: ScopeRef): string;
330
- type ExtensionRunnerOptions = {
331
- entryPhaseId?: string | null;
332
- cwd?: string;
333
- host?: ExtensionHost;
334
- };
335
391
  /**
336
- * Manages extensions and provides hooks for the agent loop.
337
- *
338
- * Features:
339
- * - Per-extension tracking (handlers, tools, phases)
340
- * - Shared runtime with lifecycle protection (invalidate/assertActive)
341
- * - Error listener pattern for structured error handling
342
- * - Direct hook API and extension-loaded hook API
343
- * - Tool registration for LLM-callable tools
344
- * - EventBus for inter-extension communication
392
+ * Extension API object passed to extension factory function.
345
393
  *
346
394
  * @example
347
- * ```ts
348
- * const runner = createExtensionRunner();
349
- *
350
- * // Direct hook registration
351
- * const unsub = runner.on("before_tool_call", (event) => {
352
- * return { allow: false, reason: "Blocked" };
353
- * });
354
- *
355
- * // Error handling
356
- * runner.onError((error) => {
357
- * console.error(`Extension error in ${error.extensionPath}:`, error.error);
358
- * });
359
- *
360
- * // Load extensions
361
- * await runner.loadExtensions(extensions);
362
- * runner.bind();
395
+ * ```typescript
396
+ * export default function(api: ExtensionAPI) {
397
+ * // api provides all extension APIs
398
+ * }
363
399
  * ```
364
400
  */
365
- declare class ExtensionRunner {
366
- readonly hooks: HooksManager;
367
- readonly runtime: ExtensionRuntime;
368
- readonly events: EventBus;
369
- readonly host: ExtensionHost;
370
- private readonly cwd;
371
- private readonly abortController;
372
- private _idle;
373
- private readonly extensions;
374
- private readonly runState;
375
- private readonly configChangeListeners;
376
- private readonly hostUnsubscribers;
377
- private readonly phases;
378
- private _phaseCache;
379
- private readonly skills;
380
- private readonly pendingProviders;
381
- private bound;
382
- private readonly errorListeners;
383
- private readonly capabilityListeners;
384
- private readonly resourceChangeListeners;
385
- /** Current agent context — set by the agent before each phase */
386
- currentContext?: AgentContext;
387
- constructor(options?: ExtensionRunnerOptions);
388
- /** Whether the agent is currently idle (not streaming). */
389
- get isIdle(): boolean;
390
- /** Set idle state — called by the agent loop. */
391
- setIdle(idle: boolean): void;
392
- /** Abort signal for the current runner instance. */
393
- get signal(): AbortSignal;
394
- /** Abort the current runner operation. */
395
- abort(): void;
396
- /**
397
- * Register an error listener.
398
- * Returns an unsubscribe function.
399
- */
400
- onError(listener: ExtensionErrorListener): () => void;
401
- /**
402
- * Emit a structured extension error to all listeners.
403
- */
404
- emitError(error: ExtensionError): void;
405
- /**
406
- * Mark all extension contexts as stale.
407
- * After calling this, any captured ExtensionAPI or ExtensionContext will throw
408
- * on use. Used during runtime replacement or reload.
409
- */
410
- invalidate(message?: string): void;
411
- /**
412
- * Subscribe to a specific hook event type.
413
- * Returns an unsubscribe function.
414
- *
415
- * @example
416
- * ```ts
417
- * const unsub = runner.on("before_tool_call", (event) => {
418
- * return { allow: false, reason: "Blocked" };
419
- * });
420
- * unsub(); // Cancel subscription
421
- * ```
422
- */
423
- on<K extends HookEventType>(type: K, handler: HookHandler<K>): () => void;
424
- /**
425
- * Load and initialize extensions.
426
- * Creates Extension tracking objects and calls each factory with an ExtensionAPI.
427
- */
428
- loadExtensions(extensions: LoadedExtension[]): Promise<void>;
429
- /** Dispose all active Extensions in reverse activation order. */
430
- close(): Promise<void>;
431
- get extensionHost(): ExtensionHost;
432
- notifyConfigChanged(extensionId: string, scope: ScopeRef): Promise<void>;
433
- getRunState(runId: string, extensionId: string, key: string): JsonValue | undefined;
434
- setRunState(runId: string, extensionId: string, key: string, value: JsonValue): void;
435
- deleteRunState(runId: string, extensionId: string, key: string): void;
436
- dropRunState(runId: string): void;
437
- /** Get all registered tools from all extensions. */
438
- getAllRegisteredTools(): RegisteredTool[];
439
- /**
440
- * Get a tool definition by name. Returns undefined if not found.
441
- */
442
- getToolDefinition(toolName: string): RegisteredTool["definition"] | undefined;
443
- /** Get all contributed capabilities across all extensions. */
444
- getCapabilities(): readonly ExtensionCapability[];
445
- /**
446
- * Subscribe to capability changes (contributions added, removed, or extensions disposed).
447
- * Returns an unsubscribe function.
448
- */
449
- onCapabilitiesChanged(listener: (capabilities: readonly ExtensionCapability[]) => void): () => void;
450
- /**
451
- * Subscribe to resource changes (tools, phases, skills registered, unregistered, or disposed).
452
- * Used by RuntimeBootstrapRegistry to re-commit implicit sources after activation.
453
- */
454
- onResourceChange(listener: (kind: "tool" | "phase" | "skill") => Promise<void> | void): () => void;
455
- private notifyResourceChange;
456
- triggerUiAction(event: {
457
- contributionId: string;
458
- actionId: string;
459
- scope?: ScopeRef;
460
- }): void;
461
- getPhase(name: string): Phase | undefined;
462
- getPhases(): Phase[];
463
- getRegisteredPhases(): readonly RegisteredPhase[];
464
- createPhaseRegistry(input?: {
465
- entryPhaseId?: string | null;
466
- }): PhaseRegistry;
467
- /** Adapt an extension RegisteredPhase to the core Phase type. */
468
- adaptToPhase(reg: RegisteredPhase): Phase;
469
- getSkills(): Skill[];
470
- getRegisteredSkills(): readonly RegisteredSkill[];
471
- /**
472
- * Bind the runner — flushes pending provider registrations and
473
- * replaces runtime stubs with real implementations.
474
- */
475
- bind(): void;
476
- /**
477
- * Generic emit — fire-and-forget for any event type.
478
- */
479
- emit<K extends HookEventType>(eventType: K, event: Parameters<HookHandler<K>>[0]): Promise<void>;
480
- /**
481
- * Unified hook emission — returns the first non-undefined result.
482
- */
483
- private emitHook;
484
- emitBeforePhase(phaseId: string, input: PhaseContext): Promise<{
485
- abort?: any;
486
- skip?: any;
487
- input?: PhaseContext;
488
- }>;
489
- emitAfterPhase(phaseId: string, output: PhaseOutput): Promise<{
490
- abort?: any;
491
- retry?: PhaseContext;
492
- output?: PhaseOutput;
493
- }>;
494
- emitBeforePrompt(phaseId: string, input: PhaseContext): Promise<PhaseContext>;
495
- emitRunStart(event: {
496
- runId: string;
497
- agentId: string;
498
- metadata: Readonly<Record<string, unknown>>;
499
- turn: JsonObject;
500
- }): Promise<void>;
501
- emitRunEnd(event: {
502
- runId: string;
503
- agentId: string;
504
- outcome: unknown;
505
- }): Promise<void>;
506
- emitBeforeToolCall(tool: Tool, args: unknown, context?: {
507
- runId?: string;
508
- agentId?: string;
509
- toolCallId?: string;
510
- metadata?: Readonly<Record<string, unknown>>;
511
- agentMetadata?: Readonly<Record<string, unknown>>;
512
- answer?: unknown;
513
- scope?: ScopeRef;
514
- turn?: JsonObject;
515
- }): Promise<BeforeToolCallResult>;
516
- emitAfterToolCall(tool: Tool, result: ToolResult, context?: {
517
- runId?: string;
518
- agentId?: string;
519
- toolCallId?: string;
520
- metadata?: Readonly<Record<string, unknown>>;
521
- scope?: ScopeRef;
522
- turn?: JsonObject;
523
- }): Promise<ToolResult>;
524
- /**
525
- * Create an ExtensionAPI for a specific extension.
526
- * Registration methods write to the extension tracking object.
527
- * Action methods delegate to the shared runtime.
528
- */
529
- private createExtensionAPI;
530
- private registerTool;
531
- private unregisterTool;
532
- private contributeCapability;
533
- private notifyCapabilitiesChanged;
534
- private registerPhase;
535
- private registerPhaseDefinition;
536
- private unregisterPhase;
537
- private loadRegisteredPhase;
538
- private registerSkill;
539
- private registerSkillDefinition;
540
- private unregisterSkill;
541
- private loadRegisteredSkill;
542
- private registerProvider;
543
- private unregisterProvider;
544
- private flushPendingProviders;
545
- private getRegisteredPhase;
546
- private collectRegisteredPhases;
547
- private rollbackExtension;
548
- private disposeExtension;
401
+ interface ExtensionAPI {
402
+ /** Hook events — subscribe or unsubscribe. */
403
+ hooks: {
404
+ /**
405
+ * Subscribe to a hook event.
406
+ *
407
+ * @param eventType - Hook type, e.g. "before_tool_call"
408
+ * @param handler - Hook handler, can return result to modify behavior
409
+ */
410
+ on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
411
+ /** Unsubscribe from a hook event. */
412
+ off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
413
+ };
414
+ /** Extension configuration — read own layered config or listen for changes. */
415
+ config: {
416
+ /** Get the extension's own effective configuration block. */
417
+ get(scope?: ScopeRef): Promise<JsonObject | null>;
418
+ /** Listen for configuration changes for a scope. */
419
+ changed(handler: (scope: ScopeRef) => void): void;
420
+ };
421
+ /** Extension state — scoped to run (in-memory) or agent (durable) or global (durable). */
422
+ state: {
423
+ /** Run-scoped in-memory state; dropped when the Run ends. */
424
+ run(runId: string): ExtensionStateStore;
425
+ /** Agent-scoped durable state; persisted with the Agent record. */
426
+ agent(agentId: string): ExtensionStateStore;
427
+ /** Extension-scoped durable state; survives process restarts. */
428
+ global(): ExtensionStateStore;
429
+ };
430
+ /** Tool capabilities — register and unregister custom tools. */
431
+ tools: {
432
+ /** Register a custom LLM-callable tool. */
433
+ register(tool: ToolDefinition, scope?: ScopeRef): Promise<void>;
434
+ /** Unregister a previously registered tool by name. */
435
+ unregister(toolName: string, scope?: ScopeRef): Promise<void>;
436
+ };
437
+ /** Capability contributions — advertise tools or features to the host. */
438
+ capabilities: {
439
+ /** Contribute a capability to the host. Returns a disposer to remove the contribution. */
440
+ contribute(contribution: ExtensionCapabilityContribution): () => void;
441
+ };
442
+ /** Model provider registration. */
443
+ providers: {
444
+ /** Register a model provider. Registering with an existing id replaces it. */
445
+ register(config: _rowan_agent_models.ProviderConfig): void;
446
+ /** Unregister a model provider by id. */
447
+ unregister(id: string): void;
448
+ };
449
+ /** Phase execution capabilities — provides Phase In/Out, phase identity, phase routing, and registration. */
450
+ phases: {
451
+ /** Register a Phase directory bundle or Phase object. */
452
+ register(phase: PhaseRegistration, scope?: ScopeRef): Promise<void>;
453
+ /** Unregister a previously registered phase by name. */
454
+ unregister(phaseName: string, scope?: ScopeRef): Promise<void> | void;
455
+ /** Phase In: get payload from previous phase */
456
+ getPayload(): unknown;
457
+ /** Phase Out: set payload for next phase */
458
+ setPayload(payload: unknown): void;
459
+ /** Phase Out: set outcome message */
460
+ setMessage(message: string): void;
461
+ /** Get current phase name */
462
+ getCurrentPhase(): string;
463
+ /** Set next phase (lower priority than PHASE.md target) */
464
+ setNextPhase(phaseName: string): void;
465
+ /** Get the next phase set by setNextPhase */
466
+ getNextPhase(): string | undefined;
467
+ /** Get the message set by setMessage */
468
+ getMessage(): string | undefined;
469
+ };
470
+ /** Skill capabilities — register and unregister standalone skills. */
471
+ skills: {
472
+ /** Register a Skill directory (containing SKILL.md) or a Skill object. Registering an existing name replaces it. */
473
+ register(skill: SkillRegistration, scope?: ScopeRef): Promise<void>;
474
+ /** Unregister a previously registered Skill by name. */
475
+ unregister(skillName: string, scope?: ScopeRef): Promise<void> | void;
476
+ };
477
+ /** Extension manifest from package.json `rowan` field. */
478
+ manifest?: ExtensionManifest;
479
+ /** Utility functions. */
480
+ utils: ExtensionUtils;
481
+ /** Runtime context — cwd, signal, exec, message access, etc. */
482
+ context: ExtensionContext;
483
+ /** Shared event bus for inter-extension communication. */
484
+ events: EventBus;
549
485
  }
486
+ /**
487
+ * Extension factory function.
488
+ * Receives ExtensionAPI for registering hooks, phases, and providers.
489
+ */
490
+ type ExtensionDisposer = () => void | Promise<void>;
491
+ type ExtensionFactoryResult = void | ExtensionDisposer;
492
+ type ExtensionFactory = (api: ExtensionAPI) => ExtensionFactoryResult | Promise<ExtensionFactoryResult>;
550
493
 
551
- type ToolCallPresentationInput = Readonly<{
552
- status: ToolCallStatus;
553
- args: JsonValue$1;
554
- progress?: ToolProgress;
555
- result?: ToolExecutionResult;
494
+ type PhaseStatusState = "running" | "completed";
495
+ /** Normalized status event exposed to Runtime consumers. */
496
+ type PhaseStatus = Readonly<{
497
+ state: PhaseStatusState;
498
+ /** Stable consumer-facing status identifier, e.g. `compacting`. */
499
+ kind: string;
500
+ /** Optional human-readable detail for UI/status consumers. */
501
+ message?: string;
502
+ /** Structured status payload. */
503
+ payload?: unknown;
556
504
  }>;
557
- type ToolCallPresentationOutput = {
558
- title?: string;
559
- content?: ToolCallContent[];
560
- locations?: ToolCallLocation[];
561
- _meta?: JsonObject$1;
562
- };
563
- type ToolCallMergeTarget = {
564
- title?: string;
565
- kind?: ToolKind;
566
- status?: ToolCallStatus;
567
- locations?: ToolCallLocation[];
568
- content?: ToolCallContent[];
569
- rawInput?: JsonValue$1;
570
- rawOutput?: JsonValue$1;
571
- _meta?: JsonObject$1;
505
+ /** Unified phase output — model-driven routing is optional; programmatic phases may normalize omission to stop. */
506
+ type PhaseOutput = {
507
+ /** User-visible assistant message. */
508
+ message?: string;
509
+ /** Final status update for non-conversational consumers. */
510
+ status?: PhaseStatus;
511
+ /** Route to next phase, or "continue" to re-execute current phase, or "stop" to end. Undefined means no model route. */
512
+ route?: string;
513
+ /** Phase name that produced this output */
514
+ phase?: string;
515
+ /** Tool calls from the model invocation (used by framework for route extraction) */
516
+ toolCalls?: Array<{
517
+ id: string;
518
+ name: string;
519
+ args: unknown;
520
+ }>;
521
+ /** Route reason extracted from route tool call (for hooks to inspect) */
522
+ routeReason?: string;
523
+ /** Structured data from this phase, passed to the next phase */
524
+ payload?: unknown;
572
525
  };
573
- type ToolCallMergePatch = {
574
- title?: string;
575
- kind?: ToolKind;
576
- status?: ToolCallStatus;
577
- locations?: ToolCallLocation[];
578
- content?: ToolCallContent[];
579
- rawInput?: JsonValue$1;
580
- rawOutput?: JsonValue$1;
581
- _meta?: JsonObject$1;
582
- };
583
- declare function mergeToolCall<T extends ToolCallMergeTarget>(target: T, patch: ToolCallMergePatch): T;
584
-
585
- type ExtensionContribution = LoadedExtension;
586
- type ExtensionLoadInput = LoadInput<ExtensionContribution>;
587
- type ExtensionActivationError = Readonly<{
588
- path: string;
589
- error: string;
590
- }>;
591
- type ExtensionActivationResult = Readonly<{
592
- active: readonly string[];
593
- errors: readonly ExtensionActivationError[];
594
- revision?: string;
595
- registered?: readonly string[];
596
- skipped?: readonly ResourceDiagnostic[];
597
- }>;
598
- type ExtensionLifetimeErrorCode = "extensions_frozen" | "extensions_closed";
599
- declare class ExtensionLifetimeError extends Error {
600
- readonly code: ExtensionLifetimeErrorCode;
601
- constructor(code: ExtensionLifetimeErrorCode, message: string);
602
- }
603
- /** Runtime-global Extension activation and lifetime boundary. */
604
- declare class RuntimeExtensionLifetime {
605
- private readonly runner;
606
- private frozen;
607
- private closed;
608
- constructor(options?: {
609
- cwd?: string;
610
- host?: ExtensionHost;
611
- });
612
- activate(extensions: readonly LoadedExtension[]): Promise<ExtensionActivationResult>;
613
- tools(): readonly RegisteredTool[];
614
- phases(): readonly Phase[];
615
- registeredPhases(): readonly RegisteredPhase[];
616
- skills(): readonly Skill[];
617
- registeredSkills(): readonly RegisteredSkill[];
618
- get extensionRunner(): ExtensionRunner;
619
- get extensionHost(): ExtensionHost;
620
- onResourceChange(listener: (kind: "tool" | "phase" | "skill") => Promise<void> | void): () => void;
621
- dropRunState(runId: string): void;
622
- close(): Promise<void>;
623
- }
624
- /** Bootstrap-only Registry facade; its Extension method disappears after init. */
625
- declare class RuntimeBootstrapRegistry extends ResourceRegistry {
626
- private readonly extensions;
627
- private readonly knownSources;
628
- private commitQueue;
629
- constructor(extensions?: RuntimeExtensionLifetime);
630
- private recommit;
631
- get extensionHost(): ExtensionHost;
632
- /** Install Rowan-owned implicit resources before any host source is read. */
633
- ensureCoreResources(): Promise<void>;
634
- loadExtensions(input: readonly LoadedExtension[] | ExtensionLoadInput): Promise<ExtensionActivationResult>;
635
- get extensionRunner(): ExtensionRunner;
636
- get extensionTools(): readonly RegisteredTool[];
637
- get extensionPhases(): readonly Phase[];
638
- closeExtensions(): Promise<void>;
526
+ /** Phase machine state — tracks position and inter-phase data */
527
+ interface PhaseState {
528
+ current: string;
529
+ available: string[];
530
+ iterations: number;
531
+ payload?: unknown;
639
532
  }
640
-
641
- type DefinitionLayer = Readonly<{
642
- description?: string;
643
- prompt?: string;
644
- model?: ModelRef;
645
- tools?: readonly string[];
646
- skills?: readonly string[];
647
- phases?: PhaseRegistrySelection;
648
- }>;
649
- type AgentConfiguration = Readonly<{
650
- identity: string;
651
- definition: Readonly<{
652
- name: string;
653
- layer?: DefinitionLayer;
654
- }>;
655
- resourceView: ResourceView;
656
- contexts?: readonly ContextCandidate[];
657
- /** Trusted Host-owned Contexts rendered as durable user messages. */
658
- additionalContexts?: readonly ContextCandidate[];
659
- cwd?: string;
660
- maxAttempts?: number;
661
- model: ModelConfig | ModelRef;
662
- stream?: StreamFn;
663
- }>;
664
- type ConfigurationSnapshot = Readonly<{
665
- identity: string;
666
- definition: AgentDefinition;
667
- resources: Readonly<{
668
- tools: readonly Tool$1[];
669
- skills: readonly Skill[];
670
- phases?: PhaseRegistry;
671
- revisions: Readonly<Record<ResourceKind, readonly string[]>>;
672
- refs: Readonly<Record<ResourceKind, readonly ResourceRef[]>>;
673
- }>;
674
- contexts: readonly ContextCandidate[];
675
- additionalContexts: readonly ContextCandidate[];
676
- resourceView: ResourceView;
533
+ type PhaseInvocation = {
534
+ mode: "serial";
535
+ instanceId: string;
536
+ } | {
537
+ mode: "parallel";
538
+ instanceId: string;
539
+ groupId: string;
540
+ index: number;
541
+ count: number;
542
+ sourcePhaseId: string;
543
+ };
544
+ /** Durable identity of the Run execution currently invoking a Phase. */
545
+ type PhaseExecutionIdentity = Readonly<{
546
+ agentId: string;
547
+ runId: string;
548
+ executionId: string;
549
+ /** Original durable Run input, before any Phase-local interpretation. */
550
+ input?: UserContent;
551
+ /** Opaque metadata captured at the durable boundary; Rowan does not decode it. */
552
+ agentMetadata?: Readonly<Record<string, unknown>>;
553
+ runMetadata?: Readonly<Record<string, unknown>>;
554
+ scope?: _rowan_agent_models.ScopeRef;
677
555
  cwd?: string;
678
- maxAttempts?: number;
679
- model: ModelConfig | ModelRef;
680
- stream?: StreamFn;
681
- }>;
682
- /** Resolve one Definition request into one immutable, source-qualified snapshot. */
683
- declare function resolveConfigurationSnapshot(registry: ResourceRegistry, input: AgentConfiguration): ConfigurationSnapshot;
684
- /** Whether one stored configuration is already a resolved snapshot. A snapshot
685
- * is used as it stands; a request is resolved against the current sources. */
686
- declare function isConfigurationSnapshot(config: AgentConfiguration | ConfigurationSnapshot): config is ConfigurationSnapshot;
687
-
688
- type UserInput = string | Readonly<{
689
- content: UserContent;
690
- metadata?: Metadata;
691
- thinkingLevel?: ThinkingLevel;
692
- providerOptions?: JsonObject;
693
- }>;
694
- type HistorySeed = readonly Message[];
695
- type ContextStatus = Readonly<{
696
- tokens: number;
697
- contextWindow: number;
698
- percent: number;
699
- thresholdTokens: number;
700
- estimated: boolean;
701
- coveredThrough?: Readonly<{
702
- messageId: MessageId;
703
- sequence: number;
704
- }>;
705
- }>;
706
- type ContextCompactionRecord = Readonly<{
707
- id: string;
708
- agentId: AgentId;
709
- summary: string;
710
- coveredThrough?: Readonly<{
711
- messageId: MessageId;
712
- sequence: number;
713
- }>;
714
- instructions?: string;
715
- createdAt: string;
716
- }>;
717
- /** Who is calling which tool, without the ability to ask or suspend. Hosts that
718
- * describe a call before it runs (for example to build a confirmation) only
719
- * have this much. */
720
- type ToolCallContext = Readonly<{
721
- agentId: AgentId;
722
- runId: RunId;
723
- /** Opaque JSON metadata captured from the Agent and Run records. Rowan does
724
- * not interpret host/domain fields. */
725
- agentMetadata?: Metadata;
726
- runMetadata?: Metadata;
727
- toolCallId: ToolCallId;
728
- /** The model's id for this call, matching `tool_call_delta` events; absent when a host runs the tool itself. */
729
- providerToolCallId?: string;
730
- scope?: ScopeRef;
731
- turn?: JsonObject;
732
- reportProgress(progress: ToolProgress): void;
733
- }>;
734
- type ToolInvocationContext = ToolCallContext & Readonly<{
735
- interaction: RunInteractionDriver;
736
- }>;
737
-
738
- type Tool$1 = Readonly<{
739
- name: string;
740
- /** Rowan-owned Core Tool; Core Tools bypass Definition/Phase filtering. */
741
- core?: boolean;
742
- description: string;
743
- parameters: Type.TSchema;
744
- promptSnippet?: string;
745
- promptGuidelines?: readonly string[];
746
- kind?: ToolKind;
747
- annotations?: ToolAnnotations;
748
- _meta?: JsonObject;
749
- present?(call: ToolCallPresentationInput): {
750
- title?: string;
751
- content?: ToolCallContent[];
752
- locations?: ToolCallLocation[];
753
- _meta?: JsonObject;
754
- } | undefined | void | Promise<{
755
- title?: string;
756
- content?: ToolCallContent[];
757
- locations?: ToolCallLocation[];
758
- _meta?: JsonObject;
759
- } | undefined | void>;
760
- execute(args: JsonValue, context: ToolInvocationContext, signal: AbortSignal): Promise<ToolExecutionResult>;
761
- }>;
762
- type BeforeToolCallDecision = Readonly<{
763
- allow: true;
764
- }> | Readonly<{
765
- allow: false;
766
- reason: string;
767
- }> | Readonly<{
768
- interaction: RunInteractionRequest;
769
- }>;
770
- type BeforeToolCall = (input: Readonly<{
771
- tool: Tool$1;
772
- args: JsonValue;
773
- context: ToolInvocationContext;
774
- signal: AbortSignal;
775
- answer?: JsonValue;
776
- }>) => BeforeToolCallDecision | Promise<BeforeToolCallDecision>;
777
- type AfterToolCall = (input: Readonly<{
778
- tool: Tool$1;
779
- result: ToolExecutionResult;
780
- context: ToolInvocationContext;
781
- signal: AbortSignal;
782
- }>) => ToolExecutionResult | Promise<ToolExecutionResult>;
783
- type InvocationSource = "auto" | "implicit" | "external";
784
- type InvocationCatalogEntry = Readonly<{
785
- kind: "phase" | "skill";
786
- name: string;
787
- description: string;
788
- input?: Phase["input"];
789
- core?: boolean;
790
- disableAutoInvocation: boolean;
791
- disableImplicitInvocation: boolean;
792
- filePath: string;
793
- }>;
794
- type AgentRecord = Readonly<{
795
- id: AgentId;
796
- metadata?: Metadata;
797
- currentConfigToken?: ConfigToken;
798
- currentConfigIdentity?: string;
799
- createdAt: string;
800
- activatedAt?: string;
801
- updatedAt: string;
802
- }>;
803
- type AgentDeletionRequest = Readonly<{
804
- agentId: AgentId;
805
- expectedRunIds: readonly RunId[];
806
- confirmation: "agent-delete-v1";
807
556
  }>;
808
- type ExecutionToken = Readonly<{
809
- runId: RunId;
810
- ownerEpoch: number;
811
- executionId: ExecutionId;
812
- }>;
813
- type ExecutionCheckpoint = Readonly<{
814
- codec: string;
815
- version: number;
816
- data: JsonValue;
817
- }>;
818
- type OwnerLease = Readonly<{
819
- ownerId: string;
820
- token: OwnerToken;
821
- epoch: number;
822
- expiresAt: string;
823
- }>;
824
- type RunClaim = Readonly<{
825
- run: RunRecord;
826
- execution: ExecutionToken;
827
- history: readonly Message[];
828
- }>;
829
- type ToolCallReservation = Readonly<{
830
- providerToolCallId: string;
831
- name: string;
832
- args: JsonValue;
833
- toolCallId?: ToolCallId;
834
- title?: string;
835
- kind?: ToolKind;
836
- locations?: ToolCallLocation[];
837
- content?: ToolCallContent[];
838
- _meta?: JsonObject;
839
- }>;
840
- type ToolCommit = Readonly<{
841
- run: RunRecord;
842
- toolCall: ToolCallSnapshot;
843
- }>;
844
- type ToolBatchCommit = Readonly<{
845
- run: RunRecord;
846
- toolCalls: readonly ToolCallSnapshot[];
847
- }>;
848
- type EntryPhaseSpec = Readonly<{
849
- phase: string;
850
- payload?: JsonValue;
851
- }>;
852
- type RunRecord = Readonly<{
853
- id: RunId;
854
- agentId: AgentId;
855
- agentSequence: number;
856
- readySequence: number;
857
- revision: number;
858
- state: RunState;
859
- input: UserInput;
860
- scope?: ScopeRef;
861
- cwd?: string;
862
- initialMessageId?: MessageId;
863
- invalidatedBy?: Readonly<{
864
- messageId: MessageId;
865
- messageRevision: number;
866
- }>;
867
- metadata?: Metadata;
868
- phasePayload?: JsonValue;
869
- entryPhases?: readonly EntryPhaseSpec[];
870
- pinnedConfigToken?: ConfigToken;
871
- checkpoint?: ExecutionCheckpoint;
872
- currentPhaseId?: string;
873
- openInteractions?: readonly RunInteraction[];
874
- interactionAnswers?: Readonly<Record<string, JsonValue>>;
875
- execution?: ExecutionToken;
876
- outcome?: Outcome$1;
877
- failure?: RunFailure;
878
- cancellationReason?: string;
879
- createdAt: string;
880
- updatedAt: string;
881
- }>;
882
- type MessageRevisionResult = Readonly<{
883
- message: UserMessage & Readonly<{
884
- messageRevision: number;
885
- }>;
886
- replacementRun: RunRecord;
887
- invalidatedRunIds: readonly RunId[];
888
- affectedToolCallIds: readonly ToolCallId[];
889
- effectDigest?: string;
890
- }>;
891
- type RetentionResult = Readonly<{
892
- deletedRunIds: readonly RunId[];
893
- deletedToolCallIds: readonly ToolCallId[];
894
- deletedEventCount: number;
895
- retentionFloor: EventCursor;
896
- skipped?: "active_consumers" | "no_eligible_events";
897
- }>;
898
- type AgentSummary = Readonly<{
899
- id: AgentId;
900
- metadata?: Metadata;
901
- currentConfigIdentity?: string;
902
- createdAt: string;
903
- activatedAt: string;
904
- updatedAt: string;
905
- }>;
906
- type RunSummary = Readonly<{
907
- id: RunId;
908
- agentId: AgentId;
909
- agentSequence: number;
910
- state: RunState;
911
- metadata?: Metadata;
912
- createdAt: string;
913
- updatedAt: string;
914
- }>;
915
- type Page<T, Cursor> = Readonly<{
916
- items: readonly T[];
917
- next?: Cursor;
918
- }>;
919
- type RunSnapshotBase = Readonly<{
920
- runId: RunId;
921
- agentId: AgentId;
922
- agentSequence: number;
923
- revision: number;
924
- input: UserInput;
925
- scope?: ScopeRef;
926
- cwd?: string;
927
- metadata?: Metadata;
928
- /** Effective entry Phase payload the Run started with (defaults filled). */
929
- phasePayload?: JsonValue;
930
- entryPhases?: readonly EntryPhaseSpec[];
931
- messageCount: number;
932
- toolCallCount: number;
933
- currentPhaseId?: string;
934
- createdAt: string;
935
- updatedAt: string;
936
- cursor: EventCursor;
937
- }>;
938
- type RunSnapshot = RunSnapshotBase & (Readonly<{
939
- state: "queued" | "running";
940
- currentPhaseId?: string;
941
- interactions?: readonly RunInteraction[];
942
- }> | Readonly<{
943
- state: "input_required";
944
- interactions: readonly RunInteraction[];
945
- answers: Readonly<Record<string, JsonValue>>;
946
- }> | Readonly<{
947
- state: "completed";
948
- outcome: Outcome$1;
949
- output?: AssistantMessage;
950
- }> | Readonly<{
951
- state: "failed";
952
- failure: RunFailure;
953
- }> | Readonly<{
954
- state: "cancelled";
955
- reason?: string;
956
- }>);
957
- type RunBoundary = Readonly<{
958
- type: "input_required";
959
- interactions: readonly RunInteraction[];
960
- answers: Readonly<Record<string, JsonValue>>;
961
- }> | Readonly<{
962
- type: "completed";
963
- outcome: Outcome$1;
964
- output?: AssistantMessage;
965
- }> | Readonly<{
966
- type: "failed";
967
- failure: RunFailure;
968
- }> | Readonly<{
969
- type: "cancelled";
970
- reason?: string;
971
- }>;
972
- type ConfigResolution = Readonly<{
973
- kind: "available";
974
- config: AgentConfiguration | ConfigurationSnapshot;
975
- } | {
976
- kind: "deferred";
977
- retryAfterMs?: number;
978
- } | {
979
- kind: "unavailable";
980
- reason: string;
981
- }>;
982
- type ConfigPutResult = Readonly<{
983
- kind: "stored";
984
- token: string;
985
- } | {
986
- kind: "identity_conflict";
987
- }>;
988
- interface ConfigProvider {
989
- put(input: {
990
- agentId: AgentId;
991
- agentMetadata?: Metadata;
992
- config: AgentConfiguration | ConfigurationSnapshot;
993
- operationId: string;
994
- signal: AbortSignal;
995
- }): Promise<ConfigPutResult>;
996
- resolve(input: {
997
- agentId: AgentId;
998
- agentMetadata?: Metadata;
999
- token: ConfigToken;
1000
- signal: AbortSignal;
1001
- }): Promise<ConfigResolution>;
1002
- }
1003
- interface OwnedStore {
1004
- readonly lease: OwnerLease;
1005
- reserveAgent(input: {
1006
- idempotencyKey: string;
1007
- metadata?: Metadata;
1008
- configIdentity?: string;
1009
- historySeed?: HistorySeed;
1010
- }): Promise<AgentRecord>;
1011
- activateAgent(agentId: AgentId, configToken?: ConfigToken, configIdentity?: string): Promise<AgentRecord>;
1012
- updateAgentConfigToken(input: {
1013
- agentId: AgentId;
1014
- token: ConfigToken;
1015
- configIdentity?: string;
1016
- idempotencyKey: string;
1017
- }): Promise<AgentRecord>;
1018
- deleteAgent(input: AgentDeletionRequest): Promise<void>;
1019
- reviseMessage(input: {
1020
- agentId: AgentId;
1021
- messageId: MessageId;
1022
- expectedMessageRevision: number;
1023
- content: UserContent;
1024
- operationId: string;
1025
- effectDigestConfirmation?: string;
1026
- }): Promise<MessageRevisionResult>;
1027
- compact(input?: {
1028
- now?: string;
1029
- retentionMs?: number;
1030
- }): Promise<RetentionResult>;
1031
- contextStatus(agentId: AgentId, contextWindow: number): Promise<ContextStatus>;
1032
- contextMessages(agentId: AgentId, recentTokenBudget?: number): Promise<readonly Message[]>;
1033
- commitContextCompaction(record: ContextCompactionRecord): Promise<ContextCompactionRecord>;
1034
- createRun(input: {
1035
- agentId: AgentId;
1036
- input: UserInput;
1037
- metadata?: Metadata;
1038
- scope?: ScopeRef;
1039
- cwd?: string;
1040
- phasePayload?: JsonValue;
1041
- entryPhases?: readonly EntryPhaseSpec[];
1042
- pinnedConfigToken?: ConfigToken;
1043
- idempotencyKey: string;
1044
- }): Promise<RunRecord>;
1045
- claimRun(input: {
1046
- runId: RunId;
1047
- expectedRevision: number;
1048
- executionId?: ExecutionId;
1049
- messageId?: MessageId;
1050
- configToken?: ConfigToken;
1051
- additionalContexts?: readonly ContextCandidate[];
1052
- }): Promise<RunClaim>;
1053
- failQueuedRun(input: {
1054
- runId: RunId;
1055
- expectedRevision: number;
1056
- failure: QueuedRunFailure;
1057
- }): Promise<RunRecord>;
1058
- commitPhaseEntered(input: {
1059
- runId: RunId;
1060
- execution: ExecutionToken;
1061
- expectedRevision: number;
1062
- phaseId: string;
1063
- visit: number;
1064
- }): Promise<RunRecord>;
1065
- commitPhaseOutput(input: {
1066
- runId: RunId;
1067
- execution: ExecutionToken;
1068
- expectedRevision: number;
1069
- message: AssistantMessage;
1070
- }): Promise<RunRecord>;
1071
- commitInputRequired(input: {
1072
- runId: RunId;
1073
- execution: ExecutionToken;
1074
- expectedRevision: number;
1075
- phase: string;
1076
- prompt?: AssistantMessage;
1077
- checkpoint: ExecutionCheckpoint;
1078
- interactions?: readonly RunInteraction[];
1079
- interactionAnswers?: Readonly<Record<string, JsonValue>>;
1080
- pendingToolCallIds?: readonly ToolCallId[];
1081
- }): Promise<RunRecord>;
1082
- answerInteraction(input: {
1083
- runId: RunId;
1084
- interactionId: string;
1085
- expectedRevision: number;
1086
- input?: JsonValue;
1087
- cancel?: boolean;
1088
- }): Promise<RunRecord>;
1089
- commitOutcome(input: {
1090
- runId: RunId;
1091
- execution: ExecutionToken;
1092
- expectedRevision: number;
1093
- outcome?: Outcome$1;
1094
- failure?: RunFailure;
1095
- output?: AssistantMessage;
1096
- }): Promise<RunRecord>;
1097
- reserveToolCall(input: {
1098
- runId: RunId;
1099
- execution: ExecutionToken;
1100
- expectedRevision: number;
1101
- requestMessageId: MessageId;
1102
- name: string;
1103
- args: JsonValue;
1104
- toolCallId?: ToolCallId;
1105
- providerToolCallId?: string;
1106
- title?: string;
1107
- kind?: ToolKind;
1108
- locations?: ToolCallLocation[];
1109
- content?: ToolCallContent[];
1110
- _meta?: JsonObject;
1111
- model?: ModelRef;
1112
- usage?: LlmTokenUsage;
1113
- }): Promise<ToolCommit>;
1114
- reserveToolCalls(input: {
1115
- runId: RunId;
1116
- execution: ExecutionToken;
1117
- expectedRevision: number;
1118
- requestMessageId: MessageId;
1119
- calls: readonly ToolCallReservation[];
1120
- /** The model response's blocks, so the request message keeps what preceded the Tool Calls. */
1121
- contentBlocks?: readonly ContentBlock[];
1122
- model?: ModelRef;
1123
- usage?: LlmTokenUsage;
1124
- }): Promise<ToolBatchCommit>;
1125
- startToolCall(input: {
1126
- runId: RunId;
1127
- execution: ExecutionToken;
1128
- expectedRevision: number;
1129
- toolCallId: ToolCallId;
1130
- title?: string;
1131
- kind?: ToolKind;
1132
- locations?: ToolCallLocation[];
1133
- content?: ToolCallContent[];
1134
- _meta?: JsonObject;
1135
- }): Promise<ToolCommit>;
1136
- suspendToolCall(input: {
1137
- runId: RunId;
1138
- execution: ExecutionToken;
1139
- expectedRevision: number;
1140
- toolCallId: ToolCallId;
1141
- }): Promise<ToolCommit>;
1142
- commitToolResult(input: {
1143
- runId: RunId;
1144
- execution: ExecutionToken;
1145
- expectedRevision: number;
1146
- toolCallId: ToolCallId;
1147
- result: ToolExecutionResult;
1148
- state: "completed" | "failed" | "indeterminate";
1149
- reason?: string;
1150
- title?: string;
1151
- kind?: ToolKind;
1152
- content?: ToolCallContent[];
1153
- locations?: ToolCallLocation[];
1154
- rawOutput?: JsonValue;
1155
- _meta?: JsonObject;
1156
- }): Promise<ToolCommit>;
1157
- cancelRun(input: {
1158
- runId: RunId;
1159
- expectedRevision?: number;
1160
- reason?: string;
1161
- output?: AssistantMessage;
1162
- }): Promise<RunRecord>;
1163
- recordToolCall(input: {
1164
- runId: RunId;
1165
- execution?: ExecutionToken;
1166
- update: ToolCall$1 | ToolCallUpdate;
1167
- external?: boolean;
1168
- contentIndex?: number;
1169
- }): Promise<DurableRunEvent>;
1170
- snapshotRun(runId: RunId): Promise<RunSnapshot>;
1171
- history(agentId: AgentId): Promise<readonly Message[]>;
1172
- listAgents(): Promise<readonly AgentRecord[]>;
1173
- listRuns(input?: {
1174
- agentId?: AgentId;
1175
- states?: readonly RunState[];
1176
- }): Promise<readonly RunRecord[]>;
1177
- listEvents(input?: {
1178
- after?: EventCursor;
1179
- }): Promise<readonly DurableRunEvent[]>;
1180
- openConsumer(consumerId: string): Promise<ConsumerRegistration>;
1181
- advanceConsumerCheckpoint(input: {
1182
- consumerId: string;
1183
- cursor: EventCursor;
1184
- }): Promise<void>;
1185
- renewOwner(leaseMs: number): Promise<OwnerLease>;
1186
- sealAndReleaseOwner(): Promise<void>;
557
+ /** Everything a phase needs to execute */
558
+ interface PhaseContext {
559
+ systemPrompt: string;
560
+ messages: AgentMessage[];
561
+ /** Phase-filtered tools */
562
+ tools: Tool[];
563
+ /** Phase-filtered skills */
564
+ skills: Skill[];
565
+ /** Phase machine state */
566
+ state: PhaseState;
567
+ /** Identity and dispatch metadata for this phase execution */
568
+ readonly invocation: PhaseInvocation;
569
+ /** Durable Run identity for cross-store integrations and idempotent commands. */
570
+ readonly execution: PhaseExecutionIdentity;
571
+ /** Additional guideline bullets appended to the system prompt */
572
+ promptGuidelines?: string[];
573
+ /** Text to append after the system prompt */
574
+ appendSystemPrompt?: string;
1187
575
  }
1188
- interface DurableStore {
1189
- openOwner(input: {
1190
- ownerId: string;
1191
- leaseMs: number;
1192
- }): Promise<OwnedStore>;
576
+ /** JSON-safe structural defaults declared by a Phase's `input` mapping. */
577
+ type PhaseInput = Readonly<Record<string, JsonValue>>;
578
+ /** JSON-safe option metadata exposed to a host Settings surface. */
579
+ interface SettingsOption {
580
+ value: string;
581
+ label: string;
582
+ description?: string;
583
+ disabled?: boolean;
1193
584
  }
1194
- type AgentRuntimeOptions = Readonly<{
1195
- store: DurableStore;
1196
- configs?: ConfigProvider;
1197
- concurrency?: number;
1198
- bootstrap?: (registry: RuntimeBootstrapRegistry) => void | Promise<void>;
1199
- host?: ExtensionHost;
1200
- sessionFiles?: Readonly<{
1201
- dir: string;
1202
- }>;
1203
- /** @internal Private / testing parameter to override retry delay */
1204
- retryDelayMs?: number;
585
+ interface SettingsBadge {
586
+ label: string;
587
+ tone?: "neutral" | "success" | "review" | "danger";
588
+ }
589
+ interface SettingsItem {
590
+ id: string;
591
+ title: string;
592
+ description?: string;
593
+ badges?: readonly SettingsBadge[];
594
+ }
595
+ type SettingsControl = {
596
+ type: "boolean";
597
+ path: string;
598
+ label: string;
599
+ description?: string;
600
+ } | {
601
+ type: "number";
602
+ path: string;
603
+ label: string;
604
+ description?: string;
605
+ min?: number;
606
+ max?: number;
607
+ step?: number;
608
+ unit?: string;
609
+ scale?: number;
610
+ } | {
611
+ type: "select";
612
+ path: string;
613
+ label: string;
614
+ description?: string;
615
+ options: readonly SettingsOption[];
616
+ } | {
617
+ type: "text";
618
+ path: string;
619
+ label: string;
620
+ description?: string;
621
+ placeholder?: string;
622
+ format?: "string" | "string-array" | "key-value";
623
+ multiline?: boolean;
624
+ } | {
625
+ type: "collection";
626
+ path: string;
627
+ label: string;
628
+ description?: string;
629
+ items: readonly SettingsItem[];
630
+ fields: readonly SettingsControl[];
631
+ add?: {
632
+ label: string;
633
+ idLabel?: string;
634
+ fields: readonly SettingsControl[];
635
+ };
636
+ removeLabel?: string;
637
+ };
638
+ interface SettingsSection {
639
+ id: string;
640
+ title: string;
641
+ description?: string;
642
+ controls: readonly SettingsControl[];
643
+ }
644
+ /** Declarative, host-neutral Settings surface. */
645
+ interface SettingsDefinition {
646
+ description?: string;
647
+ sections: readonly SettingsSection[];
648
+ }
649
+ /**
650
+ * Loaded Phase object
651
+ */
652
+ interface Phase {
653
+ /** Unique phase identity and display name. */
654
+ name: string;
655
+ /** Rowan-owned built-in Phase; built-ins are never filtered or disabled. */
656
+ core?: boolean;
657
+ /** Description */
658
+ description: string;
659
+ /** Restricted tools (undefined = all tools available) */
660
+ tools?: string[];
661
+ /** Skills bundled directly inside this phase directory. Inline phases may omit this (equivalent to []). */
662
+ skills?: Skill[];
663
+ /** Forced next phase */
664
+ target?: string;
665
+ /** Additional system-prompt guidance while this Phase is in the auto route catalog. */
666
+ promptGuidelines?: string[];
667
+ /** Structural JSON-safe input defaults */
668
+ input?: PhaseInput;
669
+ /** If true, phase gets a fresh context when executed in parallel */
670
+ isolated?: boolean;
671
+ /** Path to PHASE.md file */
672
+ filePath: string;
673
+ /** Phase directory path */
674
+ baseDir: string;
675
+ /** PHASE.md body content */
676
+ content: string;
677
+ /** Model override for this phase (resolved from frontmatter) */
678
+ model?: ModelRef;
679
+ /** Do not automatically inject this Phase into the model route catalog/context. */
680
+ disableAutoInvocation?: boolean;
681
+ /** Do not expose this Phase to direct user invocation. */
682
+ disableImplicitInvocation?: boolean;
683
+ metadata?: Readonly<Record<string, JsonValue>>;
684
+ /** ExtensionAPI factory function used for registration or programmatic execution. */
685
+ factory?: (api: ExtensionAPI) => Promise<void>;
686
+ /** Direct run function */
687
+ run?: (context: PhaseContext, execution: PhaseExecution) => Promise<PhaseOutput | void>;
688
+ }
689
+ /**
690
+ * Phase registry containing all loaded phases
691
+ */
692
+ interface PhaseRegistry {
693
+ /** Map of phase name to Phase object */
694
+ phases: Map<string, Phase>;
695
+ /** Entry phase name (null until Agent applies its default phase) */
696
+ entryPhaseId: string | null;
697
+ }
698
+
699
+ type ResourceKind = "agent" | "tool" | "skill" | "phase";
700
+ type ResourceSourceId = string;
701
+ /** Rowan-native contribution aliases. Hosts may adapt their domain handlers to
702
+ * these existing Tool/Phase lifecycles without importing host Scope types. */
703
+ type ToolContribution = Tool$1;
704
+ type PhaseContribution = Phase;
705
+ type ResourceView = Readonly<{
706
+ agents: readonly ResourceSourceId[];
707
+ tools: readonly ResourceSourceId[];
708
+ skills: readonly ResourceSourceId[];
709
+ phases: readonly ResourceSourceId[];
1205
710
  }>;
1206
- type DurableConsumer = Readonly<{
1207
- caughtUp: Promise<void>;
1208
- done: Promise<void>;
1209
- stop(): void;
711
+ type ResourceRef = Readonly<{
712
+ kind: ResourceKind;
713
+ sourceId: ResourceSourceId;
714
+ name: string;
1210
715
  }>;
1211
- interface AgentRun {
1212
- readonly id: RunId;
1213
- snapshot(): Promise<RunSnapshot>;
1214
- observe(options?: {
1215
- after?: EventCursor;
1216
- signal?: AbortSignal;
1217
- }): AsyncIterable<RunEvent>;
1218
- wait(options?: {
1219
- signal?: AbortSignal;
1220
- }): Promise<RunBoundary>;
1221
- respondInteraction(input: {
1222
- interactionId: string;
1223
- input?: JsonValue;
1224
- cancel?: boolean;
1225
- }): Promise<void>;
1226
- cancel(reason?: string): Promise<RunBoundary>;
716
+ type ResourceDiagnostic = Readonly<{
717
+ kind: "invalid" | "missing" | "collision";
718
+ sourceId: ResourceSourceId;
719
+ message: string;
720
+ path?: string;
721
+ }>;
722
+ type LoadResult = Readonly<{
723
+ revision: string;
724
+ registered: readonly ResourceRef[];
725
+ skipped: readonly ResourceDiagnostic[];
726
+ }>;
727
+ type LoadInput<T> = Readonly<{
728
+ sourceId: ResourceSourceId;
729
+ directory?: string;
730
+ values?: readonly T[];
731
+ }>;
732
+ type ResolvedResourceView = Readonly<{
733
+ agents: readonly AgentDefinition[];
734
+ tools: readonly Tool$1[];
735
+ skills: readonly Skill[];
736
+ phases: readonly Phase[];
737
+ revisions: Readonly<Record<ResourceKind, readonly string[]>>;
738
+ refs: Readonly<Record<ResourceKind, readonly ResourceRef[]>>;
739
+ }>;
740
+ type ResourceRegistryErrorCode = "invalid_source_id" | "invalid_resource_name" | "resource_collision" | "resource_input_missing" | "resource_directory_not_supported" | "unknown_resource_source" | "implicit_source_protected";
741
+ declare class ResourceRegistryError extends Error {
742
+ readonly code: ResourceRegistryErrorCode;
743
+ constructor(code: ResourceRegistryErrorCode, message: string);
744
+ }
745
+ type RegistryValue = AgentDefinition | Tool$1 | Skill | Phase;
746
+ /**
747
+ * Runtime Resource Registry source transaction and view resolver.
748
+ *
749
+ * Directory normalization is intentionally added by the typed loader slice;
750
+ * this first module owns only the atomic source/revision/collision semantics.
751
+ */
752
+ declare class ResourceRegistry {
753
+ private readonly sources;
754
+ /** Sources registered by the bootstrap boundary (currently Extensions). */
755
+ private readonly implicitSources;
756
+ private revisionSequence;
757
+ loadAgents(input: LoadInput<AgentDefinition>): Promise<LoadResult>;
758
+ loadSkills(input: LoadInput<Skill>): Promise<LoadResult>;
759
+ loadPhases(input: LoadInput<Phase>): Promise<LoadResult>;
760
+ loadTools(input: Readonly<{
761
+ sourceId: ResourceSourceId;
762
+ values: readonly ToolContribution[];
763
+ }>): Promise<LoadResult>;
764
+ unload(input: Readonly<{
765
+ kind: ResourceKind;
766
+ sourceId: ResourceSourceId;
767
+ }>): Promise<LoadResult>;
768
+ resolveView(view: ResourceView): ResolvedResourceView;
769
+ /** Mark one already-loaded source as implicit for every Resource View. */
770
+ protected markImplicit(kind: ResourceKind, sourceId: ResourceSourceId): void;
771
+ /** Bootstrap-only helper for replacing an implicit contribution source. */
772
+ protected replaceImplicit<T extends RegistryValue>(kind: ResourceKind, sourceId: ResourceSourceId, values: readonly T[]): Promise<LoadResult>;
773
+ protected hasImplicit(kind: ResourceKind, sourceId: ResourceSourceId): boolean;
774
+ private withImplicit;
775
+ private collect;
776
+ private commit;
777
+ private resolveKind;
778
+ private resolveRevisions;
779
+ private resolveRefs;
780
+ private sourcesFor;
781
+ private nextRevision;
782
+ }
783
+
784
+ declare class InMemoryExtensionHost implements ExtensionHost {
785
+ private readonly configs;
786
+ private readonly agentState;
787
+ private readonly globalState;
788
+ private readonly listeners;
789
+ extendApi?(extensionId: string): HostApiExtension | undefined;
790
+ constructor(options?: {
791
+ configs?: Record<string, Record<string, JsonObject>>;
792
+ agentState?: Record<string, Record<string, Record<string, JsonValue>>>;
793
+ globalState?: Record<string, Record<string, JsonValue>>;
794
+ extendApi?: (extensionId: string) => HostApiExtension | undefined;
795
+ });
796
+ setConfig(extensionId: string, config: JsonObject | null, scope?: ScopeRef): void;
797
+ getConfig(extensionId: string, scope?: ScopeRef): JsonObject | null;
798
+ onConfigChanged(listener: (extensionId: string, scope: ScopeRef) => void): () => void;
799
+ notifyConfigChanged(extensionId: string, scope?: ScopeRef): void;
800
+ getAgentState(extensionId: string, agentId: string, key: string): JsonValue | undefined;
801
+ setAgentState(extensionId: string, agentId: string, key: string, value: JsonValue): void;
802
+ deleteAgentState(extensionId: string, agentId: string, key: string): void;
803
+ getGlobalState(extensionId: string, key: string): JsonValue | undefined;
804
+ setGlobalState(extensionId: string, key: string, value: JsonValue): void;
805
+ deleteGlobalState(extensionId: string, key: string): void;
1227
806
  }
1228
- interface AgentRuntime$1 {
807
+
808
+ /** The Resource Source an Extension registration lands in: Global (`[]`) is `rowan.extensions`, any other Scope `rowan.extensions:<scopeToKey(scope)>`. */
809
+ declare function extensionSourceId(scope?: ScopeRef): string;
810
+ type ExtensionRunnerOptions = {
811
+ entryPhaseId?: string | null;
812
+ cwd?: string;
813
+ host?: ExtensionHost;
814
+ };
815
+ /**
816
+ * Manages extensions and provides hooks for the agent loop.
817
+ *
818
+ * Features:
819
+ * - Per-extension tracking (handlers, tools, phases)
820
+ * - Shared runtime with lifecycle protection (invalidate/assertActive)
821
+ * - Error listener pattern for structured error handling
822
+ * - Direct hook API and extension-loaded hook API
823
+ * - Tool registration for LLM-callable tools
824
+ * - EventBus for inter-extension communication
825
+ *
826
+ * @example
827
+ * ```ts
828
+ * const runner = createExtensionRunner();
829
+ *
830
+ * // Direct hook registration
831
+ * const unsub = runner.on("before_tool_call", (event) => {
832
+ * return { allow: false, reason: "Blocked" };
833
+ * });
834
+ *
835
+ * // Error handling
836
+ * runner.onError((error) => {
837
+ * console.error(`Extension error in ${error.extensionPath}:`, error.error);
838
+ * });
839
+ *
840
+ * // Load extensions
841
+ * await runner.loadExtensions(extensions);
842
+ * runner.bind();
843
+ * ```
844
+ */
845
+ declare class ExtensionRunner {
846
+ readonly hooks: HooksManager;
847
+ readonly runtime: ExtensionRuntime;
848
+ readonly events: EventBus;
1229
849
  readonly host: ExtensionHost;
1230
- loadAgents(input: LoadInput<AgentDefinition>): Promise<LoadResult>;
1231
- loadSkills(input: LoadInput<Skill>): Promise<LoadResult>;
1232
- loadPhases(input: LoadInput<Phase>): Promise<LoadResult>;
1233
- loadTools(input: Readonly<{
1234
- sourceId: string;
1235
- values: readonly Tool$1[];
1236
- }>): Promise<LoadResult>;
1237
- unload(input: Readonly<{
1238
- kind: ResourceKind;
1239
- sourceId: string;
1240
- }>): Promise<LoadResult>;
1241
- createAgent(config: AgentConfiguration, options?: {
1242
- idempotencyKey?: string;
1243
- metadata?: Metadata;
1244
- historySeed?: HistorySeed;
1245
- }): Promise<AgentId>;
1246
- updateAgentConfig(agentId: AgentId, config: AgentConfiguration, options: {
1247
- idempotencyKey: string;
1248
- }): Promise<void>;
1249
- deleteAgent(input: AgentDeletionRequest): Promise<void>;
1250
- revise(agentId: AgentId, input: {
1251
- messageId: MessageId;
1252
- expectedMessageRevision: number;
1253
- content: UserContent;
1254
- operationId: string;
1255
- effectDigestConfirmation?: string;
1256
- }): Promise<MessageRevisionResult>;
1257
- compact(input?: {
1258
- now?: string;
1259
- retentionMs?: number;
1260
- }): Promise<RetentionResult>;
1261
- start(agentId: AgentId, input: UserInput, options: {
1262
- idempotencyKey: string;
1263
- metadata?: Metadata;
1264
- scope?: ScopeRef;
1265
- cwd?: string;
1266
- phasePayload?: JsonValue;
1267
- entryPhases?: ReadonlyArray<EntryPhaseSpec>;
1268
- }): Promise<AgentRun>;
1269
- run(runId: RunId): AgentRun;
1270
- contextStatus(agentId: AgentId, options?: {
1271
- contextWindow?: number;
1272
- }): Promise<ContextStatus>;
1273
- compactContext(agentId: AgentId, options?: {
1274
- input?: UserInput;
1275
- instructions?: string;
1276
- idempotencyKey?: string;
1277
- }): Promise<AgentRun>;
1278
- runPhase(agentId: AgentId, options: {
1279
- phase: string;
1280
- payload?: JsonValue;
1281
- input?: UserInput;
1282
- yieldToInput?: boolean;
1283
- idempotencyKey?: string;
1284
- }): Promise<AgentRun>;
1285
- listInvocations(agentId: AgentId, options: {
1286
- source: InvocationSource;
1287
- }): Promise<readonly InvocationCatalogEntry[]>;
1288
- history(agentId: AgentId): Promise<readonly Message[]>;
1289
- listAgents(input?: {
1290
- after?: AgentListCursor;
1291
- limit?: number;
1292
- }): Promise<Page<AgentSummary, AgentListCursor>>;
1293
- listRuns(input?: {
1294
- agentId?: AgentId;
1295
- states?: readonly RunState[];
1296
- after?: RunListCursor;
1297
- limit?: number;
1298
- }): Promise<Page<RunSummary, RunListCursor>>;
1299
- consume(input: {
1300
- consumerId: string;
1301
- signal: AbortSignal;
1302
- onEvent(event: DurableRunEvent, context: Readonly<{
1303
- signal: AbortSignal;
1304
- }>): void | Promise<void>;
1305
- }): Promise<DurableConsumer>;
1306
- listCapabilities(): readonly ExtensionCapability[];
850
+ private readonly cwd;
851
+ private readonly abortController;
852
+ private _idle;
853
+ private readonly extensions;
854
+ private readonly runState;
855
+ private readonly configChangeListeners;
856
+ private readonly hostUnsubscribers;
857
+ private readonly phases;
858
+ private _phaseCache;
859
+ private readonly skills;
860
+ private readonly pendingProviders;
861
+ private bound;
862
+ private readonly errorListeners;
863
+ private readonly capabilityListeners;
864
+ private readonly resourceChangeListeners;
865
+ /** Current agent context — set by the agent before each phase */
866
+ currentContext?: AgentContext;
867
+ constructor(options?: ExtensionRunnerOptions);
868
+ /** Whether the agent is currently idle (not streaming). */
869
+ get isIdle(): boolean;
870
+ /** Set idle state — called by the agent loop. */
871
+ setIdle(idle: boolean): void;
872
+ /** Abort signal for the current runner instance. */
873
+ get signal(): AbortSignal;
874
+ /** Abort the current runner operation. */
875
+ abort(): void;
876
+ /**
877
+ * Register an error listener.
878
+ * Returns an unsubscribe function.
879
+ */
880
+ onError(listener: ExtensionErrorListener): () => void;
881
+ /**
882
+ * Emit a structured extension error to all listeners.
883
+ */
884
+ emitError(error: ExtensionError): void;
885
+ /**
886
+ * Mark all extension contexts as stale.
887
+ * After calling this, any captured ExtensionAPI or ExtensionContext will throw
888
+ * on use. Used during runtime replacement or reload.
889
+ */
890
+ invalidate(message?: string): void;
891
+ /**
892
+ * Subscribe to a specific hook event type.
893
+ * Returns an unsubscribe function.
894
+ *
895
+ * @example
896
+ * ```ts
897
+ * const unsub = runner.on("before_tool_call", (event) => {
898
+ * return { allow: false, reason: "Blocked" };
899
+ * });
900
+ * unsub(); // Cancel subscription
901
+ * ```
902
+ */
903
+ on<K extends HookEventType>(type: K, handler: HookHandler<K>): () => void;
904
+ /**
905
+ * Load and initialize extensions.
906
+ * Creates Extension tracking objects and calls each factory with an ExtensionAPI.
907
+ */
908
+ loadExtensions(extensions: LoadedExtension[]): Promise<void>;
909
+ /** Dispose all active Extensions in reverse activation order. */
910
+ close(): Promise<void>;
911
+ get extensionHost(): ExtensionHost;
912
+ notifyConfigChanged(extensionId: string, scope: ScopeRef): Promise<void>;
913
+ getRunState(runId: string, extensionId: string, key: string): JsonValue | undefined;
914
+ setRunState(runId: string, extensionId: string, key: string, value: JsonValue): void;
915
+ deleteRunState(runId: string, extensionId: string, key: string): void;
916
+ dropRunState(runId: string): void;
917
+ /** Get all registered tools from all extensions. */
918
+ getAllRegisteredTools(): RegisteredTool[];
919
+ /**
920
+ * Get a tool definition by name. Returns undefined if not found.
921
+ */
922
+ getToolDefinition(toolName: string): RegisteredTool["definition"] | undefined;
923
+ /** Get all contributed capabilities across all extensions. */
924
+ getCapabilities(): readonly ExtensionCapability[];
925
+ /**
926
+ * Subscribe to capability changes (contributions added, removed, or extensions disposed).
927
+ * Returns an unsubscribe function.
928
+ */
1307
929
  onCapabilitiesChanged(listener: (capabilities: readonly ExtensionCapability[]) => void): () => void;
930
+ /**
931
+ * Subscribe to resource changes (tools, phases, skills registered, unregistered, or disposed).
932
+ * Used by RuntimeBootstrapRegistry to re-commit implicit sources after activation.
933
+ */
934
+ onResourceChange(listener: (kind: "tool" | "phase" | "skill") => Promise<void> | void): () => void;
935
+ private notifyResourceChange;
1308
936
  triggerUiAction(event: {
1309
937
  contributionId: string;
1310
938
  actionId: string;
1311
939
  scope?: ScopeRef;
1312
- }): void;
1313
- close(): Promise<void>;
1314
- }
1315
- type ConsumerRegistration = Readonly<{
1316
- cursor?: EventCursor;
1317
- waterline: EventCursor;
1318
- }>;
1319
-
1320
- interface ExtensionStateStore {
1321
- get(key: string): Promise<JsonValue | undefined>;
1322
- set(key: string, value: JsonValue): Promise<void>;
1323
- delete(key: string): Promise<void>;
1324
- }
1325
- interface ExtensionHost {
1326
- getConfig(extensionId: string, scope?: ScopeRef): Promise<JsonObject | null> | JsonObject | null;
1327
- onConfigChanged?(listener: (extensionId: string, scope: ScopeRef) => void): (() => void) | void;
1328
- getAgentState(extensionId: string, agentId: string, key: string): Promise<JsonValue | undefined> | JsonValue | undefined;
1329
- setAgentState(extensionId: string, agentId: string, key: string, value: JsonValue): Promise<void> | void;
1330
- deleteAgentState(extensionId: string, agentId: string, key: string): Promise<void> | void;
1331
- getGlobalState(extensionId: string, key: string): Promise<JsonValue | undefined> | JsonValue | undefined;
1332
- setGlobalState(extensionId: string, key: string, value: JsonValue): Promise<void> | void;
1333
- deleteGlobalState(extensionId: string, key: string): Promise<void> | void;
940
+ }): void;
941
+ getPhase(name: string): Phase | undefined;
942
+ getPhases(): Phase[];
943
+ getRegisteredPhases(): readonly RegisteredPhase[];
944
+ createPhaseRegistry(input?: {
945
+ entryPhaseId?: string | null;
946
+ }): PhaseRegistry;
947
+ /** Adapt an extension RegisteredPhase to the core Phase type. */
948
+ adaptToPhase(reg: RegisteredPhase): Phase;
949
+ getSkills(): Skill[];
950
+ getRegisteredSkills(): readonly RegisteredSkill[];
951
+ /**
952
+ * Bind the runner — flushes pending provider registrations and
953
+ * replaces runtime stubs with real implementations.
954
+ */
955
+ bind(): void;
956
+ /**
957
+ * Generic emit — fire-and-forget for any event type.
958
+ */
959
+ emit<K extends HookEventType>(eventType: K, event: Parameters<HookHandler<K>>[0]): Promise<void>;
960
+ /**
961
+ * Unified hook emission — returns the first non-undefined result.
962
+ */
963
+ private emitHook;
964
+ emitBeforePhase(phaseId: string, input: PhaseContext): Promise<{
965
+ abort?: any;
966
+ skip?: any;
967
+ input?: PhaseContext;
968
+ }>;
969
+ emitAfterPhase(phaseId: string, output: PhaseOutput): Promise<{
970
+ abort?: any;
971
+ retry?: PhaseContext;
972
+ output?: PhaseOutput;
973
+ }>;
974
+ emitBeforePrompt(phaseId: string, input: PhaseContext): Promise<PhaseContext>;
975
+ emitRunStart(event: {
976
+ runId: string;
977
+ agentId: string;
978
+ metadata: Readonly<Record<string, unknown>>;
979
+ turn: JsonObject;
980
+ }): Promise<void>;
981
+ emitRunEnd(event: {
982
+ runId: string;
983
+ agentId: string;
984
+ outcome: unknown;
985
+ }): Promise<void>;
986
+ emitBeforeToolCall(tool: Tool, args: unknown, context?: {
987
+ runId?: string;
988
+ agentId?: string;
989
+ toolCallId?: string;
990
+ metadata?: Readonly<Record<string, unknown>>;
991
+ agentMetadata?: Readonly<Record<string, unknown>>;
992
+ answer?: unknown;
993
+ scope?: ScopeRef;
994
+ turn?: JsonObject;
995
+ phase?: ToolCallPhase;
996
+ }): Promise<BeforeToolCallResult>;
997
+ emitAfterToolCall(tool: Tool, result: ToolResult, context?: {
998
+ runId?: string;
999
+ agentId?: string;
1000
+ toolCallId?: string;
1001
+ metadata?: Readonly<Record<string, unknown>>;
1002
+ scope?: ScopeRef;
1003
+ turn?: JsonObject;
1004
+ phase?: ToolCallPhase;
1005
+ }): Promise<ToolResult>;
1334
1006
  /**
1335
- * Called once per extension load. The returned namespaces are merged into that extension's `api`
1336
- * (a name already used by Rowan's own API is an error). `dispose` runs when the extension is
1337
- * unloaded, reloaded or fails activation, so the host can drop everything that extension registered.
1007
+ * Create an ExtensionAPI for a specific extension.
1008
+ * Registration methods write to the extension tracking object.
1009
+ * Action methods delegate to the shared runtime.
1338
1010
  */
1339
- extendApi?(extensionId: string): HostApiExtension | undefined;
1340
- }
1341
- interface HostApiExtension {
1342
- readonly namespaces: Readonly<Record<string, unknown>>;
1343
- dispose?(): void;
1344
- }
1345
- type ExtensionToolContribution = {
1346
- kind: "tool";
1347
- name: string;
1348
- description: string;
1349
- };
1350
- type ExtensionCapabilityContribution = ExtensionToolContribution;
1351
- type ExtensionCapability = {
1352
- extensionId: string;
1353
- kind: "tool";
1354
- name: string;
1355
- description: string;
1356
- };
1357
- interface SourceInfo {
1358
- source: string;
1359
- baseDir?: string;
1360
- displayName?: string;
1361
- }
1362
- /** A loaded directory Bundle used by an extension. */
1363
- type PhaseDefinition = Phase;
1364
- /** Register a Phase by directory path or Phase object; PHASE.md and direct child Skills are loaded atomically when a path is supplied. */
1365
- type PhaseRegistration = string | Phase;
1366
- type RegisteredPhase = {
1367
- definition: PhaseDefinition;
1368
- source: {
1369
- extensionPath: string;
1370
- };
1371
- sourceId: string;
1372
- scope?: ScopeRef;
1373
- };
1374
- /** Register a Skill directory (containing SKILL.md) or a Skill object. Registering an existing name replaces it. */
1375
- type SkillRegistration = string | Skill;
1376
- type RegisteredSkill = {
1377
- definition: Skill;
1378
- source: {
1379
- extensionPath: string;
1380
- };
1381
- sourceId: string;
1382
- scope?: ScopeRef;
1383
- };
1384
- /**
1385
- * Tool definition for registering LLM-callable tools via `api.tools.register()`.
1386
- *
1387
- * @example
1388
- * ```typescript
1389
- * api.tools.register({
1390
- * name: "search_docs",
1391
- * description: "Search documentation",
1392
- * parameters: { type: "object", properties: { query: { type: "string" } } },
1393
- * execute: async (args, ctx) => {
1394
- * return { content: [{ type: "text", text: "result" }] };
1395
- * },
1396
- * });
1397
- * ```
1398
- */
1399
- interface ToolDefinition {
1400
- /** Tool name (used in LLM tool calls) */
1401
- name: string;
1402
- /** Description for LLM */
1403
- description: string;
1404
- /** Parameter schema (JSON Schema) */
1405
- parameters: Record<string, unknown>;
1406
- /** Optional: one-line snippet shown in the system prompt tool list */
1407
- promptSnippet?: string;
1408
- /** Optional: additional guidelines appended to system prompt */
1409
- promptGuidelines?: string[];
1410
- kind?: ToolKind;
1411
- annotations?: ToolAnnotations;
1412
- _meta?: JsonObject;
1413
- present?: (call: {
1414
- status: ToolCallStatus;
1415
- args: JsonValue;
1416
- progress?: ToolProgress;
1417
- result?: ToolExecutionResult;
1418
- }) => {
1419
- title?: string;
1420
- content?: ToolCallContent[];
1421
- locations?: ToolCallLocation[];
1422
- _meta?: JsonObject;
1423
- } | undefined | void | Promise<{
1424
- title?: string;
1425
- content?: ToolCallContent[];
1426
- locations?: ToolCallLocation[];
1427
- _meta?: JsonObject;
1428
- } | undefined | void>;
1429
- /** Execute the tool */
1430
- execute: (args: unknown, context: ToolInvocationContext, signal?: AbortSignal) => Promise<ToolExecutionResult>;
1431
- /** Optional: per-tool execution mode override */
1432
- executionMode?: "sequential" | "parallel";
1011
+ private createExtensionAPI;
1012
+ private registerTool;
1013
+ private unregisterTool;
1014
+ private contributeCapability;
1015
+ private notifyCapabilitiesChanged;
1016
+ private registerPhase;
1017
+ private registerPhaseDefinition;
1018
+ private unregisterPhase;
1019
+ private loadRegisteredPhase;
1020
+ private registerSkill;
1021
+ private registerSkillDefinition;
1022
+ private unregisterSkill;
1023
+ private loadRegisteredSkill;
1024
+ private registerProvider;
1025
+ private unregisterProvider;
1026
+ private flushPendingProviders;
1027
+ private getRegisteredPhase;
1028
+ private collectRegisteredPhases;
1029
+ private rollbackExtension;
1030
+ private disposeExtension;
1433
1031
  }
1434
1032
 
1435
- /**
1436
- * Registered tool with source metadata.
1437
- */
1438
- interface RegisteredTool {
1439
- definition: ToolDefinition;
1440
- sourceInfo: SourceInfo;
1441
- sourceId: string;
1442
- scope?: ScopeRef;
1443
- }
1444
- /**
1445
- * Structured extension error with attribution.
1446
- */
1447
- interface ExtensionError {
1448
- /** Path of the extension that caused the error */
1449
- extensionPath: string;
1450
- /** Event or operation that caused the error */
1451
- event: string;
1452
- /** Error message */
1453
- error: string;
1454
- /** Optional stack trace */
1455
- stack?: string;
1456
- }
1457
- /** Error listener callback type. */
1458
- type ExtensionErrorListener = (error: ExtensionError) => void;
1459
- type ExecOptions = {
1460
- /** Working directory for the command. Defaults to cwd passed to runtime. */
1461
- cwd?: string;
1462
- /** Environment variables to add/override. */
1463
- env?: Record<string, string>;
1464
- /** Timeout in milliseconds. */
1465
- timeout?: number;
1466
- /** AbortSignal for cancellation. */
1467
- signal?: AbortSignal;
1033
+ type ToolCallPresentationInput = Readonly<{
1034
+ status: ToolCallStatus;
1035
+ args: JsonValue$1;
1036
+ progress?: ToolProgress;
1037
+ result?: ToolExecutionResult;
1038
+ }>;
1039
+ type ToolCallPresentationOutput = {
1040
+ title?: string;
1041
+ content?: ToolCallContent[];
1042
+ locations?: ToolCallLocation[];
1043
+ _meta?: JsonObject$1;
1468
1044
  };
1469
- type ExecResult = {
1470
- exitCode: number;
1471
- stdout: string;
1472
- stderr: string;
1045
+ type ToolCallMergeTarget = {
1046
+ title?: string;
1047
+ kind?: ToolKind;
1048
+ status?: ToolCallStatus;
1049
+ locations?: ToolCallLocation[];
1050
+ content?: ToolCallContent[];
1051
+ rawInput?: JsonValue$1;
1052
+ rawOutput?: JsonValue$1;
1053
+ _meta?: JsonObject$1;
1473
1054
  };
1474
- /**
1475
- * Shared runtime state created by loader, used during registration and runtime.
1476
- * All ExtensionAPI instances reference this shared state.
1477
- *
1478
- * It only owns the lifetime guard shared by captured Extension API objects.
1479
- */
1480
- interface ExtensionRuntime {
1481
- /** Throws when this extension instance is stale after runtime replacement. */
1482
- assertActive: () => void;
1483
- /** Marks this extension instance as stale after runtime replacement or reload. */
1484
- invalidate: (message?: string) => void;
1485
- }
1486
- /**
1487
- * Result of loading extensions from filesystem.
1488
- * The runner takes these and creates Extension tracking objects.
1489
- */
1490
- type LoadExtensionsResult = {
1491
- extensions: LoadedExtension[];
1492
- errors: Array<{
1493
- path: string;
1494
- error: string;
1495
- }>;
1055
+ type ToolCallMergePatch = {
1056
+ title?: string;
1057
+ kind?: ToolKind;
1058
+ status?: ToolCallStatus;
1059
+ locations?: ToolCallLocation[];
1060
+ content?: ToolCallContent[];
1061
+ rawInput?: JsonValue$1;
1062
+ rawOutput?: JsonValue$1;
1063
+ _meta?: JsonObject$1;
1496
1064
  };
1497
- /**
1498
- * Pre-initialization extension form — factory + metadata.
1499
- * Runner.loadExtensions() calls the factory and creates the full Extension object.
1500
- */
1501
- interface LoadedExtension {
1502
- id?: string;
1065
+ declare function mergeToolCall<T extends ToolCallMergeTarget>(target: T, patch: ToolCallMergePatch): T;
1066
+
1067
+ type ExtensionContribution = LoadedExtension;
1068
+ type ExtensionLoadInput = LoadInput<ExtensionContribution>;
1069
+ type ExtensionActivationError = Readonly<{
1503
1070
  path: string;
1504
- name: string;
1505
- factory: ExtensionFactory;
1506
- manifest?: ExtensionManifest;
1071
+ error: string;
1072
+ }>;
1073
+ type ExtensionActivationResult = Readonly<{
1074
+ active: readonly string[];
1075
+ errors: readonly ExtensionActivationError[];
1076
+ revision?: string;
1077
+ registered?: readonly string[];
1078
+ skipped?: readonly ResourceDiagnostic[];
1079
+ }>;
1080
+ type ExtensionLifetimeErrorCode = "extensions_frozen" | "extensions_closed";
1081
+ declare class ExtensionLifetimeError extends Error {
1082
+ readonly code: ExtensionLifetimeErrorCode;
1083
+ constructor(code: ExtensionLifetimeErrorCode, message: string);
1507
1084
  }
1508
- /** Extension manifest from package.json `rowan` field. */
1509
- interface ExtensionManifest {
1510
- id?: string;
1511
- entry?: string;
1512
- name?: string;
1085
+ /** Runtime-global Extension activation and lifetime boundary. */
1086
+ declare class RuntimeExtensionLifetime {
1087
+ private readonly runner;
1088
+ private frozen;
1089
+ private closed;
1090
+ constructor(options?: {
1091
+ cwd?: string;
1092
+ host?: ExtensionHost;
1093
+ });
1094
+ activate(extensions: readonly LoadedExtension[]): Promise<ExtensionActivationResult>;
1095
+ tools(): readonly RegisteredTool[];
1096
+ phases(): readonly Phase[];
1097
+ registeredPhases(): readonly RegisteredPhase[];
1098
+ skills(): readonly Skill[];
1099
+ registeredSkills(): readonly RegisteredSkill[];
1100
+ get extensionRunner(): ExtensionRunner;
1101
+ get extensionHost(): ExtensionHost;
1102
+ onResourceChange(listener: (kind: "tool" | "phase" | "skill") => Promise<void> | void): () => void;
1103
+ dropRunState(runId: string): void;
1104
+ close(): Promise<void>;
1513
1105
  }
1514
-
1515
- /**
1516
- * Extension API object passed to extension factory function.
1517
- *
1518
- * @example
1519
- * ```typescript
1520
- * export default function(api: ExtensionAPI) {
1521
- * // api provides all extension APIs
1522
- * }
1523
- * ```
1524
- */
1525
- interface ExtensionAPI {
1526
- /** Hook events — subscribe or unsubscribe. */
1527
- hooks: {
1528
- /**
1529
- * Subscribe to a hook event.
1530
- *
1531
- * @param eventType - Hook type, e.g. "before_tool_call"
1532
- * @param handler - Hook handler, can return result to modify behavior
1533
- */
1534
- on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
1535
- /** Unsubscribe from a hook event. */
1536
- off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
1537
- };
1538
- /** Extension configuration — read own layered config or listen for changes. */
1539
- config: {
1540
- /** Get the extension's own effective configuration block. */
1541
- get(scope?: ScopeRef): Promise<JsonObject | null>;
1542
- /** Listen for configuration changes for a scope. */
1543
- changed(handler: (scope: ScopeRef) => void): void;
1544
- };
1545
- /** Extension state — scoped to run (in-memory) or agent (durable) or global (durable). */
1546
- state: {
1547
- /** Run-scoped in-memory state; dropped when the Run ends. */
1548
- run(runId: string): ExtensionStateStore;
1549
- /** Agent-scoped durable state; persisted with the Agent record. */
1550
- agent(agentId: string): ExtensionStateStore;
1551
- /** Extension-scoped durable state; survives process restarts. */
1552
- global(): ExtensionStateStore;
1553
- };
1554
- /** Tool capabilities — register and unregister custom tools. */
1555
- tools: {
1556
- /** Register a custom LLM-callable tool. */
1557
- register(tool: ToolDefinition, scope?: ScopeRef): Promise<void>;
1558
- /** Unregister a previously registered tool by name. */
1559
- unregister(toolName: string, scope?: ScopeRef): Promise<void>;
1560
- };
1561
- /** Capability contributions — advertise tools or features to the host. */
1562
- capabilities: {
1563
- /** Contribute a capability to the host. Returns a disposer to remove the contribution. */
1564
- contribute(contribution: ExtensionCapabilityContribution): () => void;
1565
- };
1566
- /** Model provider registration. */
1567
- providers: {
1568
- /** Register a model provider. Registering with an existing id replaces it. */
1569
- register(config: _rowan_agent_models.ProviderConfig): void;
1570
- /** Unregister a model provider by id. */
1571
- unregister(id: string): void;
1572
- };
1573
- /** Phase execution capabilities — provides Phase In/Out, phase identity, phase routing, and registration. */
1574
- phases: {
1575
- /** Register a Phase directory bundle or Phase object. */
1576
- register(phase: PhaseRegistration, scope?: ScopeRef): Promise<void>;
1577
- /** Unregister a previously registered phase by name. */
1578
- unregister(phaseName: string, scope?: ScopeRef): Promise<void> | void;
1579
- /** Phase In: get payload from previous phase */
1580
- getPayload(): unknown;
1581
- /** Phase Out: set payload for next phase */
1582
- setPayload(payload: unknown): void;
1583
- /** Phase Out: set outcome message */
1584
- setMessage(message: string): void;
1585
- /** Get current phase name */
1586
- getCurrentPhase(): string;
1587
- /** Set next phase (lower priority than PHASE.md target) */
1588
- setNextPhase(phaseName: string): void;
1589
- /** Get the next phase set by setNextPhase */
1590
- getNextPhase(): string | undefined;
1591
- /** Get the message set by setMessage */
1592
- getMessage(): string | undefined;
1593
- };
1594
- /** Skill capabilities — register and unregister standalone skills. */
1595
- skills: {
1596
- /** Register a Skill directory (containing SKILL.md) or a Skill object. Registering an existing name replaces it. */
1597
- register(skill: SkillRegistration, scope?: ScopeRef): Promise<void>;
1598
- /** Unregister a previously registered Skill by name. */
1599
- unregister(skillName: string, scope?: ScopeRef): Promise<void> | void;
1600
- };
1601
- /** Extension manifest from package.json `rowan` field. */
1602
- manifest?: ExtensionManifest;
1603
- /** Utility functions. */
1604
- utils: ExtensionUtils;
1605
- /** Runtime context — cwd, signal, exec, message access, etc. */
1606
- context: ExtensionContext;
1607
- /** Shared event bus for inter-extension communication. */
1608
- events: EventBus;
1106
+ /** Bootstrap-only Registry facade; its Extension method disappears after init. */
1107
+ declare class RuntimeBootstrapRegistry extends ResourceRegistry {
1108
+ private readonly extensions;
1109
+ private readonly knownSources;
1110
+ private commitQueue;
1111
+ constructor(extensions?: RuntimeExtensionLifetime);
1112
+ private recommit;
1113
+ get extensionHost(): ExtensionHost;
1114
+ /** Install Rowan-owned implicit resources before any host source is read. */
1115
+ ensureCoreResources(): Promise<void>;
1116
+ loadExtensions(input: readonly LoadedExtension[] | ExtensionLoadInput): Promise<ExtensionActivationResult>;
1117
+ get extensionRunner(): ExtensionRunner;
1118
+ get extensionTools(): readonly RegisteredTool[];
1119
+ get extensionPhases(): readonly Phase[];
1120
+ closeExtensions(): Promise<void>;
1609
1121
  }
1610
- /**
1611
- * Extension factory function.
1612
- * Receives ExtensionAPI for registering hooks, phases, and providers.
1613
- */
1614
- type ExtensionDisposer = () => void | Promise<void>;
1615
- type ExtensionFactoryResult = void | ExtensionDisposer;
1616
- type ExtensionFactory = (api: ExtensionAPI) => ExtensionFactoryResult | Promise<ExtensionFactoryResult>;
1617
1122
 
1618
- type PhaseStatusState = "running" | "completed";
1619
- /** Normalized status event exposed to Runtime consumers. */
1620
- type PhaseStatus = Readonly<{
1621
- state: PhaseStatusState;
1622
- /** Stable consumer-facing status identifier, e.g. `compacting`. */
1623
- kind: string;
1624
- /** Optional human-readable detail for UI/status consumers. */
1625
- message?: string;
1626
- /** Structured status payload. */
1627
- payload?: unknown;
1123
+ type DefinitionLayer = Readonly<{
1124
+ description?: string;
1125
+ prompt?: string;
1126
+ model?: ModelRef;
1127
+ tools?: readonly string[];
1128
+ skills?: readonly string[];
1129
+ phases?: PhaseRegistrySelection;
1130
+ }>;
1131
+ type AgentConfiguration = Readonly<{
1132
+ identity: string;
1133
+ definition: Readonly<{
1134
+ name: string;
1135
+ layer?: DefinitionLayer;
1136
+ }>;
1137
+ resourceView: ResourceView;
1138
+ contexts?: readonly ContextCandidate[];
1139
+ /** Trusted Host-owned Contexts rendered as durable user messages. */
1140
+ additionalContexts?: readonly ContextCandidate[];
1141
+ cwd?: string;
1142
+ maxAttempts?: number;
1143
+ model: ModelConfig | ModelRef;
1144
+ stream?: StreamFn;
1145
+ }>;
1146
+ type ConfigurationSnapshot = Readonly<{
1147
+ identity: string;
1148
+ definition: AgentDefinition;
1149
+ resources: Readonly<{
1150
+ tools: readonly Tool$1[];
1151
+ skills: readonly Skill[];
1152
+ phases?: PhaseRegistry;
1153
+ revisions: Readonly<Record<ResourceKind, readonly string[]>>;
1154
+ refs: Readonly<Record<ResourceKind, readonly ResourceRef[]>>;
1155
+ }>;
1156
+ contexts: readonly ContextCandidate[];
1157
+ additionalContexts: readonly ContextCandidate[];
1158
+ resourceView: ResourceView;
1159
+ cwd?: string;
1160
+ maxAttempts?: number;
1161
+ model: ModelConfig | ModelRef;
1162
+ stream?: StreamFn;
1163
+ }>;
1164
+ /** Resolve one Definition request into one immutable, source-qualified snapshot. */
1165
+ declare function resolveConfigurationSnapshot(registry: ResourceRegistry, input: AgentConfiguration): ConfigurationSnapshot;
1166
+ /** Whether one stored configuration is already a resolved snapshot. A snapshot
1167
+ * is used as it stands; a request is resolved against the current sources. */
1168
+ declare function isConfigurationSnapshot(config: AgentConfiguration | ConfigurationSnapshot): config is ConfigurationSnapshot;
1169
+
1170
+ type UserInput = string | Readonly<{
1171
+ content: UserContent;
1172
+ metadata?: Metadata;
1173
+ thinkingLevel?: ThinkingLevel;
1174
+ providerOptions?: JsonObject;
1175
+ }>;
1176
+ type HistorySeed = readonly Message[];
1177
+ type ContextStatus = Readonly<{
1178
+ tokens: number;
1179
+ contextWindow: number;
1180
+ percent: number;
1181
+ thresholdTokens: number;
1182
+ estimated: boolean;
1183
+ coveredThrough?: Readonly<{
1184
+ messageId: MessageId;
1185
+ sequence: number;
1186
+ }>;
1187
+ }>;
1188
+ type ContextCompactionRecord = Readonly<{
1189
+ id: string;
1190
+ agentId: AgentId;
1191
+ summary: string;
1192
+ coveredThrough?: Readonly<{
1193
+ messageId: MessageId;
1194
+ sequence: number;
1195
+ }>;
1196
+ instructions?: string;
1197
+ createdAt: string;
1198
+ }>;
1199
+ /** Who is calling which tool, without the ability to ask or suspend. Hosts that
1200
+ * describe a call before it runs (for example to build a confirmation) only
1201
+ * have this much. */
1202
+ /** The Phase whose execution issued a Tool call, with its PHASE.md metadata. */
1203
+ type ToolCallPhase = Readonly<{
1204
+ name: string;
1205
+ metadata?: Readonly<Record<string, JsonValue>>;
1206
+ }>;
1207
+ type ToolCallContext = Readonly<{
1208
+ agentId: AgentId;
1209
+ runId: RunId;
1210
+ /** Opaque JSON metadata captured from the Agent and Run records. Rowan does
1211
+ * not interpret host/domain fields. */
1212
+ agentMetadata?: Metadata;
1213
+ runMetadata?: Metadata;
1214
+ toolCallId: ToolCallId;
1215
+ /** The model's id for this call, matching `tool_call_delta` events; absent when a host runs the tool itself. */
1216
+ providerToolCallId?: string;
1217
+ scope?: ScopeRef;
1218
+ turn?: JsonObject;
1219
+ phase?: ToolCallPhase;
1220
+ reportProgress(progress: ToolProgress): void;
1221
+ }>;
1222
+ type ToolInvocationContext = ToolCallContext & Readonly<{
1223
+ interaction: RunInteractionDriver;
1224
+ }>;
1225
+
1226
+ type Tool$1 = Readonly<{
1227
+ name: string;
1228
+ /** Rowan-owned Core Tool; Core Tools bypass Definition/Phase filtering. */
1229
+ core?: boolean;
1230
+ description: string;
1231
+ parameters: Type.TSchema;
1232
+ promptSnippet?: string;
1233
+ promptGuidelines?: readonly string[];
1234
+ kind?: ToolKind;
1235
+ annotations?: ToolAnnotations;
1236
+ _meta?: JsonObject;
1237
+ present?(call: ToolCallPresentationInput): {
1238
+ title?: string;
1239
+ content?: ToolCallContent[];
1240
+ locations?: ToolCallLocation[];
1241
+ _meta?: JsonObject;
1242
+ } | undefined | void | Promise<{
1243
+ title?: string;
1244
+ content?: ToolCallContent[];
1245
+ locations?: ToolCallLocation[];
1246
+ _meta?: JsonObject;
1247
+ } | undefined | void>;
1248
+ execute(args: JsonValue, context: ToolInvocationContext, signal: AbortSignal): Promise<ToolExecutionResult>;
1628
1249
  }>;
1629
- /** Unified phase output — model-driven routing is optional; programmatic phases may normalize omission to stop. */
1630
- type PhaseOutput = {
1631
- /** User-visible assistant message. */
1632
- message?: string;
1633
- /** Final status update for non-conversational consumers. */
1634
- status?: PhaseStatus;
1635
- /** Route to next phase, or "continue" to re-execute current phase, or "stop" to end. Undefined means no model route. */
1636
- route?: string;
1637
- /** Phase name that produced this output */
1638
- phase?: string;
1639
- /** Tool calls from the model invocation (used by framework for route extraction) */
1640
- toolCalls?: Array<{
1641
- id: string;
1642
- name: string;
1643
- args: unknown;
1250
+ type BeforeToolCallDecision = Readonly<{
1251
+ allow: true;
1252
+ }> | Readonly<{
1253
+ allow: false;
1254
+ reason: string;
1255
+ }> | Readonly<{
1256
+ interaction: RunInteractionRequest;
1257
+ }>;
1258
+ type BeforeToolCall = (input: Readonly<{
1259
+ tool: Tool$1;
1260
+ args: JsonValue;
1261
+ context: ToolInvocationContext;
1262
+ signal: AbortSignal;
1263
+ answer?: JsonValue;
1264
+ }>) => BeforeToolCallDecision | Promise<BeforeToolCallDecision>;
1265
+ type AfterToolCall = (input: Readonly<{
1266
+ tool: Tool$1;
1267
+ result: ToolExecutionResult;
1268
+ context: ToolInvocationContext;
1269
+ signal: AbortSignal;
1270
+ }>) => ToolExecutionResult | Promise<ToolExecutionResult>;
1271
+ type InvocationSource = "auto" | "implicit" | "external";
1272
+ type InvocationCatalogEntry = Readonly<{
1273
+ kind: "phase" | "skill";
1274
+ name: string;
1275
+ description: string;
1276
+ input?: Phase["input"];
1277
+ core?: boolean;
1278
+ disableAutoInvocation: boolean;
1279
+ disableImplicitInvocation: boolean;
1280
+ filePath: string;
1281
+ }>;
1282
+ type AgentRecord = Readonly<{
1283
+ id: AgentId;
1284
+ metadata?: Metadata;
1285
+ currentConfigToken?: ConfigToken;
1286
+ currentConfigIdentity?: string;
1287
+ createdAt: string;
1288
+ activatedAt?: string;
1289
+ updatedAt: string;
1290
+ }>;
1291
+ type AgentDeletionRequest = Readonly<{
1292
+ agentId: AgentId;
1293
+ expectedRunIds: readonly RunId[];
1294
+ confirmation: "agent-delete-v1";
1295
+ }>;
1296
+ type ExecutionToken = Readonly<{
1297
+ runId: RunId;
1298
+ ownerEpoch: number;
1299
+ executionId: ExecutionId;
1300
+ }>;
1301
+ type ExecutionCheckpoint = Readonly<{
1302
+ codec: string;
1303
+ version: number;
1304
+ data: JsonValue;
1305
+ }>;
1306
+ type OwnerLease = Readonly<{
1307
+ ownerId: string;
1308
+ token: OwnerToken;
1309
+ epoch: number;
1310
+ expiresAt: string;
1311
+ }>;
1312
+ type RunClaim = Readonly<{
1313
+ run: RunRecord;
1314
+ execution: ExecutionToken;
1315
+ history: readonly Message[];
1316
+ }>;
1317
+ type ToolCallReservation = Readonly<{
1318
+ providerToolCallId: string;
1319
+ name: string;
1320
+ args: JsonValue;
1321
+ toolCallId?: ToolCallId;
1322
+ title?: string;
1323
+ kind?: ToolKind;
1324
+ locations?: ToolCallLocation[];
1325
+ content?: ToolCallContent[];
1326
+ _meta?: JsonObject;
1327
+ }>;
1328
+ type ToolCommit = Readonly<{
1329
+ run: RunRecord;
1330
+ toolCall: ToolCallSnapshot;
1331
+ }>;
1332
+ type ToolBatchCommit = Readonly<{
1333
+ run: RunRecord;
1334
+ toolCalls: readonly ToolCallSnapshot[];
1335
+ }>;
1336
+ type EntryPhaseSpec = Readonly<{
1337
+ phase: string;
1338
+ payload?: JsonValue;
1339
+ }>;
1340
+ type RunRecord = Readonly<{
1341
+ id: RunId;
1342
+ agentId: AgentId;
1343
+ agentSequence: number;
1344
+ readySequence: number;
1345
+ revision: number;
1346
+ state: RunState;
1347
+ input: UserInput;
1348
+ scope?: ScopeRef;
1349
+ cwd?: string;
1350
+ initialMessageId?: MessageId;
1351
+ invalidatedBy?: Readonly<{
1352
+ messageId: MessageId;
1353
+ messageRevision: number;
1644
1354
  }>;
1645
- /** Route reason extracted from route tool call (for hooks to inspect) */
1646
- routeReason?: string;
1647
- /** Structured data from this phase, passed to the next phase */
1648
- payload?: unknown;
1649
- };
1650
- /** Phase machine state — tracks position and inter-phase data */
1651
- interface PhaseState {
1652
- current: string;
1653
- available: string[];
1654
- iterations: number;
1655
- payload?: unknown;
1656
- }
1657
- type PhaseInvocation = {
1658
- mode: "serial";
1659
- instanceId: string;
1660
- } | {
1661
- mode: "parallel";
1662
- instanceId: string;
1663
- groupId: string;
1664
- index: number;
1665
- count: number;
1666
- sourcePhaseId: string;
1667
- };
1668
- /** Durable identity of the Run execution currently invoking a Phase. */
1669
- type PhaseExecutionIdentity = Readonly<{
1670
- agentId: string;
1671
- runId: string;
1672
- executionId: string;
1673
- /** Original durable Run input, before any Phase-local interpretation. */
1674
- input?: UserContent;
1675
- /** Opaque metadata captured at the durable boundary; Rowan does not decode it. */
1676
- agentMetadata?: Readonly<Record<string, unknown>>;
1677
- runMetadata?: Readonly<Record<string, unknown>>;
1678
- scope?: _rowan_agent_models.ScopeRef;
1355
+ metadata?: Metadata;
1356
+ phasePayload?: JsonValue;
1357
+ entryPhases?: readonly EntryPhaseSpec[];
1358
+ pinnedConfigToken?: ConfigToken;
1359
+ checkpoint?: ExecutionCheckpoint;
1360
+ currentPhaseId?: string;
1361
+ openInteractions?: readonly RunInteraction[];
1362
+ interactionAnswers?: Readonly<Record<string, JsonValue>>;
1363
+ execution?: ExecutionToken;
1364
+ outcome?: Outcome$1;
1365
+ failure?: RunFailure;
1366
+ cancellationReason?: string;
1367
+ createdAt: string;
1368
+ updatedAt: string;
1369
+ }>;
1370
+ type MessageRevisionResult = Readonly<{
1371
+ message: UserMessage & Readonly<{
1372
+ messageRevision: number;
1373
+ }>;
1374
+ replacementRun: RunRecord;
1375
+ invalidatedRunIds: readonly RunId[];
1376
+ affectedToolCallIds: readonly ToolCallId[];
1377
+ effectDigest?: string;
1378
+ }>;
1379
+ type RetentionResult = Readonly<{
1380
+ deletedRunIds: readonly RunId[];
1381
+ deletedToolCallIds: readonly ToolCallId[];
1382
+ deletedEventCount: number;
1383
+ retentionFloor: EventCursor;
1384
+ skipped?: "active_consumers" | "no_eligible_events";
1385
+ }>;
1386
+ type AgentSummary = Readonly<{
1387
+ id: AgentId;
1388
+ metadata?: Metadata;
1389
+ currentConfigIdentity?: string;
1390
+ createdAt: string;
1391
+ activatedAt: string;
1392
+ updatedAt: string;
1393
+ }>;
1394
+ type RunSummary = Readonly<{
1395
+ id: RunId;
1396
+ agentId: AgentId;
1397
+ agentSequence: number;
1398
+ state: RunState;
1399
+ metadata?: Metadata;
1400
+ createdAt: string;
1401
+ updatedAt: string;
1402
+ }>;
1403
+ type Page<T, Cursor> = Readonly<{
1404
+ items: readonly T[];
1405
+ next?: Cursor;
1406
+ }>;
1407
+ type RunSnapshotBase = Readonly<{
1408
+ runId: RunId;
1409
+ agentId: AgentId;
1410
+ agentSequence: number;
1411
+ revision: number;
1412
+ input: UserInput;
1413
+ scope?: ScopeRef;
1679
1414
  cwd?: string;
1415
+ metadata?: Metadata;
1416
+ /** Effective entry Phase payload the Run started with (defaults filled). */
1417
+ phasePayload?: JsonValue;
1418
+ entryPhases?: readonly EntryPhaseSpec[];
1419
+ messageCount: number;
1420
+ toolCallCount: number;
1421
+ currentPhaseId?: string;
1422
+ createdAt: string;
1423
+ updatedAt: string;
1424
+ cursor: EventCursor;
1680
1425
  }>;
1681
- /** Everything a phase needs to execute */
1682
- interface PhaseContext {
1683
- systemPrompt: string;
1684
- messages: AgentMessage[];
1685
- /** Phase-filtered tools */
1686
- tools: Tool[];
1687
- /** Phase-filtered skills */
1688
- skills: Skill[];
1689
- /** Phase machine state */
1690
- state: PhaseState;
1691
- /** Identity and dispatch metadata for this phase execution */
1692
- readonly invocation: PhaseInvocation;
1693
- /** Durable Run identity for cross-store integrations and idempotent commands. */
1694
- readonly execution: PhaseExecutionIdentity;
1695
- /** Additional guideline bullets appended to the system prompt */
1696
- promptGuidelines?: string[];
1697
- /** Text to append after the system prompt */
1698
- appendSystemPrompt?: string;
1699
- }
1700
- /** JSON-safe structural defaults declared by a Phase's `input` mapping. */
1701
- type PhaseInput = Readonly<Record<string, JsonValue>>;
1702
- /** JSON-safe option metadata exposed to a host Settings surface. */
1703
- interface SettingsOption {
1704
- value: string;
1705
- label: string;
1706
- description?: string;
1707
- disabled?: boolean;
1708
- }
1709
- interface SettingsBadge {
1710
- label: string;
1711
- tone?: "neutral" | "success" | "review" | "danger";
1712
- }
1713
- interface SettingsItem {
1714
- id: string;
1715
- title: string;
1716
- description?: string;
1717
- badges?: readonly SettingsBadge[];
1718
- }
1719
- type SettingsControl = {
1720
- type: "boolean";
1721
- path: string;
1722
- label: string;
1723
- description?: string;
1724
- } | {
1725
- type: "number";
1726
- path: string;
1727
- label: string;
1728
- description?: string;
1729
- min?: number;
1730
- max?: number;
1731
- step?: number;
1732
- unit?: string;
1733
- scale?: number;
1426
+ type RunSnapshot = RunSnapshotBase & (Readonly<{
1427
+ state: "queued" | "running";
1428
+ currentPhaseId?: string;
1429
+ interactions?: readonly RunInteraction[];
1430
+ }> | Readonly<{
1431
+ state: "input_required";
1432
+ interactions: readonly RunInteraction[];
1433
+ answers: Readonly<Record<string, JsonValue>>;
1434
+ }> | Readonly<{
1435
+ state: "completed";
1436
+ outcome: Outcome$1;
1437
+ output?: AssistantMessage;
1438
+ }> | Readonly<{
1439
+ state: "failed";
1440
+ failure: RunFailure;
1441
+ }> | Readonly<{
1442
+ state: "cancelled";
1443
+ reason?: string;
1444
+ }>);
1445
+ type RunBoundary = Readonly<{
1446
+ type: "input_required";
1447
+ interactions: readonly RunInteraction[];
1448
+ answers: Readonly<Record<string, JsonValue>>;
1449
+ }> | Readonly<{
1450
+ type: "completed";
1451
+ outcome: Outcome$1;
1452
+ output?: AssistantMessage;
1453
+ }> | Readonly<{
1454
+ type: "failed";
1455
+ failure: RunFailure;
1456
+ }> | Readonly<{
1457
+ type: "cancelled";
1458
+ reason?: string;
1459
+ }>;
1460
+ type ConfigResolution = Readonly<{
1461
+ kind: "available";
1462
+ config: AgentConfiguration | ConfigurationSnapshot;
1734
1463
  } | {
1735
- type: "select";
1736
- path: string;
1737
- label: string;
1738
- description?: string;
1739
- options: readonly SettingsOption[];
1464
+ kind: "deferred";
1465
+ retryAfterMs?: number;
1740
1466
  } | {
1741
- type: "text";
1742
- path: string;
1743
- label: string;
1744
- description?: string;
1745
- placeholder?: string;
1746
- format?: "string" | "string-array" | "key-value";
1747
- multiline?: boolean;
1467
+ kind: "unavailable";
1468
+ reason: string;
1469
+ }>;
1470
+ type ConfigPutResult = Readonly<{
1471
+ kind: "stored";
1472
+ token: string;
1748
1473
  } | {
1749
- type: "collection";
1750
- path: string;
1751
- label: string;
1752
- description?: string;
1753
- items: readonly SettingsItem[];
1754
- fields: readonly SettingsControl[];
1755
- add?: {
1756
- label: string;
1757
- idLabel?: string;
1758
- fields: readonly SettingsControl[];
1759
- };
1760
- removeLabel?: string;
1761
- };
1762
- interface SettingsSection {
1763
- id: string;
1764
- title: string;
1765
- description?: string;
1766
- controls: readonly SettingsControl[];
1474
+ kind: "identity_conflict";
1475
+ }>;
1476
+ interface ConfigProvider {
1477
+ put(input: {
1478
+ agentId: AgentId;
1479
+ agentMetadata?: Metadata;
1480
+ config: AgentConfiguration | ConfigurationSnapshot;
1481
+ operationId: string;
1482
+ signal: AbortSignal;
1483
+ }): Promise<ConfigPutResult>;
1484
+ resolve(input: {
1485
+ agentId: AgentId;
1486
+ agentMetadata?: Metadata;
1487
+ token: ConfigToken;
1488
+ signal: AbortSignal;
1489
+ }): Promise<ConfigResolution>;
1490
+ }
1491
+ interface OwnedStore {
1492
+ readonly lease: OwnerLease;
1493
+ reserveAgent(input: {
1494
+ idempotencyKey: string;
1495
+ metadata?: Metadata;
1496
+ configIdentity?: string;
1497
+ historySeed?: HistorySeed;
1498
+ }): Promise<AgentRecord>;
1499
+ activateAgent(agentId: AgentId, configToken?: ConfigToken, configIdentity?: string): Promise<AgentRecord>;
1500
+ updateAgentConfigToken(input: {
1501
+ agentId: AgentId;
1502
+ token: ConfigToken;
1503
+ configIdentity?: string;
1504
+ idempotencyKey: string;
1505
+ }): Promise<AgentRecord>;
1506
+ deleteAgent(input: AgentDeletionRequest): Promise<void>;
1507
+ reviseMessage(input: {
1508
+ agentId: AgentId;
1509
+ messageId: MessageId;
1510
+ expectedMessageRevision: number;
1511
+ content: UserContent;
1512
+ operationId: string;
1513
+ effectDigestConfirmation?: string;
1514
+ }): Promise<MessageRevisionResult>;
1515
+ compact(input?: {
1516
+ now?: string;
1517
+ retentionMs?: number;
1518
+ }): Promise<RetentionResult>;
1519
+ contextStatus(agentId: AgentId, contextWindow: number): Promise<ContextStatus>;
1520
+ contextMessages(agentId: AgentId, recentTokenBudget?: number): Promise<readonly Message[]>;
1521
+ commitContextCompaction(record: ContextCompactionRecord): Promise<ContextCompactionRecord>;
1522
+ createRun(input: {
1523
+ agentId: AgentId;
1524
+ input: UserInput;
1525
+ metadata?: Metadata;
1526
+ scope?: ScopeRef;
1527
+ cwd?: string;
1528
+ phasePayload?: JsonValue;
1529
+ entryPhases?: readonly EntryPhaseSpec[];
1530
+ pinnedConfigToken?: ConfigToken;
1531
+ idempotencyKey: string;
1532
+ }): Promise<RunRecord>;
1533
+ claimRun(input: {
1534
+ runId: RunId;
1535
+ expectedRevision: number;
1536
+ executionId?: ExecutionId;
1537
+ messageId?: MessageId;
1538
+ configToken?: ConfigToken;
1539
+ additionalContexts?: readonly ContextCandidate[];
1540
+ }): Promise<RunClaim>;
1541
+ failQueuedRun(input: {
1542
+ runId: RunId;
1543
+ expectedRevision: number;
1544
+ failure: QueuedRunFailure;
1545
+ }): Promise<RunRecord>;
1546
+ commitPhaseEntered(input: {
1547
+ runId: RunId;
1548
+ execution: ExecutionToken;
1549
+ expectedRevision: number;
1550
+ phaseId: string;
1551
+ visit: number;
1552
+ }): Promise<RunRecord>;
1553
+ commitPhaseOutput(input: {
1554
+ runId: RunId;
1555
+ execution: ExecutionToken;
1556
+ expectedRevision: number;
1557
+ message: AssistantMessage;
1558
+ }): Promise<RunRecord>;
1559
+ commitInputRequired(input: {
1560
+ runId: RunId;
1561
+ execution: ExecutionToken;
1562
+ expectedRevision: number;
1563
+ phase: string;
1564
+ prompt?: AssistantMessage;
1565
+ checkpoint: ExecutionCheckpoint;
1566
+ interactions?: readonly RunInteraction[];
1567
+ interactionAnswers?: Readonly<Record<string, JsonValue>>;
1568
+ pendingToolCallIds?: readonly ToolCallId[];
1569
+ }): Promise<RunRecord>;
1570
+ answerInteraction(input: {
1571
+ runId: RunId;
1572
+ interactionId: string;
1573
+ expectedRevision: number;
1574
+ input?: JsonValue;
1575
+ cancel?: boolean;
1576
+ }): Promise<RunRecord>;
1577
+ commitOutcome(input: {
1578
+ runId: RunId;
1579
+ execution: ExecutionToken;
1580
+ expectedRevision: number;
1581
+ outcome?: Outcome$1;
1582
+ failure?: RunFailure;
1583
+ output?: AssistantMessage;
1584
+ }): Promise<RunRecord>;
1585
+ reserveToolCall(input: {
1586
+ runId: RunId;
1587
+ execution: ExecutionToken;
1588
+ expectedRevision: number;
1589
+ requestMessageId: MessageId;
1590
+ name: string;
1591
+ args: JsonValue;
1592
+ toolCallId?: ToolCallId;
1593
+ providerToolCallId?: string;
1594
+ title?: string;
1595
+ kind?: ToolKind;
1596
+ locations?: ToolCallLocation[];
1597
+ content?: ToolCallContent[];
1598
+ _meta?: JsonObject;
1599
+ model?: ModelRef;
1600
+ usage?: LlmTokenUsage;
1601
+ }): Promise<ToolCommit>;
1602
+ reserveToolCalls(input: {
1603
+ runId: RunId;
1604
+ execution: ExecutionToken;
1605
+ expectedRevision: number;
1606
+ requestMessageId: MessageId;
1607
+ calls: readonly ToolCallReservation[];
1608
+ /** The model response's blocks, so the request message keeps what preceded the Tool Calls. */
1609
+ contentBlocks?: readonly ContentBlock[];
1610
+ model?: ModelRef;
1611
+ usage?: LlmTokenUsage;
1612
+ }): Promise<ToolBatchCommit>;
1613
+ startToolCall(input: {
1614
+ runId: RunId;
1615
+ execution: ExecutionToken;
1616
+ expectedRevision: number;
1617
+ toolCallId: ToolCallId;
1618
+ title?: string;
1619
+ kind?: ToolKind;
1620
+ locations?: ToolCallLocation[];
1621
+ content?: ToolCallContent[];
1622
+ _meta?: JsonObject;
1623
+ }): Promise<ToolCommit>;
1624
+ suspendToolCall(input: {
1625
+ runId: RunId;
1626
+ execution: ExecutionToken;
1627
+ expectedRevision: number;
1628
+ toolCallId: ToolCallId;
1629
+ }): Promise<ToolCommit>;
1630
+ commitToolResult(input: {
1631
+ runId: RunId;
1632
+ execution: ExecutionToken;
1633
+ expectedRevision: number;
1634
+ toolCallId: ToolCallId;
1635
+ result: ToolExecutionResult;
1636
+ state: "completed" | "failed" | "indeterminate";
1637
+ reason?: string;
1638
+ title?: string;
1639
+ kind?: ToolKind;
1640
+ content?: ToolCallContent[];
1641
+ locations?: ToolCallLocation[];
1642
+ rawOutput?: JsonValue;
1643
+ _meta?: JsonObject;
1644
+ }): Promise<ToolCommit>;
1645
+ cancelRun(input: {
1646
+ runId: RunId;
1647
+ expectedRevision?: number;
1648
+ reason?: string;
1649
+ output?: AssistantMessage;
1650
+ }): Promise<RunRecord>;
1651
+ recordToolCall(input: {
1652
+ runId: RunId;
1653
+ execution?: ExecutionToken;
1654
+ update: ToolCall$1 | ToolCallUpdate;
1655
+ external?: boolean;
1656
+ contentIndex?: number;
1657
+ }): Promise<DurableRunEvent>;
1658
+ snapshotRun(runId: RunId): Promise<RunSnapshot>;
1659
+ history(agentId: AgentId): Promise<readonly Message[]>;
1660
+ listAgents(): Promise<readonly AgentRecord[]>;
1661
+ listRuns(input?: {
1662
+ agentId?: AgentId;
1663
+ states?: readonly RunState[];
1664
+ }): Promise<readonly RunRecord[]>;
1665
+ listEvents(input?: {
1666
+ after?: EventCursor;
1667
+ }): Promise<readonly DurableRunEvent[]>;
1668
+ openConsumer(consumerId: string): Promise<ConsumerRegistration>;
1669
+ advanceConsumerCheckpoint(input: {
1670
+ consumerId: string;
1671
+ cursor: EventCursor;
1672
+ }): Promise<void>;
1673
+ renewOwner(leaseMs: number): Promise<OwnerLease>;
1674
+ sealAndReleaseOwner(): Promise<void>;
1767
1675
  }
1768
- /** Declarative, host-neutral Settings surface. */
1769
- interface SettingsDefinition {
1770
- description?: string;
1771
- sections: readonly SettingsSection[];
1676
+ interface DurableStore {
1677
+ openOwner(input: {
1678
+ ownerId: string;
1679
+ leaseMs: number;
1680
+ }): Promise<OwnedStore>;
1772
1681
  }
1773
- /**
1774
- * Loaded Phase object
1775
- */
1776
- interface Phase {
1777
- /** Unique phase identity and display name. */
1778
- name: string;
1779
- /** Rowan-owned built-in Phase; built-ins are never filtered or disabled. */
1780
- core?: boolean;
1781
- /** Description */
1782
- description: string;
1783
- /** Restricted tools (undefined = all tools available) */
1784
- tools?: string[];
1785
- /** Skills bundled directly inside this phase directory. Inline phases may omit this (equivalent to []). */
1786
- skills?: Skill[];
1787
- /** Forced next phase */
1788
- target?: string;
1789
- /** Additional system-prompt guidance while this Phase is in the auto route catalog. */
1790
- promptGuidelines?: string[];
1791
- /** Structural JSON-safe input defaults */
1792
- input?: PhaseInput;
1793
- /** If true, phase gets a fresh context when executed in parallel */
1794
- isolated?: boolean;
1795
- /** Path to PHASE.md file */
1796
- filePath: string;
1797
- /** Phase directory path */
1798
- baseDir: string;
1799
- /** PHASE.md body content */
1800
- content: string;
1801
- /** Model override for this phase (resolved from frontmatter) */
1802
- model?: ModelRef;
1803
- /** Do not automatically inject this Phase into the model route catalog/context. */
1804
- disableAutoInvocation?: boolean;
1805
- /** Do not expose this Phase to direct user invocation. */
1806
- disableImplicitInvocation?: boolean;
1807
- /** ExtensionAPI factory function used for registration or programmatic execution. */
1808
- factory?: (api: ExtensionAPI) => Promise<void>;
1809
- /** Direct run function */
1810
- run?: (context: PhaseContext, execution: PhaseExecution) => Promise<PhaseOutput | void>;
1682
+ type AgentRuntimeOptions = Readonly<{
1683
+ store: DurableStore;
1684
+ configs?: ConfigProvider;
1685
+ concurrency?: number;
1686
+ bootstrap?: (registry: RuntimeBootstrapRegistry) => void | Promise<void>;
1687
+ host?: ExtensionHost;
1688
+ sessionFiles?: Readonly<{
1689
+ dir: string;
1690
+ }>;
1691
+ /** @internal Private / testing parameter to override retry delay */
1692
+ retryDelayMs?: number;
1693
+ }>;
1694
+ type DurableConsumer = Readonly<{
1695
+ caughtUp: Promise<void>;
1696
+ done: Promise<void>;
1697
+ stop(): void;
1698
+ }>;
1699
+ interface AgentRun {
1700
+ readonly id: RunId;
1701
+ snapshot(): Promise<RunSnapshot>;
1702
+ observe(options?: {
1703
+ after?: EventCursor;
1704
+ signal?: AbortSignal;
1705
+ }): AsyncIterable<RunEvent>;
1706
+ wait(options?: {
1707
+ signal?: AbortSignal;
1708
+ }): Promise<RunBoundary>;
1709
+ respondInteraction(input: {
1710
+ interactionId: string;
1711
+ input?: JsonValue;
1712
+ cancel?: boolean;
1713
+ }): Promise<void>;
1714
+ cancel(reason?: string): Promise<RunBoundary>;
1811
1715
  }
1812
- /**
1813
- * Phase registry containing all loaded phases
1814
- */
1815
- interface PhaseRegistry {
1816
- /** Map of phase name to Phase object */
1817
- phases: Map<string, Phase>;
1818
- /** Entry phase name (null until Agent applies its default phase) */
1819
- entryPhaseId: string | null;
1716
+ interface AgentRuntime$1 {
1717
+ readonly host: ExtensionHost;
1718
+ loadAgents(input: LoadInput<AgentDefinition>): Promise<LoadResult>;
1719
+ loadSkills(input: LoadInput<Skill>): Promise<LoadResult>;
1720
+ loadPhases(input: LoadInput<Phase>): Promise<LoadResult>;
1721
+ loadTools(input: Readonly<{
1722
+ sourceId: string;
1723
+ values: readonly Tool$1[];
1724
+ }>): Promise<LoadResult>;
1725
+ unload(input: Readonly<{
1726
+ kind: ResourceKind;
1727
+ sourceId: string;
1728
+ }>): Promise<LoadResult>;
1729
+ createAgent(config: AgentConfiguration, options?: {
1730
+ idempotencyKey?: string;
1731
+ metadata?: Metadata;
1732
+ historySeed?: HistorySeed;
1733
+ }): Promise<AgentId>;
1734
+ updateAgentConfig(agentId: AgentId, config: AgentConfiguration, options: {
1735
+ idempotencyKey: string;
1736
+ }): Promise<void>;
1737
+ deleteAgent(input: AgentDeletionRequest): Promise<void>;
1738
+ revise(agentId: AgentId, input: {
1739
+ messageId: MessageId;
1740
+ expectedMessageRevision: number;
1741
+ content: UserContent;
1742
+ operationId: string;
1743
+ effectDigestConfirmation?: string;
1744
+ }): Promise<MessageRevisionResult>;
1745
+ compact(input?: {
1746
+ now?: string;
1747
+ retentionMs?: number;
1748
+ }): Promise<RetentionResult>;
1749
+ start(agentId: AgentId, input: UserInput, options: {
1750
+ idempotencyKey: string;
1751
+ metadata?: Metadata;
1752
+ scope?: ScopeRef;
1753
+ cwd?: string;
1754
+ phasePayload?: JsonValue;
1755
+ entryPhases?: ReadonlyArray<EntryPhaseSpec>;
1756
+ }): Promise<AgentRun>;
1757
+ run(runId: RunId): AgentRun;
1758
+ contextStatus(agentId: AgentId, options?: {
1759
+ contextWindow?: number;
1760
+ }): Promise<ContextStatus>;
1761
+ compactContext(agentId: AgentId, options?: {
1762
+ input?: UserInput;
1763
+ instructions?: string;
1764
+ idempotencyKey?: string;
1765
+ }): Promise<AgentRun>;
1766
+ runPhase(agentId: AgentId, options: {
1767
+ phase: string;
1768
+ payload?: JsonValue;
1769
+ input?: UserInput;
1770
+ yieldToInput?: boolean;
1771
+ idempotencyKey?: string;
1772
+ }): Promise<AgentRun>;
1773
+ listInvocations(agentId: AgentId, options: {
1774
+ source: InvocationSource;
1775
+ }): Promise<readonly InvocationCatalogEntry[]>;
1776
+ history(agentId: AgentId): Promise<readonly Message[]>;
1777
+ listAgents(input?: {
1778
+ after?: AgentListCursor;
1779
+ limit?: number;
1780
+ }): Promise<Page<AgentSummary, AgentListCursor>>;
1781
+ listRuns(input?: {
1782
+ agentId?: AgentId;
1783
+ states?: readonly RunState[];
1784
+ after?: RunListCursor;
1785
+ limit?: number;
1786
+ }): Promise<Page<RunSummary, RunListCursor>>;
1787
+ consume(input: {
1788
+ consumerId: string;
1789
+ signal: AbortSignal;
1790
+ onEvent(event: DurableRunEvent, context: Readonly<{
1791
+ signal: AbortSignal;
1792
+ }>): void | Promise<void>;
1793
+ }): Promise<DurableConsumer>;
1794
+ listCapabilities(): readonly ExtensionCapability[];
1795
+ onCapabilitiesChanged(listener: (capabilities: readonly ExtensionCapability[]) => void): () => void;
1796
+ triggerUiAction(event: {
1797
+ contributionId: string;
1798
+ actionId: string;
1799
+ scope?: ScopeRef;
1800
+ }): void;
1801
+ close(): Promise<void>;
1820
1802
  }
1803
+ type ConsumerRegistration = Readonly<{
1804
+ cursor?: EventCursor;
1805
+ waterline: EventCursor;
1806
+ }>;
1821
1807
 
1822
1808
  interface BeforePhaseEvent {
1823
1809
  type: "before_phase";
@@ -1847,6 +1833,7 @@ interface BeforeToolCallEvent {
1847
1833
  readonly answer?: unknown;
1848
1834
  readonly scope?: ScopeRef;
1849
1835
  readonly turn?: JsonObject;
1836
+ readonly phase?: ToolCallPhase;
1850
1837
  }
1851
1838
  interface AfterToolCallEvent {
1852
1839
  type: "after_tool_call";
@@ -1858,6 +1845,7 @@ interface AfterToolCallEvent {
1858
1845
  readonly metadata?: Readonly<Record<string, unknown>>;
1859
1846
  readonly scope?: ScopeRef;
1860
1847
  readonly turn?: JsonObject;
1848
+ readonly phase?: ToolCallPhase;
1861
1849
  }
1862
1850
  interface RunStartEvent {
1863
1851
  type: "run_start";
@@ -3408,4 +3396,4 @@ declare function parseFrontmatter<T = Record<string, unknown>>(raw: string): Fro
3408
3396
 
3409
3397
  declare function createCoreTools(input?: CoreToolContext): Tool$1[];
3410
3398
 
3411
- 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 EntryPhaseSpec, type EventCursor, type EventId, type ExecutionCheckpoint, type ExecutionId, type ExecutionToken, type ExtensionAPI, type ExtensionActivationError, type ExtensionActivationResult, type ExtensionCapability, type ExtensionCapabilityContribution, type ExtensionContribution, type ExtensionDisposer, type ExtensionFactory, type ExtensionFactoryResult, type ExtensionHost, ExtensionLifetimeError, type ExtensionLifetimeErrorCode, type ExtensionLoadInput, type ExtensionStateStore, type ExtensionToolContribution, type FrontmatterResult, type HistorySeed, type HookEvent, type HookEventType, type HookHandler, type HostApiExtension, InMemoryConfigProvider, InMemoryExtensionHost, InMemoryStore, type InteractionRecord, type InternalModelLoopOptions, type InvocationCatalogEntry, type InvocationSource, type JsonObject, type JsonPrimitive, type JsonValue, type LiveInteractionEvent, 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 ModelInvokeOutput, type ModelRetry, type OpaqueId, type Outcome$1 as 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 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 RunEndEvent, 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 RunStartEvent, type RunState, type RunStateChanged, type RunSummary, RuntimeBootstrapRegistry, RuntimeError, type RuntimeErrorCode, type RuntimeErrorDetails, RuntimeExtensionLifetime, STOP_PHASE_ID, type SettingsBadge, type SettingsControl, type SettingsDefinition, type SettingsItem, type SettingsOption, type SettingsSection, type Skill, type SkillRegistration, SqliteStore, type TextContent, type ThinkingContent, type ThinkingDelta, type Tool$1 as Tool, type ToolCallContext, type ToolCallDelta, type ToolCallId, type ToolCallPresentationInput, type ToolCallPresentationOutput, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, type WithdrawnUserInput, brandConfigToken, createCompactPhase, createCorePhases, createCoreTools, createDefaultPhase, createStopPhase, extensionSourceId, isConfigurationSnapshot, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhases, loadSkill, loadSkills, mergeToolCall, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };
3399
+ 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 EntryPhaseSpec, type EventCursor, type EventId, type ExecutionCheckpoint, type ExecutionId, type ExecutionToken, type ExtensionAPI, type ExtensionActivationError, type ExtensionActivationResult, type ExtensionCapability, type ExtensionCapabilityContribution, type ExtensionContribution, type ExtensionDisposer, type ExtensionFactory, type ExtensionFactoryResult, type ExtensionHost, ExtensionLifetimeError, type ExtensionLifetimeErrorCode, type ExtensionLoadInput, type ExtensionStateStore, type ExtensionToolContribution, type FrontmatterResult, type HistorySeed, type HookEvent, type HookEventType, type HookHandler, type HostApiExtension, InMemoryConfigProvider, InMemoryExtensionHost, InMemoryStore, type InteractionRecord, type InternalModelLoopOptions, type InvocationCatalogEntry, type InvocationSource, type JsonObject, type JsonPrimitive, type JsonValue, type LiveInteractionEvent, 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 ModelInvokeOutput, type ModelRetry, type OpaqueId, type Outcome$1 as 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 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 RunEndEvent, 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 RunStartEvent, type RunState, type RunStateChanged, type RunSummary, RuntimeBootstrapRegistry, RuntimeError, type RuntimeErrorCode, type RuntimeErrorDetails, RuntimeExtensionLifetime, STOP_PHASE_ID, type SettingsBadge, type SettingsControl, type SettingsDefinition, type SettingsItem, type SettingsOption, type SettingsSection, type Skill, type SkillRegistration, SqliteStore, type TextContent, type ThinkingContent, type ThinkingDelta, type Tool$1 as Tool, type ToolCallContext, type ToolCallDelta, type ToolCallId, type ToolCallPhase, type ToolCallPresentationInput, type ToolCallPresentationOutput, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, type WithdrawnUserInput, brandConfigToken, createCompactPhase, createCorePhases, createCoreTools, createDefaultPhase, createStopPhase, extensionSourceId, isConfigurationSnapshot, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhases, loadSkill, loadSkills, mergeToolCall, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };