@saadnvd1/agent-os 0.3.512 → 0.3.513
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/lib/chat/activity.ts +6 -12
- package/lib/chat/events.ts +1 -1
- package/lib/chat/runner.ts +4 -11
- package/lib/chat/socket.ts +2 -3
- package/lib/chat/store.ts +12 -7
- package/lib/db/migrations.ts +13 -0
- package/package.json +1 -1
package/lib/chat/activity.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { formatTokens } from "./context";
|
|
|
3
3
|
import { formatElapsed } from "./elapsed";
|
|
4
4
|
import { registry, type Live } from "./registry";
|
|
5
5
|
import { stallThresholdMs } from "./stall";
|
|
6
|
-
import {
|
|
6
|
+
import { lastItems, runningItems } from "./store";
|
|
7
7
|
import type { WorkerEvent } from "./worker/protocol";
|
|
8
8
|
|
|
9
9
|
const lastWhat = (i: ChatItem): string =>
|
|
@@ -55,23 +55,17 @@ export function track(live: Live, e: WorkerEvent): void {
|
|
|
55
55
|
|
|
56
56
|
// After a reattach, what's still running comes from the saved items.
|
|
57
57
|
export function restoreActivity(sessionId: string, state: ChatState) {
|
|
58
|
-
const items = listItems(sessionId);
|
|
59
58
|
const activity: Live["activity"] = { tools: new Map(), tasks: new Set() };
|
|
60
|
-
if (state !== "idle")
|
|
61
|
-
activity.turnStartedAt = items.findLast(
|
|
62
|
-
(i) => i.kind === "user"
|
|
63
|
-
)?.createdAt;
|
|
64
59
|
if (state !== "idle") {
|
|
65
|
-
|
|
60
|
+
activity.turnStartedAt = lastItems(sessionId, 1, "user")[0]?.createdAt;
|
|
61
|
+
const last = lastItems(sessionId, 1)[0];
|
|
66
62
|
activity.lastAt = last?.createdAt ?? activity.turnStartedAt;
|
|
67
63
|
activity.lastWhat = last ? lastWhat(last) : undefined;
|
|
68
|
-
|
|
69
|
-
for (const i of items) {
|
|
70
|
-
if (i.kind === "tool" && i.status === "running" && state !== "idle")
|
|
64
|
+
for (const i of runningItems(sessionId, "tool"))
|
|
71
65
|
activity.tools.set(i.id, { label: i.title, since: i.createdAt });
|
|
72
|
-
if (i.kind === "task" && i.status === "running" && !i.ambient)
|
|
73
|
-
activity.tasks.add(i.taskId);
|
|
74
66
|
}
|
|
67
|
+
for (const i of runningItems(sessionId, "task"))
|
|
68
|
+
if (!i.ambient) activity.tasks.add(i.taskId);
|
|
75
69
|
return activity;
|
|
76
70
|
}
|
|
77
71
|
|
package/lib/chat/events.ts
CHANGED
|
@@ -311,7 +311,7 @@ export interface ToolBody {
|
|
|
311
311
|
export type ChatServerMessage =
|
|
312
312
|
| {
|
|
313
313
|
type: "snapshot";
|
|
314
|
-
//
|
|
314
|
+
// The latest page; older ones come with `history`.
|
|
315
315
|
items: ChatItem[];
|
|
316
316
|
// Where older items start, and whether there are any.
|
|
317
317
|
cursor: number | null;
|
package/lib/chat/runner.ts
CHANGED
|
@@ -38,7 +38,6 @@ import {
|
|
|
38
38
|
hasItem,
|
|
39
39
|
itemsOfKind,
|
|
40
40
|
recentTasks,
|
|
41
|
-
listItems,
|
|
42
41
|
saveItem,
|
|
43
42
|
settle,
|
|
44
43
|
} from "./store";
|
|
@@ -851,17 +850,11 @@ function present(sessionId: string, items: ChatItem[]): ChatItem[] {
|
|
|
851
850
|
return runningWorkers().includes(sessionId) ? items : settle(items);
|
|
852
851
|
}
|
|
853
852
|
|
|
854
|
-
// Snapshot then live updates. Returns the unsubscribe function.
|
|
855
|
-
//
|
|
856
|
-
export function watchChat(
|
|
857
|
-
sessionId: string,
|
|
858
|
-
listener: Listener,
|
|
859
|
-
paged = false
|
|
860
|
-
): () => void {
|
|
853
|
+
// Snapshot then live updates. Returns the unsubscribe function. Every
|
|
854
|
+
// client gets the latest page and asks for older ones.
|
|
855
|
+
export function watchChat(sessionId: string, listener: Listener): () => void {
|
|
861
856
|
const live = registry.live.get(sessionId);
|
|
862
|
-
const page =
|
|
863
|
-
? readPage(sessionId)
|
|
864
|
-
: { items: listItems(sessionId), cursor: null, hasMore: false };
|
|
857
|
+
const page = readPage(sessionId);
|
|
865
858
|
const onPage = new Set(page.items.map((i) => i.id));
|
|
866
859
|
// The composer lists background work still going or just done, even when
|
|
867
860
|
// it started before the page.
|
package/lib/chat/socket.ts
CHANGED
|
@@ -102,17 +102,16 @@ export function serveChatSocket(
|
|
|
102
102
|
// A linked machine's session: its own AgentOS serves the chat.
|
|
103
103
|
const link = demo ? null : peerChatLink(sessionId);
|
|
104
104
|
if (link) {
|
|
105
|
-
const paged = params.get("paged");
|
|
106
105
|
return relayChatSocket(
|
|
107
106
|
ws,
|
|
108
107
|
link,
|
|
109
|
-
{ session: sessionId,
|
|
108
|
+
{ session: sessionId, paged: "1" },
|
|
110
109
|
send,
|
|
111
110
|
(message) => reply(errorItem(message))
|
|
112
111
|
);
|
|
113
112
|
}
|
|
114
113
|
try {
|
|
115
|
-
unwatch = watchChat(sessionId, reply
|
|
114
|
+
unwatch = watchChat(sessionId, reply);
|
|
116
115
|
} catch (err) {
|
|
117
116
|
fail(err);
|
|
118
117
|
if (!closed) ws.close();
|
package/lib/chat/store.ts
CHANGED
|
@@ -198,22 +198,27 @@ export function recentTasks(
|
|
|
198
198
|
.map((r) => JSON.parse(r.data));
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
//
|
|
202
|
-
export function
|
|
203
|
-
sessionId: string
|
|
204
|
-
|
|
201
|
+
// Items of a kind saved as still running, read from the running index.
|
|
202
|
+
export function runningItems<K extends "tool" | "task">(
|
|
203
|
+
sessionId: string,
|
|
204
|
+
kind: K
|
|
205
|
+
): Extract<ChatItem, { kind: K }>[] {
|
|
205
206
|
flushItems();
|
|
206
207
|
return (
|
|
207
208
|
db
|
|
208
209
|
.prepare(
|
|
209
210
|
`SELECT data FROM chat_items WHERE session_id = ?
|
|
210
|
-
AND kind = '
|
|
211
|
-
|
|
211
|
+
AND kind = ? AND json_extract(data, '$.status') = 'running'
|
|
212
|
+
ORDER BY seq`
|
|
212
213
|
)
|
|
213
|
-
.all(sessionId) as { data: string }[]
|
|
214
|
+
.all(sessionId, kind) as { data: string }[]
|
|
214
215
|
).map((r) => JSON.parse(r.data));
|
|
215
216
|
}
|
|
216
217
|
|
|
218
|
+
// Tool calls saved as still running.
|
|
219
|
+
export const runningTools = (sessionId: string) =>
|
|
220
|
+
runningItems(sessionId, "tool");
|
|
221
|
+
|
|
217
222
|
export function deleteItems(sessionId: string): void {
|
|
218
223
|
pending.delete(sessionId);
|
|
219
224
|
seqs.delete(sessionId);
|
package/lib/db/migrations.ts
CHANGED
|
@@ -1617,6 +1617,19 @@ const migrations: Migration[] = [
|
|
|
1617
1617
|
`);
|
|
1618
1618
|
},
|
|
1619
1619
|
},
|
|
1620
|
+
{
|
|
1621
|
+
id: 70,
|
|
1622
|
+
name: "chat_items_running",
|
|
1623
|
+
up: (db) => {
|
|
1624
|
+
// What is still running (tools, background tasks) is read on every
|
|
1625
|
+
// attach; the index holds only those rows, so it's a lookup, not a
|
|
1626
|
+
// scan that parses every tool output of a long conversation.
|
|
1627
|
+
db.exec(
|
|
1628
|
+
`CREATE INDEX IF NOT EXISTS idx_chat_items_running ON chat_items(session_id, kind, seq)
|
|
1629
|
+
WHERE json_extract(data, '$.status') = 'running'`
|
|
1630
|
+
);
|
|
1631
|
+
},
|
|
1632
|
+
},
|
|
1620
1633
|
];
|
|
1621
1634
|
|
|
1622
1635
|
// `upTo`: stop after this id (tests that start from an older database).
|