@rowan-agent/agent 0.5.2 → 0.5.3

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
@@ -42,14 +42,51 @@ The `Agent` class is the public facade. It drives the entire execution loop —
42
42
  ```ts
43
43
  class Agent {
44
44
  constructor(options: AgentOptions);
45
- run(options?: RunOptions): Promise<AgentRunResult>;
45
+ run(options?: RunOptions): Promise<RunResult>;
46
+
47
+ // User input / conversation continuation
48
+ appendUserMessage(input: string): void;
49
+ appendMessage(message: AgentMessage): void;
50
+ appendMessages(messages: AgentMessage[]): void;
51
+ runWithUserInput(input: string, options?: RunOptions): Promise<RunResult>;
52
+ runWithMessage(message: AgentMessage, options?: RunOptions): Promise<RunResult>;
53
+
54
+ // Context and transcript
55
+ getContext(): AgentContext;
56
+ setContext(context: AgentContext): void;
57
+ updateContext(updater: (context: AgentContext) => AgentContext): void;
58
+ forkContext(overrides?: Partial<AgentContext>): AgentContext;
59
+ getMessages(): AgentMessage[];
60
+ setMessages(messages: AgentMessage[]): void;
61
+ clearMessages(): void;
62
+ getTranscript(): AgentMessage[];
63
+ replaceTranscript(messages: AgentMessage[]): void;
64
+
65
+ // Config access and shortcuts
66
+ getConfig(): AgentOptions;
67
+ setConfig(config: AgentOptions): void;
68
+ updateConfig(updater: (config: AgentOptions) => AgentOptions): void;
69
+ setSessionId(sessionId: string): void;
70
+ getSessionId(): string | undefined;
71
+ setModel(model: LlmModelRef): void;
72
+ setTools(tools: Tool[]): void;
73
+ setSkills(skills: Skill[]): void;
74
+ setPhases(phases: PhaseRegistry): void;
75
+ setCwd(cwd: string): void;
76
+ setStream(stream: StreamFn): void;
77
+ getModel(): LlmModelRef;
78
+ getTools(): Tool[];
79
+ getSkills(): Skill[];
80
+ getPhases(): PhaseRegistry | undefined;
81
+ getCwd(): string | undefined;
82
+
46
83
  abort(): void;
47
84
  subscribe(listener: AgentEventListener): () => void;
48
- skill(name: string): Promise<void>;
85
+ skill(name: string, additionalInstructions?: string): string;
49
86
  phase(name: string): Promise<string>;
50
87
  waitForIdle(): Promise<void>;
51
88
  flushEvents(): Promise<void>;
52
- readonly status: AgentStatus;
89
+ readonly state: AgentStatus;
53
90
 
54
91
  // Resource loading — replaces standalone loadSkills/loadPhases/loadExtensions
55
92
  static loadSkills(targetPath: string): Promise<Skill[]>;
@@ -65,6 +102,7 @@ type AgentOptions = {
65
102
  context: AgentContext;
66
103
  model: LlmModelRef;
67
104
  stream: StreamFn;
105
+ cwd?: string;
68
106
  extensions?: LoadedExtension[];
69
107
  sessionId?: string;
70
108
  maxAttempts?: number;
@@ -78,18 +116,57 @@ type AgentOptions = {
78
116
  };
79
117
  ```
80
118
 
81
- ### AgentRunResult
119
+ ### RunResult
82
120
 
83
121
  ```ts
84
- type AgentRunResult = {
85
- status: AgentStatus;
86
- outcome?: Outcome;
87
- metrics?: LoopMetrics;
88
- messages: AgentMessage[];
122
+ type RunResult = {
89
123
  sessionId: string;
124
+ messages: AgentMessage[];
125
+ outcome: Outcome;
126
+ metrics: LoopMetrics;
90
127
  };
91
128
  ```
92
129
 
130
+ ### Conversation Continuation
131
+
132
+ For multi-turn use, append input to the agent's current transcript and run with the updated context. `runWithUserInput()` is the main convenience API; the lower-level append methods are useful when a UI or session layer controls message creation.
133
+
134
+ ```ts
135
+ const first = await agent.runWithUserInput("summarize this repository");
136
+
137
+ agent.appendUserMessage("now focus on the CLI package");
138
+ const second = await agent.run();
139
+
140
+ await agent.runWithMessage(createMessage("user", "what changed since last turn?"));
141
+ ```
142
+
143
+ Transcript helpers return snapshots, so callers can inspect or edit history without accidentally mutating the agent until they call a setter.
144
+
145
+ ```ts
146
+ const messages = agent.getMessages();
147
+ agent.replaceTranscript(messages.slice(-6));
148
+ agent.clearMessages();
149
+ ```
150
+
151
+ ### Updating Config
152
+
153
+ `AgentOptions` can be replaced wholesale with `setConfig()`, or updated through focused shortcuts for common orchestration flows.
154
+
155
+ ```ts
156
+ agent.setSessionId("ses_known");
157
+ agent.setModel({ provider: "openai", id: "gpt-4.1" });
158
+ agent.setTools(createCoreTools({ root: process.cwd() }));
159
+ agent.setSkills(await Agent.loadSkills("./.rowan/skills"));
160
+ agent.setPhases(await Agent.loadPhases("./.rowan/phases"));
161
+ agent.setCwd(process.cwd());
162
+ agent.setStream(createDispatchStream());
163
+
164
+ agent.updateContext((context) => ({
165
+ ...context,
166
+ systemPrompt: `${context.systemPrompt}\n\nPrefer concise answers.`,
167
+ }));
168
+ ```
169
+
93
170
  ## AgentContext
94
171
 
95
172
  The context snapshot that defines what the agent can see and do — the system prompt sets the role, messages form the conversation history, and tools/skills define the capability boundary.
package/dist/index.d.ts CHANGED
@@ -1376,6 +1376,36 @@ declare class Agent {
1376
1376
  static loadExtensions(targetPath: string): Promise<LoadExtensionsResult>;
1377
1377
  constructor(options: AgentOptions);
1378
1378
  subscribe(listener: AgentEventListener): Unsubscribe;
1379
+ appendUserMessage(input: string): void;
1380
+ appendMessage(message: AgentMessage): void;
1381
+ appendMessages(messages: AgentMessage[]): void;
1382
+ runWithUserInput(input: string, options?: RunOptions): Promise<RunResult>;
1383
+ runWithMessage(message: AgentMessage, options?: RunOptions): Promise<RunResult>;
1384
+ getContext(): AgentContext;
1385
+ setContext(context: AgentContext): void;
1386
+ updateContext(updater: (context: AgentContext) => AgentContext): void;
1387
+ forkContext(overrides?: Partial<AgentContext>): AgentContext;
1388
+ getMessages(): AgentMessage[];
1389
+ setMessages(messages: AgentMessage[]): void;
1390
+ clearMessages(): void;
1391
+ getTranscript(): AgentMessage[];
1392
+ replaceTranscript(messages: AgentMessage[]): void;
1393
+ getConfig(): AgentOptions;
1394
+ setConfig(config: AgentOptions): void;
1395
+ updateConfig(updater: (config: AgentOptions) => AgentOptions): void;
1396
+ setSessionId(sessionId: string): void;
1397
+ getSessionId(): string | undefined;
1398
+ setModel(model: LlmModelRef): void;
1399
+ setTools(tools: Tool[]): void;
1400
+ setSkills(skills: Skill$1[]): void;
1401
+ setPhases(phases: PhaseRegistry): void;
1402
+ setCwd(cwd: string): void;
1403
+ setStream(stream: StreamFn): void;
1404
+ getModel(): LlmModelRef;
1405
+ getTools(): Tool[];
1406
+ getSkills(): Skill$1[];
1407
+ getPhases(): PhaseRegistry | undefined;
1408
+ getCwd(): string | undefined;
1379
1409
  private emitToListeners;
1380
1410
  flushEvents(): Promise<void>;
1381
1411
  private processEvents;
@@ -1434,6 +1464,7 @@ declare class Agent {
1434
1464
  waitForIdle(): Promise<void>;
1435
1465
  private resolveRunConfig;
1436
1466
  private createContextSnapshot;
1467
+ private cloneOptions;
1437
1468
  }
1438
1469
 
1439
1470
  declare function createId(prefix: string): string;
package/dist/index.js CHANGED
@@ -3448,6 +3448,142 @@ var Agent = class {
3448
3448
  this.listeners.delete(listener);
3449
3449
  };
3450
3450
  }
3451
+ appendUserMessage(input) {
3452
+ this.appendMessage(createMessage("user", input));
3453
+ }
3454
+ appendMessage(message) {
3455
+ this.appendMessages([message]);
3456
+ }
3457
+ appendMessages(messages) {
3458
+ this.setMessages([...this.options.context.messages, ...snapshotMessages(messages)]);
3459
+ }
3460
+ runWithUserInput(input, options) {
3461
+ this.appendUserMessage(input);
3462
+ return this.run(options);
3463
+ }
3464
+ runWithMessage(message, options) {
3465
+ this.appendMessage(message);
3466
+ return this.run(options);
3467
+ }
3468
+ getContext() {
3469
+ return prepareAgentContext(this.options.context);
3470
+ }
3471
+ setContext(context) {
3472
+ const nextContext = prepareAgentContext(context);
3473
+ this.options = {
3474
+ ...this.options,
3475
+ context: nextContext
3476
+ };
3477
+ this.state.context = prepareAgentContext(nextContext, this.extensionRunner);
3478
+ this.state.tools = this.state.context.tools ?? [];
3479
+ }
3480
+ updateContext(updater) {
3481
+ this.setContext(updater(this.getContext()));
3482
+ }
3483
+ forkContext(overrides = {}) {
3484
+ return prepareAgentContext({
3485
+ ...this.getContext(),
3486
+ ...overrides
3487
+ });
3488
+ }
3489
+ getMessages() {
3490
+ return snapshotMessages(this.options.context.messages);
3491
+ }
3492
+ setMessages(messages) {
3493
+ this.setContext({
3494
+ ...this.options.context,
3495
+ messages: snapshotMessages(messages)
3496
+ });
3497
+ }
3498
+ clearMessages() {
3499
+ this.setMessages([]);
3500
+ }
3501
+ getTranscript() {
3502
+ return this.getMessages();
3503
+ }
3504
+ replaceTranscript(messages) {
3505
+ this.setMessages(messages);
3506
+ }
3507
+ getConfig() {
3508
+ return this.cloneOptions(this.options);
3509
+ }
3510
+ setConfig(config) {
3511
+ const context = prepareAgentContext(config.context);
3512
+ this.options = {
3513
+ ...config,
3514
+ context,
3515
+ ...config.extensions ? { extensions: config.extensions.slice() } : {}
3516
+ };
3517
+ this.state.sessionId = config.sessionId;
3518
+ this.state.context = prepareAgentContext(context, this.extensionRunner);
3519
+ this.state.model = config.model;
3520
+ this.state.tools = this.state.context.tools ?? [];
3521
+ }
3522
+ updateConfig(updater) {
3523
+ this.setConfig(updater(this.getConfig()));
3524
+ }
3525
+ setSessionId(sessionId) {
3526
+ this.options = {
3527
+ ...this.options,
3528
+ sessionId
3529
+ };
3530
+ this.state.sessionId = sessionId;
3531
+ }
3532
+ getSessionId() {
3533
+ return this.state.sessionId;
3534
+ }
3535
+ setModel(model) {
3536
+ this.options = {
3537
+ ...this.options,
3538
+ model
3539
+ };
3540
+ this.state.model = model;
3541
+ }
3542
+ setTools(tools) {
3543
+ this.setContext({
3544
+ ...this.options.context,
3545
+ tools: tools.slice()
3546
+ });
3547
+ }
3548
+ setSkills(skills) {
3549
+ this.setContext({
3550
+ ...this.options.context,
3551
+ skills: skills.slice()
3552
+ });
3553
+ }
3554
+ setPhases(phases) {
3555
+ this.setContext({
3556
+ ...this.options.context,
3557
+ phases: clonePhaseRegistry(phases)
3558
+ });
3559
+ }
3560
+ setCwd(cwd) {
3561
+ this.options = {
3562
+ ...this.options,
3563
+ cwd
3564
+ };
3565
+ }
3566
+ setStream(stream) {
3567
+ this.options = {
3568
+ ...this.options,
3569
+ stream
3570
+ };
3571
+ }
3572
+ getModel() {
3573
+ return this.state.model;
3574
+ }
3575
+ getTools() {
3576
+ return this.state.context.tools.slice();
3577
+ }
3578
+ getSkills() {
3579
+ return this.state.context.skills.slice();
3580
+ }
3581
+ getPhases() {
3582
+ return this.state.context.phases ? clonePhaseRegistry(this.state.context.phases) : void 0;
3583
+ }
3584
+ getCwd() {
3585
+ return this.options.cwd;
3586
+ }
3451
3587
  emitToListeners(event) {
3452
3588
  for (const listener of this.listeners) {
3453
3589
  try {
@@ -3718,7 +3854,20 @@ ${additionalInstructions}` : content;
3718
3854
  createContextSnapshot() {
3719
3855
  return prepareAgentContext(this.options.context);
3720
3856
  }
3857
+ cloneOptions(options) {
3858
+ return {
3859
+ ...options,
3860
+ context: prepareAgentContext(options.context),
3861
+ ...options.extensions ? { extensions: options.extensions.slice() } : {}
3862
+ };
3863
+ }
3721
3864
  };
3865
+ function clonePhaseRegistry(registry) {
3866
+ return {
3867
+ phases: new Map(registry.phases),
3868
+ entryPhaseId: registry.entryPhaseId
3869
+ };
3870
+ }
3722
3871
  function prepareAgentContext(context, extensionRunner) {
3723
3872
  const phases = /* @__PURE__ */ new Map();
3724
3873
  phases.set(DEFAULT_PHASE_ID, createDefaultPhase());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowan-agent/agent",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",