@evandu/super-pi 0.1.70 → 0.1.72
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 +12 -0
- package/dist/client/assets/index-Bi2QvT9i.js +63 -0
- package/dist/client/assets/index-CKdlMXJt.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/server/application/run-service.js +83 -31
- package/dist/server/http-server.js +74 -1
- package/dist/server/index.js +3 -0
- package/dist/server/rpc-channel.d.ts +109 -0
- package/dist/server/rpc-channel.js +117 -0
- package/dist/server/runtime.d.ts +6 -227
- package/dist/server/runtime.js +66 -358
- package/dist/server/server-context.d.ts +2 -0
- package/dist/server/session-repository.d.ts +99 -0
- package/dist/server/session-repository.js +245 -0
- package/dist/server/store.d.ts +12 -0
- package/dist/server/store.js +45 -5
- package/dist/server/subagents.js +3 -2
- package/dist/server/tool-registry.d.ts +35 -0
- package/dist/server/tool-registry.js +74 -0
- package/dist/server/types.d.ts +20 -1
- package/dist/server/ws-server.d.ts +5 -0
- package/dist/server/ws-server.js +49 -3
- package/package.json +5 -2
- package/dist/client/assets/index-B0eJbg4U.js +0 -54
- package/dist/client/assets/index-CbHwRb22.css +0 -1
package/dist/server/types.d.ts
CHANGED
|
@@ -94,6 +94,10 @@ export type Message = {
|
|
|
94
94
|
piEntryId?: string;
|
|
95
95
|
toolCalls?: ToolCallBlock[];
|
|
96
96
|
thinking?: string;
|
|
97
|
+
thinkingBlocks?: {
|
|
98
|
+
at: number;
|
|
99
|
+
text: string;
|
|
100
|
+
}[];
|
|
97
101
|
images?: MessageImage[];
|
|
98
102
|
attachments?: MessageAttachments;
|
|
99
103
|
agentIdentity?: {
|
|
@@ -241,11 +245,17 @@ export type ToolCallNotice = {
|
|
|
241
245
|
* - read out of the arguments as far as they have arrived. It is `undefined` when nothing identifying has
|
|
242
246
|
* been written yet, which is a different fact from an empty one: the caller has a placeholder word for the
|
|
243
247
|
* second case and must not invent one for the first.
|
|
248
|
+
*
|
|
249
|
+
* `live` is the arguments AS THEY STAND - the whole text written so far, never the newest fragment alone.
|
|
250
|
+
* It shares its meaning with `tool_execution_update`'s output (which Pi sends already accumulated), so one
|
|
251
|
+
* field with two meanings would make the caller store one kind of text by appending and the other by
|
|
252
|
+
* replacing - which is a flicker and a duplication at once. Pi sends argument fragments raw; accumulating
|
|
253
|
+
* them is the runtime's job, where the fragments already are.
|
|
244
254
|
*/
|
|
245
255
|
export interface ToolCallPreparing {
|
|
246
256
|
contentIndex: number;
|
|
247
257
|
name: string;
|
|
248
|
-
|
|
258
|
+
live?: string;
|
|
249
259
|
detail?: string;
|
|
250
260
|
}
|
|
251
261
|
/**
|
|
@@ -315,6 +325,9 @@ export type Conversation = {
|
|
|
315
325
|
status: RunStatus;
|
|
316
326
|
messages: Message[];
|
|
317
327
|
archivedAt?: string;
|
|
328
|
+
/** Pi's own resolved transcript path, observed from this conversation's live worker. It is only a
|
|
329
|
+
* locator: revert still verifies the file header and every retained boundary before writing. */
|
|
330
|
+
piSessionFile?: string;
|
|
318
331
|
/** Set when the user explicitly names the session; automatic first-message titles must not overwrite it. */
|
|
319
332
|
titleLocked?: boolean;
|
|
320
333
|
/**
|
|
@@ -912,6 +925,11 @@ export type ClientCommandBody =
|
|
|
912
925
|
type: "catalog.fetch";
|
|
913
926
|
conversationId?: string;
|
|
914
927
|
}
|
|
928
|
+
/** Enables bounded transport coalescing for high-frequency streaming events on this socket. */
|
|
929
|
+
| {
|
|
930
|
+
type: "stream.configure";
|
|
931
|
+
coalesce: boolean;
|
|
932
|
+
}
|
|
915
933
|
/** Asks for the agent catalog read from disk. Answered by `agent.catalog`. */
|
|
916
934
|
| {
|
|
917
935
|
type: "agent.catalog.fetch";
|
|
@@ -1080,6 +1098,7 @@ export type ServerEvent = {
|
|
|
1080
1098
|
messageId: string;
|
|
1081
1099
|
delta: string;
|
|
1082
1100
|
active: boolean;
|
|
1101
|
+
at?: number;
|
|
1083
1102
|
}
|
|
1084
1103
|
/**
|
|
1085
1104
|
* THE ANSWER TO `conversation.fork`, as ONE event with an `ok` discriminant rather than two events or a
|
|
@@ -11,9 +11,14 @@ import type { CatalogService } from "./application/catalog-service.js";
|
|
|
11
11
|
export declare class WsBroadcaster implements EventBroadcaster {
|
|
12
12
|
private readonly getState;
|
|
13
13
|
private readonly sockets;
|
|
14
|
+
private readonly coalescedSockets;
|
|
15
|
+
private readonly pendingStreams;
|
|
14
16
|
constructor(getState: () => AppState);
|
|
15
17
|
register(socket: WebSocket): void;
|
|
16
18
|
unregister(socket: WebSocket): void;
|
|
19
|
+
configureStreaming(socket: WebSocket, coalesce: boolean): void;
|
|
20
|
+
private flushStreaming;
|
|
21
|
+
private enqueueStreaming;
|
|
17
22
|
getSockets(): Set<WebSocket>;
|
|
18
23
|
broadcast(event: ServerEvent): void;
|
|
19
24
|
broadcastState(): void;
|
package/dist/server/ws-server.js
CHANGED
|
@@ -7,6 +7,8 @@ import { isAuthorized } from "./http-server.js";
|
|
|
7
7
|
export class WsBroadcaster {
|
|
8
8
|
getState;
|
|
9
9
|
sockets = new Set();
|
|
10
|
+
coalescedSockets = new Set();
|
|
11
|
+
pendingStreams = new Map();
|
|
10
12
|
constructor(getState) {
|
|
11
13
|
this.getState = getState;
|
|
12
14
|
}
|
|
@@ -14,16 +16,56 @@ export class WsBroadcaster {
|
|
|
14
16
|
this.sockets.add(socket);
|
|
15
17
|
}
|
|
16
18
|
unregister(socket) {
|
|
19
|
+
this.coalescedSockets.delete(socket);
|
|
20
|
+
const pending = this.pendingStreams.get(socket);
|
|
21
|
+
if (pending)
|
|
22
|
+
clearTimeout(pending.timer);
|
|
23
|
+
this.pendingStreams.delete(socket);
|
|
17
24
|
this.sockets.delete(socket);
|
|
18
25
|
}
|
|
26
|
+
configureStreaming(socket, coalesce) {
|
|
27
|
+
if (coalesce)
|
|
28
|
+
this.coalescedSockets.add(socket);
|
|
29
|
+
else {
|
|
30
|
+
this.flushStreaming(socket);
|
|
31
|
+
this.coalescedSockets.delete(socket);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
flushStreaming(socket) {
|
|
35
|
+
const pending = this.pendingStreams.get(socket);
|
|
36
|
+
if (!pending)
|
|
37
|
+
return;
|
|
38
|
+
clearTimeout(pending.timer);
|
|
39
|
+
this.pendingStreams.delete(socket);
|
|
40
|
+
for (const event of pending.events.values())
|
|
41
|
+
if (socket.readyState === WebSocket.OPEN)
|
|
42
|
+
socket.send(JSON.stringify(event));
|
|
43
|
+
}
|
|
44
|
+
enqueueStreaming(socket, event) {
|
|
45
|
+
let pending = this.pendingStreams.get(socket);
|
|
46
|
+
if (!pending) {
|
|
47
|
+
const events = new Map();
|
|
48
|
+
pending = { events, timer: setTimeout(() => this.flushStreaming(socket), 16) };
|
|
49
|
+
this.pendingStreams.set(socket, pending);
|
|
50
|
+
}
|
|
51
|
+
const key = `${event.type}\u0000${event.conversationId}\u0000${event.messageId}`;
|
|
52
|
+
const previous = pending.events.get(key);
|
|
53
|
+
pending.events.set(key, previous ? { ...previous, delta: previous.delta + event.delta } : event);
|
|
54
|
+
}
|
|
19
55
|
getSockets() {
|
|
20
56
|
return this.sockets;
|
|
21
57
|
}
|
|
22
58
|
broadcast(event) {
|
|
23
|
-
const
|
|
59
|
+
const streaming = event.type === "message.delta" || event.type === "message.thinking";
|
|
24
60
|
for (const socket of this.sockets) {
|
|
25
|
-
if (socket.readyState
|
|
26
|
-
|
|
61
|
+
if (socket.readyState !== WebSocket.OPEN)
|
|
62
|
+
continue;
|
|
63
|
+
if (streaming && this.coalescedSockets.has(socket))
|
|
64
|
+
this.enqueueStreaming(socket, event);
|
|
65
|
+
else {
|
|
66
|
+
// A state/tool/lifecycle event is a transcript boundary. Flush its preceding text first.
|
|
67
|
+
this.flushStreaming(socket);
|
|
68
|
+
socket.send(JSON.stringify(event));
|
|
27
69
|
}
|
|
28
70
|
}
|
|
29
71
|
}
|
|
@@ -169,6 +211,10 @@ export class WsServer {
|
|
|
169
211
|
socket.send(JSON.stringify({ type: "error", message: "command failed" }));
|
|
170
212
|
return;
|
|
171
213
|
}
|
|
214
|
+
if (parsed.type === "stream.configure") {
|
|
215
|
+
this.broadcaster.configureStreaming(socket, parsed.coalesce);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
172
218
|
// A send represents a streaming operation. It must be admitted immediately so a second send
|
|
173
219
|
// can observe the active run and enter the durable follow-up queue; waiting for the first model
|
|
174
220
|
// turn here makes every follow-up test time out and defeats the queue semantics.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evandu/super-pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.72",
|
|
4
4
|
"description": "Web control plane and companion for Pi",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -34,6 +34,8 @@
|
|
|
34
34
|
"check": "node scripts/run-check.mjs"
|
|
35
35
|
},
|
|
36
36
|
"check:logic": [
|
|
37
|
+
"scripts/stream-checkpoint.test.mjs",
|
|
38
|
+
"scripts/stream-transport.test.mjs",
|
|
37
39
|
"scripts/lan-access.test.mjs",
|
|
38
40
|
"scripts/terminal-pty.test.mjs",
|
|
39
41
|
"scripts/persistence-repository.test.mjs",
|
|
@@ -69,7 +71,6 @@
|
|
|
69
71
|
"scripts/revert-session-format.test.mjs",
|
|
70
72
|
"scripts/revert-session-file.test.mjs",
|
|
71
73
|
"scripts/revert-real-pi.test.mjs",
|
|
72
|
-
"scripts/revert-browser.test.mjs",
|
|
73
74
|
"scripts/bg-task.test.mjs",
|
|
74
75
|
"scripts/todo-tool.test.mjs",
|
|
75
76
|
"scripts/tool-calls.test.mjs",
|
|
@@ -84,6 +85,7 @@
|
|
|
84
85
|
"scripts/active-memory.test.mjs"
|
|
85
86
|
],
|
|
86
87
|
"check:browser": [
|
|
88
|
+
"scripts/revert-browser.test.mjs",
|
|
87
89
|
"scripts/extension-ui-browser.test.mjs",
|
|
88
90
|
"scripts/inline-rename-blur.test.mjs",
|
|
89
91
|
"scripts/message-timestamps-browser.test.mjs",
|
|
@@ -93,6 +95,7 @@
|
|
|
93
95
|
"scripts/workflow-browser.test.mjs",
|
|
94
96
|
"scripts/conversation-reconcile-browser.test.mjs",
|
|
95
97
|
"scripts/visual-defects-browser.test.mjs",
|
|
98
|
+
"scripts/session-state-animation-browser.test.mjs",
|
|
96
99
|
"scripts/agent-vis-card-browser.test.mjs",
|
|
97
100
|
"scripts/queue-dock.test.mjs",
|
|
98
101
|
"scripts/md-render-browser.test.mjs",
|