@evandu/super-pi 0.1.138 → 0.1.140
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/agents/super-pi-knowledge/index.ts +11 -13
- package/agents/super-pi-memory/index.ts +11 -5
- package/agents/super-pi-task/core.ts +418 -1
- package/agents/super-pi-task/index.ts +115 -0
- package/bin/super-pi.js +7 -11
- package/dist/.super-pi-check-inputs.json +2 -2
- package/dist/client/.super-pi-client-sources.json +7 -6
- package/dist/client/assets/{CodeMirrorEditor-CVImD0nh.js → CodeMirrorEditor-DvZeOLny.js} +2 -2
- package/dist/client/assets/{dist-CiEW7LQW.js → dist-3BuyVG3H.js} +1 -1
- package/dist/client/assets/{dist-faxwvvOU.js → dist-BCUfH4nP.js} +1 -1
- package/dist/client/assets/{dist-yONALz0V.js → dist-BIIMtU9W.js} +1 -1
- package/dist/client/assets/{dist-CKI1xVeE.js → dist-C-QmRwbd.js} +1 -1
- package/dist/client/assets/{dist-4uPxkRdw.js → dist-CTkzLBdb.js} +1 -1
- package/dist/client/assets/{dist-CUACXe1Y.js → dist-C_VuSpx8.js} +1 -1
- package/dist/client/assets/{dist-BwQM8_Mk.js → dist-CaUsvSz1.js} +1 -1
- package/dist/client/assets/{dist-Clf26yld.js → dist-Cb1gxS57.js} +1 -1
- package/dist/client/assets/{dist-YB4GJD3u.js → dist-CqDSeoUk.js} +1 -1
- package/dist/client/assets/{dist-DozjvPAZ.js → dist-D7yfnKNC.js} +1 -1
- package/dist/client/assets/{dist-Cocw5XJ_.js → dist-DA8yW4lK.js} +1 -1
- package/dist/client/assets/{dist-amySbADh.js → dist-DAcS4Kj8.js} +1 -1
- package/dist/client/assets/{dist-B75OT6A9.js → dist-DN0M4DAX.js} +1 -1
- package/dist/client/assets/{dist-At94VK1P.js → dist-DRgWZqFH.js} +1 -1
- package/dist/client/assets/{dist-BIgRwYsI.js → dist-DdfW8Gjv.js} +1 -1
- package/dist/client/assets/{dist-DhEa5hHR.js → dist-DlQ8PMvv.js} +1 -1
- package/dist/client/assets/{dist-quQ6u6Rw.js → dist-Dvca0LeR.js} +1 -1
- package/dist/client/assets/{dist-BqblSnWL.js → dist-HJdP1yxN.js} +1 -1
- package/dist/client/assets/{dist-pnGHl3nq.js → dist-gBAr9yXF.js} +1 -1
- package/dist/client/assets/{dist-1H_gIENV.js → dist-gyzurUDR.js} +1 -1
- package/dist/client/assets/{dist-DSCjkO-y.js → dist-qG53hT1b.js} +1 -1
- package/dist/client/assets/{dist-CNP-Q5Gs.js → dist-r4Kq1ABA.js} +1 -1
- package/dist/client/assets/{index-CNoiRdJC.js → index-CNbh1fL2.js} +14 -14
- package/dist/client/assets/index-DCSFD4VV.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/server/application/conversation-service.d.ts +13 -4
- package/dist/server/application/conversation-service.js +112 -61
- package/dist/server/application/run-service.d.ts +13 -0
- package/dist/server/application/run-service.js +255 -69
- package/dist/server/application/scheduled-task-service.js +8 -1
- package/dist/server/application/session-orchestrator-service.d.ts +113 -0
- package/dist/server/application/session-orchestrator-service.js +234 -0
- package/dist/server/application/workspace-service.js +16 -1
- package/dist/server/feishu-cli.js +15 -4
- package/dist/server/file-index.d.ts +30 -0
- package/dist/server/file-index.js +49 -4
- package/dist/server/files.d.ts +21 -0
- package/dist/server/files.js +38 -0
- package/dist/server/http-server.js +1580 -1402
- package/dist/server/index.js +23 -6
- package/dist/server/logging.js +56 -3
- package/dist/server/pi-session-pool.d.ts +2 -0
- package/dist/server/pi-session-pool.js +1 -0
- package/dist/server/pi-session.d.ts +118 -0
- package/dist/server/pi-session.js +132 -10
- package/dist/server/runtime.d.ts +48 -0
- package/dist/server/runtime.js +189 -86
- package/dist/server/server-context.d.ts +2 -0
- package/dist/server/session-ledger.d.ts +60 -0
- package/dist/server/session-ledger.js +76 -0
- package/dist/server/store.d.ts +44 -1
- package/dist/server/store.js +114 -12
- package/dist/server/subagent-runs.d.ts +31 -1
- package/dist/server/subagent-runs.js +48 -20
- package/dist/server/subagents.js +7 -0
- package/dist/server/task-tool.d.ts +18 -0
- package/dist/server/task-tool.js +85 -0
- package/dist/server/tool-runner.js +13 -4
- package/dist/server/types.d.ts +50 -0
- package/dist/server/ws-server.d.ts +86 -6
- package/dist/server/ws-server.js +291 -51
- package/package.json +16 -2
- package/scripts/diagnose.mjs +161 -58
- package/dist/client/assets/index-FxTrUapG.css +0 -1
package/dist/server/types.d.ts
CHANGED
|
@@ -464,6 +464,10 @@ export type Conversation = {
|
|
|
464
464
|
status: RunStatus;
|
|
465
465
|
messages: Message[];
|
|
466
466
|
archivedAt?: string;
|
|
467
|
+
/** Transport projection only: false means messages were omitted, rather than an empty transcript. */
|
|
468
|
+
messagesLoaded?: boolean;
|
|
469
|
+
/** Pending question summary, retained when a focused snapshot omits this conversation's messages. */
|
|
470
|
+
hasPendingQuestion?: boolean;
|
|
467
471
|
/** Pi's own resolved transcript path, observed from this conversation's live worker. It is only a
|
|
468
472
|
* locator: revert still verifies the file header and every retained boundary before writing. */
|
|
469
473
|
piSessionFile?: string;
|
|
@@ -484,6 +488,21 @@ export type Conversation = {
|
|
|
484
488
|
* would answer "what happened" with something the reader has to go and decode.
|
|
485
489
|
*/
|
|
486
490
|
error?: string;
|
|
491
|
+
/**
|
|
492
|
+
* WHY THIS CONVERSATION IS NOT ON THE MODEL THE USER SET FOR IT - in words a person reads.
|
|
493
|
+
*
|
|
494
|
+
* A default model can stop being usable between one session and the next: Pi may drop the model
|
|
495
|
+
* from its list, or the workspace's own model rules may forbid it. The conversation then starts on
|
|
496
|
+
* Pi's own default, which is the right behaviour - but doing it SILENTLY is not: the user set a
|
|
497
|
+
* default, they set a rule, and nobody told them the two contradicted each other (TEST-062).
|
|
498
|
+
*
|
|
499
|
+
* It lives on the conversation rather than on the workspace because that is where the decision
|
|
500
|
+
* was made: a default can be usable for one workspace and unusable for another, and two
|
|
501
|
+
* conversations of the same workspace can disagree if the rules changed in between. It is set
|
|
502
|
+
* ONCE, at birth, and never rewritten afterwards - it describes how this conversation came to be,
|
|
503
|
+
* not what is true right now.
|
|
504
|
+
*/
|
|
505
|
+
modelNotice?: string;
|
|
487
506
|
/** Absent means "Pi's own default", which is why a conversation created before the picker existed still works. */
|
|
488
507
|
model?: ModelSelection;
|
|
489
508
|
thinkingLevel?: string;
|
|
@@ -852,6 +871,29 @@ export type TodoItem = {
|
|
|
852
871
|
status: "pending" | "in_progress" | "completed";
|
|
853
872
|
priority?: "high" | "medium" | "low";
|
|
854
873
|
};
|
|
874
|
+
/** Summary of an orchestrated sibling session, returned by orchestrator queries. */
|
|
875
|
+
export type OrchestratorSessionSummary = {
|
|
876
|
+
conversationId: string;
|
|
877
|
+
workspaceId: string;
|
|
878
|
+
title: string;
|
|
879
|
+
status: RunStatus;
|
|
880
|
+
origin: "user" | "orchestrator";
|
|
881
|
+
parentConversationId?: string;
|
|
882
|
+
task?: string;
|
|
883
|
+
messageCount: number;
|
|
884
|
+
turnCount: number;
|
|
885
|
+
lastAssistantSnippet?: string;
|
|
886
|
+
lastUserSnippet?: string;
|
|
887
|
+
hasPendingQuestion: boolean;
|
|
888
|
+
activeTool?: {
|
|
889
|
+
label: string;
|
|
890
|
+
detail?: string;
|
|
891
|
+
};
|
|
892
|
+
error?: string;
|
|
893
|
+
updatedAt: string;
|
|
894
|
+
createdAt?: number;
|
|
895
|
+
lastProgress?: string;
|
|
896
|
+
};
|
|
855
897
|
/**
|
|
856
898
|
* What Pi reports about ITS OWN queue, forwarded to the browser as it arrives.
|
|
857
899
|
*
|
|
@@ -1194,6 +1236,14 @@ export type ClientCommandBody =
|
|
|
1194
1236
|
type: "stream.configure";
|
|
1195
1237
|
coalesce: boolean;
|
|
1196
1238
|
}
|
|
1239
|
+
/** Selects this socket's transcript; omitted conversationId requests sidebar summaries only. */
|
|
1240
|
+
| {
|
|
1241
|
+
type: "files.index.subscribe";
|
|
1242
|
+
workspaceId?: string;
|
|
1243
|
+
} | {
|
|
1244
|
+
type: "state.subscribe";
|
|
1245
|
+
conversationId?: string;
|
|
1246
|
+
}
|
|
1197
1247
|
/** Asks for the agent catalog read from disk. Answered by `agent.catalog`. */
|
|
1198
1248
|
| {
|
|
1199
1249
|
type: "agent.catalog.fetch";
|
|
@@ -4,6 +4,40 @@ import type { AppState, ServerEvent } from "./types.js";
|
|
|
4
4
|
import type { EventBroadcaster } from "./server-context.js";
|
|
5
5
|
import type { CommandHandler } from "./command-handler.js";
|
|
6
6
|
import type { CatalogService } from "./application/catalog-service.js";
|
|
7
|
+
/**
|
|
8
|
+
* A WebSocket is a live transport, not an unbounded queue. `ws.send()` only
|
|
9
|
+
* copies bytes into the socket's userland buffer; a browser that is frozen or
|
|
10
|
+
* a network peer that has disappeared can therefore make the buffer grow
|
|
11
|
+
* without throwing. Once this threshold is crossed we drop that connection
|
|
12
|
+
* and let the normal close path clean up its resources.
|
|
13
|
+
*
|
|
14
|
+
* AND YET DROPPING IT IS THE WRONG ANSWER FOR A BUSY SERVER. The threshold was
|
|
15
|
+
* written for a peer that has gone away - a frozen tab, a pulled cable. A server
|
|
16
|
+
* that is merely DELIVERING TOO MUCH hits the same number: a sub-agent that
|
|
17
|
+
* streams text emits one `subagent.event` per delta, each of which asks for a
|
|
18
|
+
* full state broadcast, and a browser that cannot parse frames as fast as they
|
|
19
|
+
* arrive lets the buffer grow past the threshold while it is perfectly alive.
|
|
20
|
+
* The browser then reports code 1006 and reconnects, only to be dropped again -
|
|
21
|
+
* "连接中 / 断连 / 连接中" forever - and the user's work is interrupted rather
|
|
22
|
+
* than slowed.
|
|
23
|
+
*
|
|
24
|
+
* So a frame that does not fit is DROPPED, not the connection: the next frame
|
|
25
|
+
* carries the same state, and a browser that is behind will catch up on the next
|
|
26
|
+
* one instead of being disconnected and losing its place. The connection is
|
|
27
|
+
* only terminated when the socket itself is gone (readyState is not OPEN).
|
|
28
|
+
*/
|
|
29
|
+
export declare const MAX_WS_BUFFERED_BYTES: number;
|
|
30
|
+
/** Maximum size of one inbound WebSocket message. Attachments are uploaded
|
|
31
|
+
* over HTTP and commands contain references, so multi-megabyte WS frames are
|
|
32
|
+
* almost certainly malformed or abusive. */
|
|
33
|
+
export declare const MAX_WS_PAYLOAD_BYTES: number;
|
|
34
|
+
/**
|
|
35
|
+
* Send one frame without allowing a race with close/error to escape as an
|
|
36
|
+
* uncaught exception. The `ws` package can throw synchronously after the
|
|
37
|
+
* readyState check (for example when a close happens between the two calls),
|
|
38
|
+
* and an unhandled `error` event can otherwise terminate the Node process.
|
|
39
|
+
*/
|
|
40
|
+
export declare function safeSend(socket: WebSocket, payload: string): boolean;
|
|
7
41
|
/**
|
|
8
42
|
* Concrete implementation of EventBroadcaster delivering server events
|
|
9
43
|
* across active WebSocket connections.
|
|
@@ -11,21 +45,67 @@ import type { CatalogService } from "./application/catalog-service.js";
|
|
|
11
45
|
export declare class WsBroadcaster implements EventBroadcaster {
|
|
12
46
|
private readonly getState;
|
|
13
47
|
private readonly sockets;
|
|
48
|
+
private readonly scopes;
|
|
49
|
+
private readonly fileIndexScopes;
|
|
14
50
|
private readonly coalescedSockets;
|
|
15
51
|
private readonly pendingStreams;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
52
|
+
/**
|
|
53
|
+
* DIAGNOSTIC ONLY - sends every requested state frame immediately instead of merging them.
|
|
54
|
+
*
|
|
55
|
+
* The legacy flood switch (`SUPER_PI_LEGACY_SUBAGENT_FLOOD=1`) restores the pre-fix WIRING: one
|
|
56
|
+
* full state broadcast per sub-agent event. But the 150ms merge window would still fold those
|
|
57
|
+
* broadcasts into one frame, so the "before" measurement would not actually be "before" - it
|
|
58
|
+
* would show a flood that the fixed server also survives, and the A/B comparison would prove
|
|
59
|
+
* nothing. This flag removes the window as well, so the probe can reproduce the real pre-fix
|
|
60
|
+
* wire shape: one frame per request, sent at once.
|
|
61
|
+
*
|
|
62
|
+
* Never set outside a probe or a regression test that is asserting the old behaviour.
|
|
63
|
+
*/
|
|
64
|
+
private readonly sendStateImmediately;
|
|
65
|
+
constructor(getState: (scope?: {
|
|
66
|
+
conversationId?: string;
|
|
67
|
+
}) => AppState);
|
|
68
|
+
register(socket: WebSocket, scope?: {
|
|
69
|
+
conversationId?: string;
|
|
70
|
+
}): void;
|
|
21
71
|
unregister(socket: WebSocket): void;
|
|
72
|
+
subscribe(socket: WebSocket, conversationId?: string): void;
|
|
73
|
+
sendState(socket: WebSocket): void;
|
|
74
|
+
subscribeFileIndex(socket: WebSocket, workspaceId?: string): void;
|
|
75
|
+
private receives;
|
|
22
76
|
configureStreaming(socket: WebSocket, coalesce: boolean): void;
|
|
23
77
|
private flushStreaming;
|
|
24
78
|
private enqueueStreaming;
|
|
25
79
|
getSockets(): Set<WebSocket>;
|
|
26
80
|
broadcast(event: ServerEvent): void;
|
|
81
|
+
/**
|
|
82
|
+
* BROADCAST STATES IN A TIME WINDOW, NOT IN A MICROTASK.
|
|
83
|
+
*
|
|
84
|
+
* The microtask flag this replaces merged only the calls that arrived within the
|
|
85
|
+
* SAME tick. A sub-agent that streams text emits one `subagent.event` per delta,
|
|
86
|
+
* each asking for a full state broadcast, and those deltas arrive across many
|
|
87
|
+
* ticks - so a single sub-agent run could ask for HUNDREDS of full state
|
|
88
|
+
* broadcasts. On a machine whose state is large, that is a flood the browser
|
|
89
|
+
* cannot drain: its parse queue falls behind, the socket buffer grows, and the
|
|
90
|
+
* connection is dropped (the browser reports 1006).
|
|
91
|
+
*
|
|
92
|
+
* A window turns a burst into a handful of frames. The state a browser receives
|
|
93
|
+
* is the LATEST state - the intermediate ones carried nothing the last one did
|
|
94
|
+
* not - so nothing is lost by sending fewer of them. The only thing that
|
|
95
|
+
* changes is how promptly the browser sees a change, and 150ms is below the
|
|
96
|
+
* threshold at which a person notices.
|
|
97
|
+
*/
|
|
98
|
+
private stateFlushScheduled;
|
|
27
99
|
broadcastState(): void;
|
|
28
|
-
|
|
100
|
+
private flushState;
|
|
101
|
+
/**
|
|
102
|
+
* Releases the pending state window, so a shutting-down server does not hold the event loop
|
|
103
|
+
* open on a timer whose flush would send to sockets that are already closed.
|
|
104
|
+
*/
|
|
105
|
+
dispose(): void;
|
|
106
|
+
getStateSnapshot(scope?: {
|
|
107
|
+
conversationId?: string;
|
|
108
|
+
}): AppState;
|
|
29
109
|
}
|
|
30
110
|
export interface WsServerOptions {
|
|
31
111
|
httpServer: NodeHttpServer;
|