agent-state-machine 2.0.2 → 2.0.4

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
@@ -44,11 +44,11 @@ Requirements: Node.js >= 16.
44
44
  ```bash
45
45
  state-machine --setup <workflow-name>
46
46
  state-machine run <workflow-name>
47
+ state-machine run <workflow-name> -reset
48
+ state-machine run <workflow-name> -reset-hard
47
49
 
48
50
 
49
51
  state-machine history <workflow-name> [limit]
50
- state-machine reset <workflow-name> (clears memory/state)
51
- state-machine reset-hard <workflow-name> (clears everything: history/interactions/memory)
52
52
  ```
53
53
 
54
54
  Workflows live in:
@@ -140,7 +140,7 @@ export default async function() {
140
140
 
141
141
  `state-machine run` restarts your workflow from the top, loading the persisted state.
142
142
 
143
- If the workflow needs human input, it will **block inline** in the terminal. You’ll be told which `interactions/<slug>.md` file to edit; after you fill it in, press `y` in the same terminal session to continue.
143
+ If the workflow needs human input, it will **block inline** in the terminal. You can answer in the terminal, edit `interactions/<slug>.md`, or respond in the browser.
144
144
 
145
145
  If the process is interrupted, running `state-machine run <workflow-name>` again will continue execution (assuming your workflow uses `memory` to skip completed steps).
146
146
 
@@ -172,8 +172,8 @@ memory.count = (memory.count || 0) + 1;
172
172
 
173
173
  Gets user input.
174
174
 
175
- - In a TTY, it prompts in the terminal.
176
- - Otherwise it creates `interactions/<slug>.md` and blocks until you confirm in the terminal.
175
+ - In a TTY, it prompts in the terminal (or via the browser when remote follow is enabled).
176
+ - Otherwise it creates `interactions/<slug>.md` and blocks until you confirm in the terminal (or respond in the browser).
177
177
 
178
178
  ```js
179
179
  const repo = await initialPrompt('What repo should I work on?', { slug: 'repo' });
@@ -298,7 +298,7 @@ export const config = {
298
298
  };
299
299
  ```
300
300
 
301
- The runtime captures the fully-built prompt in `state/history.jsonl`, viewable in the browser with live updates when running with the `--local` flag or via the remote URL.
301
+ The runtime captures the fully-built prompt in `state/history.jsonl`, viewable in the browser with live updates when running with the `--local` flag or via the remote URL. Remote follow links persist across runs (stored in `workflow.js` config) unless you pass `-n`/`--new` to regenerate.
302
302
 
303
303
  ---
304
304
 
package/bin/cli.js CHANGED
@@ -361,14 +361,18 @@ async function runOrResume(
361
361
  try {
362
362
  await runtime.runWorkflow(workflowUrl);
363
363
  } finally {
364
- // Cleanup
365
- if (remoteUrl) {
364
+ // Keep local server alive after run so the session remains accessible.
365
+ if (!useLocalServer && remoteUrl) {
366
366
  await runtime.disableRemote();
367
367
  }
368
- if (localServer) {
368
+ if (!useLocalServer && localServer) {
369
369
  localServer.close();
370
370
  }
371
371
  }
372
+
373
+ if (useLocalServer) {
374
+ console.log('Local server still running for follow session. Press Ctrl+C to stop.');
375
+ }
372
376
  }
373
377
 
374
378
  async function main() {
@@ -533,7 +533,7 @@ export class WorkflowRuntime {
533
533
  // Send existing history if connected
534
534
  if (this.remoteClient.connected) {
535
535
  const history = this.loadHistory();
536
- this.remoteClient.sendSessionInit(history);
536
+ await this.remoteClient.sendSessionInit(history);
537
537
  }
538
538
 
539
539
  this.remoteEnabled = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-state-machine",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "type": "module",
5
5
  "description": "A workflow orchestrator for running agents and scripts in sequence with state management",
6
6
  "main": "lib/index.js",
@@ -59,9 +59,21 @@ export default async function handler(req, res) {
59
59
  const eventsListKey = `${KEYS.events(token)}:list`;
60
60
  let lastEventIndex = 0;
61
61
 
62
- // Get current list length to start from
62
+ // If history is empty, seed from the event list to catch early events.
63
63
  const currentLength = await redis.llen(eventsListKey);
64
- lastEventIndex = currentLength;
64
+ // if (history.length === 0 && currentLength > 0) {
65
+ // const existingEvents = await redis.lrange(eventsListKey, 0, -1);
66
+ // const entries = existingEvents
67
+ // .map((event) => (typeof event === 'object' ? event : JSON.parse(event)))
68
+ // .filter(Boolean);
69
+ // res.write(`data: ${JSON.stringify({
70
+ // type: 'history',
71
+ // entries,
72
+ // })}\n\n`);
73
+ // lastEventIndex = currentLength;
74
+ // } else {
75
+ // lastEventIndex = currentLength;
76
+ // }
65
77
 
66
78
  const pollInterval = setInterval(async () => {
67
79
  try {
@@ -59,6 +59,9 @@ async function handlePost(req, res) {
59
59
  // Create session
60
60
  await createSession(sessionToken, { workflowName, cliConnected: true });
61
61
 
62
+ // Replace any existing history and event stream with the provided snapshot
63
+ await redis.del(KEYS.history(sessionToken), `${KEYS.events(sessionToken)}:list`);
64
+
62
65
  // Store initial history
63
66
  if (history && history.length > 0) {
64
67
  await addHistoryEvents(sessionToken, history);