@rowan-agent/agent 0.4.11 → 0.5.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.
package/README.md CHANGED
@@ -50,6 +50,11 @@ class Agent {
50
50
  waitForIdle(): Promise<void>;
51
51
  flushEvents(): Promise<void>;
52
52
  readonly status: AgentStatus;
53
+
54
+ // Resource loading — replaces standalone loadSkills/loadPhases/loadExtensions
55
+ static loadSkills(targetPath: string): Promise<Skill[]>;
56
+ static loadPhases(targetPath: string): Promise<PhaseRegistry>;
57
+ static loadExtensions(targetPath: string): Promise<LoadExtensionsResult>;
53
58
  }
54
59
  ```
55
60
 
@@ -60,12 +65,8 @@ type AgentOptions = {
60
65
  context: AgentContext;
61
66
  model: LlmModelRef;
62
67
  stream: StreamFn;
63
- cwd?: string;
64
- rowanDir?: string; // project-local Rowan directory, default: ".rowan"
68
+ extensions?: LoadedExtension[];
65
69
  sessionId?: string;
66
- phases?: PhaseRegistry;
67
- extensions?: ExtensionRunnerRef;
68
- signal?: AbortSignal;
69
70
  maxAttempts?: number;
70
71
 
71
72
  // Lifecycle hooks
@@ -99,6 +100,8 @@ type AgentContext = {
99
100
  messages: AgentMessage[];
100
101
  tools: Tool[];
101
102
  skills: Skill[];
103
+ // Optional custom phases; Agent merges them with its built-in "default" phase.
104
+ phases?: PhaseRegistry;
102
105
  };
103
106
  ```
104
107
 
@@ -239,12 +242,9 @@ await session.branch(entryId);
239
242
  Skills are `SKILL.md` knowledge bundles that get injected into the agent context, extending its domain knowledge without changing code.
240
243
 
241
244
  ```ts
242
- import { loadSkill, loadSkills, resolveSkillPath } from "@rowan-agent/agent";
245
+ import { Agent } from "@rowan-agent/agent";
243
246
 
244
- const skills = await loadSkills(workspace);
245
- const skill = await loadSkill(path, workspace);
246
- const path = resolveSkillPath("example", workspace);
247
- // → <rowanDir>/skills/example/SKILL.md
247
+ const skills = await Agent.loadSkills("/User/Skills");
248
248
  ```
249
249
 
250
250
  ## Phases
@@ -257,7 +257,7 @@ Each phase's `PHASE.md` content is injected as a system message, giving the LLM
257
257
 
258
258
  ```
259
259
  Per iteration:
260
- 1. Hot-reload phase configs from disk (PHASE.md)
260
+ 1. Read Agent-normalized `context.phases`
261
261
  2. Inject phase instructions as system message
262
262
  3. Execute phase (factory | run | LLM fallback)
263
263
  4. Extract routing decision from route tool call
@@ -402,15 +402,17 @@ Each target gets a forked copy of the current messages (or empty if `isolated: t
402
402
  The extension system lets plugins register lifecycle hooks, tools, phases, model providers, and cross-plugin events. Plugins are discovered from `<workspace>/.rowan/extensions`.
403
403
 
404
404
  ```ts
405
- import { createExtensionRunner, discoverAndLoadExtensions } from "@rowan-agent/agent";
405
+ import { Agent } from "@rowan-agent/agent";
406
406
 
407
- const { extensions } = await discoverAndLoadExtensions(cwd);
408
- const runner = createExtensionRunner({ cwd });
409
- await runner.loadExtensions(extensions);
407
+ const { extensions } = await Agent.loadExtensions(`${cwd}/.rowan/extensions`);
408
+ // Pass extensions to the Agent constructor — they are loaded and bound internally
409
+ const agent = new Agent({ context, model, stream, extensions });
410
410
  ```
411
411
 
412
412
  ### ExtensionRunner
413
413
 
414
+ `ExtensionRunner` is used internally by Agent when extensions are passed via the constructor or `run()`. The Agent manages the runner lifecycle — load, bind, invalidate — automatically.
415
+
414
416
  ```ts
415
417
  class ExtensionRunner {
416
418
  readonly hooks: HooksManager; // 19 lifecycle hook types
@@ -462,7 +464,7 @@ export default function myPlugin(rowan: ExtensionAPI) {
462
464
 
463
465
  Multi-provider model configuration via `.rowan/config.yaml`. Supports multiple API providers, per-model settings, environment variable interpolation, and per-phase model overrides.
464
466
 
465
- Config is loaded from the runtime Rowan directory, which defaults to `.rowan` and can be set when constructing `Agent` via `rowanDir`.
467
+ Config is loaded from the runtime Rowan directory, which defaults to `.rowan`.
466
468
 
467
469
  ### Config File
468
470
 
@@ -636,13 +638,13 @@ const request = buildModelRequest({ systemPrompt, messages, tools });
636
638
 
637
639
  ## Workspace
638
640
 
639
- Workspace resolution uses the current project for both source and binary runs. The project Rowan directory defaults to `<cwd>/.rowan`; pass `rowanDir` to resolve another project-local directory.
641
+ Workspace resolution uses the current project root. The project Rowan directory defaults to `<cwd>/.rowan`; pass `rowanDir` to resolve another project-local directory.
640
642
 
641
643
  ```ts
642
644
  import { resolveWorkspacePaths, resolveInWorkspace } from "@rowan-agent/agent";
643
645
 
644
646
  const workspace = resolveWorkspacePaths();
645
- // → { mode: "source" | "binary", cwd: string, rowanDir: string }
647
+ // → { cwd: string, rowanDir: string }
646
648
 
647
649
  const custom = resolveWorkspacePaths({ rowanDir: ".rowan-project" });
648
650
  // → custom.rowanDir is <cwd>/.rowan-project
@@ -666,7 +668,7 @@ type LoopMetrics = {
666
668
  | Type | Description |
667
669
  |------|-------------|
668
670
  | `Agent` | Main agent facade |
669
- | `AgentContext` | System prompt, messages, tools, skills |
671
+ | `AgentContext` | System prompt, messages, tools, skills, phases |
670
672
  | `AgentMessage` | Typed message with role, content, metadata |
671
673
  | `AgentEvent` | Discriminated union of 13 event types |
672
674
  | `Tool` / `ToolResult` | Tool definition and execution result |
@@ -694,4 +696,4 @@ type LoopMetrics = {
694
696
 
695
697
  ## Version
696
698
 
697
- Current version: **0.4.6**
699
+ Current version: **0.4.11**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _rowan_agent_models from '@rowan-agent/models';
2
- import { LlmRequest, LlmResponse, LlmModelRef, LlmModelUsage, StreamFn, AgentEventListener, ToolCall, ToolResult, AgentMessage, Outcome, Skill as Skill$1, ContentBlock, ProviderConfig, Protocol, ModelCost, AgentEvent, LlmMessage } from '@rowan-agent/models';
2
+ import { LlmRequest, LlmResponse, LlmModelRef, LlmModelUsage, AgentMessage, Skill as Skill$1, ToolResult, Outcome, ContentBlock, ToolCall, ProviderConfig, StreamFn, AgentEventListener, Protocol, ModelCost, AgentEvent, LlmMessage } from '@rowan-agent/models';
3
3
  export { AgentEvent, AgentEventListener, AgentMessage, LlmModelRef, Outcome, Skill, StreamFn, ToolResult, createDispatchStream, registerBuiltInApiProviders } from '@rowan-agent/models';
4
4
  import Type from 'typebox';
5
5
 
@@ -23,9 +23,6 @@ type ModelTranscript = {
23
23
  response: LlmResponse;
24
24
  };
25
25
 
26
- type BeforePhaseHook = (phaseId: string, input: PhaseContext) => Promise<BeforePhaseHookResult>;
27
- type AfterPhaseHook = (phaseId: string, output: PhaseOutput) => Promise<AfterPhaseHookResult>;
28
- type BeforePromptHook = (phaseId: string, input: PhaseContext) => Promise<PhaseContext>;
29
26
  type LoopMetrics = {
30
27
  /** Number of phase iterations executed. */
31
28
  iterations: number;
@@ -54,37 +51,6 @@ type SessionState = {
54
51
  metrics: LoopMetrics;
55
52
  status: "idle" | "running" | "completed" | "aborted" | "failed";
56
53
  };
57
- type AgentConfig = {
58
- context: AgentContext;
59
- sessionId?: string;
60
- model: LlmModelRef;
61
- stream: StreamFn;
62
- signal?: AbortSignal;
63
- emit?: AgentEventListener;
64
- phases?: PhaseRegistry;
65
- runtime?: AgentRuntimePort;
66
- beforeToolCall?: BeforeToolCall;
67
- afterToolCall?: AfterToolCall;
68
- beforePhase?: BeforePhaseHook;
69
- afterPhase?: AfterPhaseHook;
70
- beforePrompt?: BeforePromptHook;
71
- maxAttempts?: number;
72
- onModelTranscript?: (transcript: ModelTranscript, meta: {
73
- phase: string;
74
- model: LlmModelRef;
75
- }) => Promise<void>;
76
- onMessage?: (message: AgentMessage) => Promise<void>;
77
- onOutcome?: (outcome: Outcome) => Promise<void>;
78
- sessionState?: SessionState;
79
- };
80
- type ToolRunnerInput = {
81
- config: AgentConfig;
82
- toolCall: ToolCall;
83
- };
84
- type ToolRunner = (input: ToolRunnerInput) => Promise<ToolResult>;
85
- type AgentRuntimePort = {
86
- tools?: ToolRunner;
87
- };
88
54
 
89
55
  type ToolContext = Pick<AgentContext, "skills"> & {
90
56
  toolCallId: string;
@@ -112,6 +78,8 @@ type AgentContext = {
112
78
  tools: Tool[];
113
79
  /** Skills available for this run. */
114
80
  skills: Skill$1[];
81
+ /** Custom phases for this run. Agent normalizes this with the built-in default phase. */
82
+ phases?: PhaseRegistry;
115
83
  };
116
84
  type BeforeToolCall = (input: {
117
85
  tool: Tool;
@@ -238,7 +206,7 @@ interface Phase {
238
206
  interface PhaseRegistry {
239
207
  /** Map of phase id to Phase object */
240
208
  phases: Map<string, Phase>;
241
- /** Entry phase id (null if no phases defined) */
209
+ /** Entry phase id (null until Agent applies its default phase) */
242
210
  entryPhaseId: string | null;
243
211
  }
244
212
 
@@ -387,10 +355,8 @@ type HandlerFn = (...args: unknown[]) => Promise<unknown>;
387
355
  * Tracks what each extension registered for attribution and cleanup.
388
356
  */
389
357
  interface Extension {
390
- /** Extension path (may be synthetic like `<builtin:phase:chat>`) */
358
+ /** Extension path (may be synthetic like `<inline>`) */
391
359
  path: string;
392
- /** Resolved absolute path */
393
- resolvedPath: string;
394
360
  /** Source info for error messages */
395
361
  sourceInfo: SourceInfo;
396
362
  /** Event handlers registered by this extension */
@@ -403,7 +369,7 @@ interface Extension {
403
369
  /**
404
370
  * Create an Extension object with empty collections.
405
371
  */
406
- declare function createExtension(extensionPath: string, resolvedPath: string, sourceInfo: SourceInfo): Extension;
372
+ declare function createExtension(extensionPath: string, sourceInfo: SourceInfo): Extension;
407
373
  /**
408
374
  * Shared runtime state created by loader, used during registration and runtime.
409
375
  * All ExtensionAPI instances reference this shared state.
@@ -459,7 +425,6 @@ type LoadExtensionsResult = {
459
425
  */
460
426
  interface LoadedExtension {
461
427
  path: string;
462
- resolvedPath: string;
463
428
  name: string;
464
429
  factory: ExtensionFactory;
465
430
  manifest?: ExtensionManifest;
@@ -1342,48 +1307,11 @@ declare class ExtensionRunner {
1342
1307
  }
1343
1308
  declare function createExtensionRunner(options?: ExtensionRunnerOptions): ExtensionRunner;
1344
1309
 
1345
- /**
1346
- * Extension loader — discovers and loads extensions from the filesystem.
1347
- *
1348
- * Uses the new LoadedExtension type that works with ExtensionRunner.
1349
- */
1350
-
1351
- /**
1352
- * Load a single extension from a factory function.
1353
- */
1354
- declare function loadExtensionFromFactory(factory: ExtensionFactory, cwd: string, extensionPath?: string): LoadedExtension;
1355
- /**
1356
- * Load extensions from file paths.
1357
- */
1358
- declare function loadExtensions(paths: string[], cwd: string): Promise<{
1359
- extensions: LoadedExtension[];
1360
- errors: Array<{
1361
- path: string;
1362
- error: string;
1363
- }>;
1364
- }>;
1365
- /**
1366
- * Discover and load extensions from .rowan/extensions directory.
1367
- */
1368
- declare function discoverAndLoadExtensions(cwd: string): Promise<{
1369
- extensions: LoadedExtension[];
1370
- errors: Array<{
1371
- path: string;
1372
- error: string;
1373
- }>;
1374
- }>;
1375
-
1376
- type ExtensionRunnerRef = {
1377
- current?: ExtensionRunner;
1378
- };
1379
1310
  type AgentOptions = {
1380
1311
  context: AgentContext;
1381
1312
  model: LlmModelRef;
1382
1313
  stream: StreamFn;
1383
- cwd?: string;
1384
- rowanDir?: string;
1385
- phases?: PhaseRegistry;
1386
- extensionRunnerRef?: ExtensionRunnerRef;
1314
+ extensions?: LoadedExtension[];
1387
1315
  sessionId?: string;
1388
1316
  maxAttempts?: number;
1389
1317
  beforeToolCall?: BeforeToolCall;
@@ -1395,7 +1323,7 @@ type AgentOptions = {
1395
1323
  model: LlmModelRef;
1396
1324
  }) => Promise<void>;
1397
1325
  };
1398
- type RunOptions = Partial<AgentConfig> & Pick<AgentConfig, "context">;
1326
+ type RunOptions = Partial<AgentOptions>;
1399
1327
  type AgentStatus = {
1400
1328
  sessionId?: string;
1401
1329
  context: AgentContext;
@@ -1412,6 +1340,11 @@ declare class Agent {
1412
1340
  private readonly pendingListenerTasks;
1413
1341
  private readonly listenerErrors;
1414
1342
  private activeRun?;
1343
+ private extensionRunner?;
1344
+ private loadedExtensions?;
1345
+ static loadSkills(targetPath: string): Promise<AgentContext["skills"]>;
1346
+ static loadPhases(targetPath: string): Promise<PhaseRegistry>;
1347
+ static loadExtensions(targetPath: string): Promise<LoadExtensionsResult>;
1415
1348
  constructor(options: AgentOptions);
1416
1349
  subscribe(listener: AgentEventListener): Unsubscribe;
1417
1350
  private emitToListeners;
@@ -1443,16 +1376,9 @@ declare class Agent {
1443
1376
  */
1444
1377
  private handleBeforePrompt;
1445
1378
  private handleRunFailure;
1446
- /**
1447
- * Discover and load phases and skills from the workspace.
1448
- *
1449
- * - Auto-discovers file-based phases from .rowan/phases/
1450
- * - Auto-discovers skills from .rowan/skills/
1451
- * - Merges with CLI-provided phases and skills
1452
- */
1453
- private discoverResources;
1454
1379
  private runWithLifecycle;
1455
1380
  private finishRun;
1381
+ private loadExtensions;
1456
1382
  run(config?: RunOptions): Promise<RunResult>;
1457
1383
  abort(reason?: string): void;
1458
1384
  /**
@@ -1688,28 +1614,19 @@ type CoreToolContext = {
1688
1614
  };
1689
1615
  declare function createCoreTools(input?: CoreToolContext): Tool[];
1690
1616
 
1691
- type RuntimeMode = "source" | "binary";
1692
1617
  type WorkspacePaths = {
1693
- mode: RuntimeMode;
1694
1618
  cwd: string;
1695
1619
  rowanDir: string;
1696
1620
  };
1697
1621
  type ResolveWorkspaceOptions = {
1698
1622
  cwd?: string;
1699
1623
  env?: NodeJS.ProcessEnv;
1700
- execPath?: string;
1701
- entrypoint?: string;
1702
1624
  homeDir?: string;
1703
- mode?: RuntimeMode;
1704
1625
  rowanDir?: string;
1705
1626
  };
1706
1627
  declare function resolveWorkspacePaths(options?: ResolveWorkspaceOptions): WorkspacePaths;
1707
1628
  declare function resolveInWorkspace(path: string, rootOrPaths: string | Pick<WorkspacePaths, "cwd">): string;
1708
1629
 
1709
- declare function resolveSkillPath(input: string, workspace?: WorkspacePaths): string;
1710
- declare function loadSkill(path: string, workspace?: WorkspacePaths): Promise<Skill$1>;
1711
- declare function loadSkills(workspace?: WorkspacePaths, paths?: string[]): Promise<Skill$1[]>;
1712
-
1713
1630
  type ModelConfigFromFile = {
1714
1631
  id: string;
1715
1632
  name?: string;
@@ -1776,18 +1693,6 @@ declare class AgentEventStream extends EventStream<AgentEvent, AgentMessage[]> {
1776
1693
  constructor();
1777
1694
  }
1778
1695
 
1779
- /**
1780
- * Load all phases from .rowan/phases directory.
1781
- *
1782
- * Scans for subdirectories containing PHASE.md files.
1783
- * Returns PhaseRegistry with entryPhaseId:
1784
- * - null by default (caller must explicitly set to start from a specific phase)
1785
- * - Set to a specific phase id to start from that phase
1786
- *
1787
- * When entryPhaseId is null, AgentLoop starts from "none" phase.
1788
- */
1789
- declare function loadPhases(workspace?: WorkspacePaths, paths?: string[]): Promise<PhaseRegistry>;
1790
-
1791
1696
  interface SystemPromptOptions {
1792
1697
  /** Base system prompt. */
1793
1698
  systemPrompt: string;
@@ -1841,4 +1746,4 @@ declare function buildModelRequest(input: ModelRequestInput, options?: {
1841
1746
  model?: LlmModelRef;
1842
1747
  }): LlmRequest;
1843
1748
 
1844
- export { type AbortEvent, type AfterPhaseEvent, type AfterPhaseHookResult, type AfterPhaseResult, type AfterToolCallEvent, type AfterToolCallResult, Agent, type AgentConfigFile, type AgentContext, type AgentEndEvent, AgentEventStream, type AgentOptions, type AgentStartEvent, type AgentStatus, type BeforePhaseEvent, type BeforePhaseHookResult, type BeforePhaseResult, type BeforePromptEvent, type BeforePromptResult, type BeforeToolCallEvent, type BeforeToolCallResult, type EventBus, EventStream, type ExecOptions, type ExecResult, type ExecutionTurn, type Extension, type ExtensionAPI, type ExtensionContext, type ExtensionError, type ExtensionErrorListener, type ExtensionFactory, type ExtensionManifest, type ExtensionPackageManifest, ExtensionRunner, type ExtensionRunnerOptions, type ExtensionRunnerRef, type ExtensionRuntime, type ExtensionUtils, HookError, type HookEvent, type HookEventType, type HookHandler, type HookResultMap, HooksManager, type LoadExtensionsResult, type LoadedExtension, LocalJsonlSessionManager, type LoopMetrics, type MessageEndEvent, type MessageStartEvent, type MessageUpdateEvent, type ModelConfigFromFile, type ModelTranscript, type Phase, type PhaseContext, type PhaseDefinition, type PhaseExecution, type PhaseOutput, type PhaseRegistration, type PhaseRegistry, type PhaseRun, type PhaseState, type ProviderConfigFromFile, type QueueUpdateEvent, type RegisteredPhase, type RegisteredTool, type RunOptions, type RunResult, type SavePointEvent, type Session, type SessionListItem, type SettledEvent, type SourceInfo, type Tool, type ToolDefinition, type ToolExecutionEndEvent, type ToolExecutionResult, type ToolExecutionStartEvent, type ToolExecutionUpdateEvent, type TurnEndEvent, type TurnStartEvent, type WorkspacePaths, appendUserTurn, buildModelRequest, buildSystemPrompt, conversationMessages, createCoreTools, createEventBus, createExtension, createExtensionAPI, createExtensionRunner, createExtensionRuntime, createId, createMessage, createSession, createSourceInfo, createTimestamp, discoverAndLoadExtensions, getGlobalHooks, interpolateEnvVars, latestUserInput, loadConfigFile, loadExtensionFromFactory, loadExtensions, loadPhases, loadSkill, loadSkills, messageContentText, parseModelRef, registerConfigModels, resetGlobalHooks, resolveDefaultModel, resolveInWorkspace, resolveSkillPath, resolveWorkspacePaths, serializeSkills };
1749
+ export { type AbortEvent, type AfterPhaseEvent, type AfterPhaseHookResult, type AfterPhaseResult, type AfterToolCallEvent, type AfterToolCallResult, Agent, type AgentConfigFile, type AgentContext, type AgentEndEvent, AgentEventStream, type AgentOptions, type AgentStartEvent, type AgentStatus, type BeforePhaseEvent, type BeforePhaseHookResult, type BeforePhaseResult, type BeforePromptEvent, type BeforePromptResult, type BeforeToolCallEvent, type BeforeToolCallResult, type EventBus, EventStream, type ExecOptions, type ExecResult, type ExecutionTurn, type Extension, type ExtensionAPI, type ExtensionContext, type ExtensionError, type ExtensionErrorListener, type ExtensionFactory, type ExtensionManifest, type ExtensionPackageManifest, ExtensionRunner, type ExtensionRunnerOptions, type ExtensionRuntime, type ExtensionUtils, HookError, type HookEvent, type HookEventType, type HookHandler, type HookResultMap, HooksManager, type LoadExtensionsResult, type LoadedExtension, LocalJsonlSessionManager, type LoopMetrics, type MessageEndEvent, type MessageStartEvent, type MessageUpdateEvent, type ModelConfigFromFile, type ModelTranscript, type Phase, type PhaseContext, type PhaseDefinition, type PhaseExecution, type PhaseOutput, type PhaseRegistration, type PhaseRegistry, type PhaseRun, type PhaseState, type ProviderConfigFromFile, type QueueUpdateEvent, type RegisteredPhase, type RegisteredTool, type RunOptions, type RunResult, type SavePointEvent, type Session, type SessionListItem, type SettledEvent, type SourceInfo, type Tool, type ToolDefinition, type ToolExecutionEndEvent, type ToolExecutionResult, type ToolExecutionStartEvent, type ToolExecutionUpdateEvent, type TurnEndEvent, type TurnStartEvent, type WorkspacePaths, appendUserTurn, buildModelRequest, buildSystemPrompt, conversationMessages, createCoreTools, createEventBus, createExtension, createExtensionAPI, createExtensionRunner, createExtensionRuntime, createId, createMessage, createSession, createSourceInfo, createTimestamp, getGlobalHooks, interpolateEnvVars, latestUserInput, loadConfigFile, messageContentText, parseModelRef, registerConfigModels, resetGlobalHooks, resolveDefaultModel, resolveInWorkspace, resolveWorkspacePaths, serializeSkills };