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 +6 -6
- package/bin/cli.js +7 -3
- package/lib/runtime/runtime.js +1 -1
- package/package.json +1 -1
- package/vercel-server/api/events/[token].js +14 -2
- package/vercel-server/api/ws/cli.js +3 -0
- package/vercel-server/ui/index.html +677 -426
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
|
|
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
|
-
//
|
|
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() {
|
package/lib/runtime/runtime.js
CHANGED
|
@@ -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
|
@@ -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
|
-
//
|
|
62
|
+
// If history is empty, seed from the event list to catch early events.
|
|
63
63
|
const currentLength = await redis.llen(eventsListKey);
|
|
64
|
-
|
|
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);
|