@av-pi-studio/client 0.0.1
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/dist/.tsbuildinfo +1 -0
- package/dist/daemon-client.d.ts +115 -0
- package/dist/daemon-client.d.ts.map +1 -0
- package/dist/daemon-client.js +318 -0
- package/dist/daemon-client.js.map +1 -0
- package/dist/file-transfer-client.d.ts +30 -0
- package/dist/file-transfer-client.d.ts.map +1 -0
- package/dist/file-transfer-client.js +83 -0
- package/dist/file-transfer-client.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/pistudio-client.d.ts +122 -0
- package/dist/pistudio-client.d.ts.map +1 -0
- package/dist/pistudio-client.js +155 -0
- package/dist/pistudio-client.js.map +1 -0
- package/dist/reconnect.d.ts +68 -0
- package/dist/reconnect.d.ts.map +1 -0
- package/dist/reconnect.js +103 -0
- package/dist/reconnect.js.map +1 -0
- package/dist/terminal-stream-router.d.ts +38 -0
- package/dist/terminal-stream-router.d.ts.map +1 -0
- package/dist/terminal-stream-router.js +62 -0
- package/dist/terminal-stream-router.js.map +1 -0
- package/dist/transport.d.ts +44 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +80 -0
- package/dist/transport.js.map +1 -0
- package/package.json +23 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {} from "@av-pi-studio/protocol";
|
|
2
|
+
function concat(chunks) {
|
|
3
|
+
const total = chunks.reduce((sum, c) => sum + c.length, 0);
|
|
4
|
+
const out = new Uint8Array(total);
|
|
5
|
+
let offset = 0;
|
|
6
|
+
for (const chunk of chunks) {
|
|
7
|
+
out.set(chunk, offset);
|
|
8
|
+
offset += chunk.length;
|
|
9
|
+
}
|
|
10
|
+
return out;
|
|
11
|
+
}
|
|
12
|
+
export class FileTransferClient {
|
|
13
|
+
daemon;
|
|
14
|
+
pending = new Map();
|
|
15
|
+
nextStream = 1;
|
|
16
|
+
detach = null;
|
|
17
|
+
constructor(daemon) {
|
|
18
|
+
this.daemon = daemon;
|
|
19
|
+
}
|
|
20
|
+
/** Begin routing inbound file-transfer frames. Idempotent. */
|
|
21
|
+
start() {
|
|
22
|
+
if (this.detach)
|
|
23
|
+
return;
|
|
24
|
+
this.detach = this.daemon.onFileTransferFrame((frame) => this.dispatch(frame));
|
|
25
|
+
}
|
|
26
|
+
/** Stop routing inbound frames. Any downloads still pending are rejected. */
|
|
27
|
+
stop() {
|
|
28
|
+
this.detach?.();
|
|
29
|
+
this.detach = null;
|
|
30
|
+
for (const [stream, pending] of this.pending) {
|
|
31
|
+
pending.reject(new Error("file transfer router stopped"));
|
|
32
|
+
this.pending.delete(stream);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Download the file at `path`: requests a single-use token, then requests the chunked
|
|
37
|
+
* transfer, assembling `Begin → Chunk* → End` frames into one buffer.
|
|
38
|
+
*/
|
|
39
|
+
async download(path) {
|
|
40
|
+
const tokenResponse = await this.daemon.request("file_download_token_request", { path });
|
|
41
|
+
if (!tokenResponse.ok || !tokenResponse.token) {
|
|
42
|
+
throw new Error(tokenResponse.error ?? "failed to issue download token");
|
|
43
|
+
}
|
|
44
|
+
const stream = this.nextStream++;
|
|
45
|
+
const result = new Promise((resolve, reject) => {
|
|
46
|
+
this.pending.set(stream, { chunks: [], meta: {}, resolve, reject });
|
|
47
|
+
});
|
|
48
|
+
const requestResponse = await this.daemon.request("file_download_request", { token: tokenResponse.token, stream });
|
|
49
|
+
if (!requestResponse.ok) {
|
|
50
|
+
this.pending.delete(stream);
|
|
51
|
+
throw new Error(requestResponse.error ?? "download request failed");
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
dispatch(frame) {
|
|
56
|
+
const pending = this.pending.get(frame.stream);
|
|
57
|
+
if (!pending)
|
|
58
|
+
return; // not a download stream we're tracking (e.g. an upload) — ignore
|
|
59
|
+
switch (frame.opcode) {
|
|
60
|
+
case "Begin":
|
|
61
|
+
pending.meta.fileName = frame.meta.fileName;
|
|
62
|
+
pending.meta.mimeType = frame.meta.mimeType;
|
|
63
|
+
return;
|
|
64
|
+
case "Chunk":
|
|
65
|
+
pending.chunks.push(frame.data);
|
|
66
|
+
return;
|
|
67
|
+
case "End":
|
|
68
|
+
this.pending.delete(frame.stream);
|
|
69
|
+
if (frame.ok) {
|
|
70
|
+
pending.resolve({ bytes: concat(pending.chunks), ...pending.meta });
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
pending.reject(new Error("download failed"));
|
|
74
|
+
}
|
|
75
|
+
return;
|
|
76
|
+
case "Error":
|
|
77
|
+
this.pending.delete(frame.stream);
|
|
78
|
+
pending.reject(new Error(frame.message));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=file-transfer-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-transfer-client.js","sourceRoot":"","sources":["../src/file-transfer-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const CLIENT_PACKAGE: "@av-pi-studio/client";
|
|
2
|
+
/** Proves the client consumes protocol's emitted declarations. */
|
|
3
|
+
export declare const PROTOCOL_DEP: "@av-pi-studio/protocol";
|
|
4
|
+
export * from "./transport.js";
|
|
5
|
+
export * from "./daemon-client.js";
|
|
6
|
+
export * from "./pistudio-client.js";
|
|
7
|
+
export * from "./terminal-stream-router.js";
|
|
8
|
+
export * from "./file-transfer-client.js";
|
|
9
|
+
export * from "./reconnect.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,EAAG,sBAA+B,CAAC;AAE9D,kEAAkE;AAClE,eAAO,MAAM,YAAY,0BAAmB,CAAC;AAG7C,cAAc,gBAAgB,CAAC;AAG/B,cAAc,oBAAoB,CAAC;AAGnC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,6BAA6B,CAAC;AAG5C,cAAc,2BAA2B,CAAC;AAG1C,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// @av-pi-studio/client — low-level daemon WS driver + Pi-StudioClient SDK facade.
|
|
2
|
+
import { PROTOCOL_PACKAGE } from "@av-pi-studio/protocol";
|
|
3
|
+
export const CLIENT_PACKAGE = "@av-pi-studio/client";
|
|
4
|
+
/** Proves the client consumes protocol's emitted declarations. */
|
|
5
|
+
export const PROTOCOL_DEP = PROTOCOL_PACKAGE;
|
|
6
|
+
// Transport abstraction (direct WS; relay rides the same API).
|
|
7
|
+
export * from "./transport.js";
|
|
8
|
+
// Low-level daemon WebSocket driver.
|
|
9
|
+
export * from "./daemon-client.js";
|
|
10
|
+
// High-level PiStudioClient SDK facade + handles.
|
|
11
|
+
export * from "./pistudio-client.js";
|
|
12
|
+
// Terminal-stream router (binary frame demux per slot).
|
|
13
|
+
export * from "./terminal-stream-router.js";
|
|
14
|
+
// File-transfer client (binary download frame demux + assembly).
|
|
15
|
+
export * from "./file-transfer-client.js";
|
|
16
|
+
// Reconnection + capability-rehydrate driver.
|
|
17
|
+
export * from "./reconnect.js";
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,CAAC,MAAM,cAAc,GAAG,sBAA+B,CAAC;AAE9D,kEAAkE;AAClE,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAE7C,+DAA+D;AAC/D,cAAc,gBAAgB,CAAC;AAE/B,qCAAqC;AACrC,cAAc,oBAAoB,CAAC;AAEnC,kDAAkD;AAClD,cAAc,sBAAsB,CAAC;AAErC,wDAAwD;AACxD,cAAc,6BAA6B,CAAC;AAE5C,iEAAiE;AACjE,cAAc,2BAA2B,CAAC;AAE1C,8CAA8C;AAC9C,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { AgentStreamEvent, CreateAgentRequest, FetchAgentTimelineResponse, SessionMessage, TimelineDirection } from "@av-pi-studio/protocol";
|
|
2
|
+
import type { DaemonClient } from "./daemon-client.js";
|
|
3
|
+
/**
|
|
4
|
+
* High-level `PiStudioClient` SDK facade over the low-level `DaemonClient` driver.
|
|
5
|
+
*
|
|
6
|
+
* Exposes workspace/agent/provider handles plus update handler registration, mirroring the
|
|
7
|
+
* scope's `Pi-StudioClient` surface (architecture/client-app-runtime.md § Layered client library /
|
|
8
|
+
* Facade and features/agent-sessions.md § Public Contract). Method names follow the server RPC
|
|
9
|
+
* type names (`create_agent_request`, `send_agent_prompt`, `interrupt_agent`, `update_agent`,
|
|
10
|
+
* `resume_agent`, `import_agent_session`, `fetch_agent_timeline_request`).
|
|
11
|
+
*
|
|
12
|
+
* Out of scope: app runtime controller (sprint-012), terminal router (task-003).
|
|
13
|
+
*/
|
|
14
|
+
export type PiStudioAgentUpdateHandler = (update: AgentUpdateMessage) => void;
|
|
15
|
+
export type PiStudioWorkspaceUpdateHandler = (update: WorkspaceUpdateMessage) => void;
|
|
16
|
+
export type PiStudioAgentStreamHandler = (event: AgentStreamEvent) => void;
|
|
17
|
+
/** Shape of an inbound `agent_update` session message (append-only; passthrough). */
|
|
18
|
+
export interface AgentUpdateMessage {
|
|
19
|
+
type: "agent_update";
|
|
20
|
+
agentId: string;
|
|
21
|
+
status?: string;
|
|
22
|
+
title?: string;
|
|
23
|
+
labels?: Record<string, string>;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
/** Shape of an inbound `workspace_update` session message. */
|
|
27
|
+
export interface WorkspaceUpdateMessage {
|
|
28
|
+
type: "workspace_update";
|
|
29
|
+
workspaceId: string;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
}
|
|
32
|
+
export interface PiStudioAgentTimelineHandle {
|
|
33
|
+
/** Fetch a bounded page of authoritative timeline history. */
|
|
34
|
+
fetch(opts?: {
|
|
35
|
+
cursor?: string;
|
|
36
|
+
direction?: TimelineDirection;
|
|
37
|
+
limit?: number;
|
|
38
|
+
}): Promise<FetchAgentTimelineResponse>;
|
|
39
|
+
/** Subscribe to live `agent_stream` events for this agent. Returns an unsubscribe fn. */
|
|
40
|
+
subscribe(handler: PiStudioAgentStreamHandler): () => void;
|
|
41
|
+
}
|
|
42
|
+
export interface PiStudioAgentActions {
|
|
43
|
+
readonly agentId: string;
|
|
44
|
+
readonly timeline: PiStudioAgentTimelineHandle;
|
|
45
|
+
/** Send a follow-up prompt to the running/idle agent. */
|
|
46
|
+
send(prompt: string, opts?: {
|
|
47
|
+
clientMessageId?: string;
|
|
48
|
+
images?: unknown[];
|
|
49
|
+
}): Promise<unknown>;
|
|
50
|
+
/** Alias for `send` reflecting the scope's "run a turn" verb. */
|
|
51
|
+
run(prompt: string, opts?: {
|
|
52
|
+
clientMessageId?: string;
|
|
53
|
+
images?: unknown[];
|
|
54
|
+
}): Promise<unknown>;
|
|
55
|
+
/** Interrupt the current turn. */
|
|
56
|
+
interrupt(): Promise<unknown>;
|
|
57
|
+
/** Update model/mode/thinking/features/title/labels without recreating the session. */
|
|
58
|
+
update(patch: {
|
|
59
|
+
modeId?: string;
|
|
60
|
+
model?: string;
|
|
61
|
+
thinkingOptionId?: string;
|
|
62
|
+
featureValues?: Record<string, unknown>;
|
|
63
|
+
title?: string;
|
|
64
|
+
labels?: Record<string, string>;
|
|
65
|
+
}): Promise<unknown>;
|
|
66
|
+
/** Resume a closed session via its persistence handle. */
|
|
67
|
+
resume(): Promise<unknown>;
|
|
68
|
+
/** Archive (soft-delete) the agent — closes the runtime, keeps the record for resume. */
|
|
69
|
+
archive(): Promise<unknown>;
|
|
70
|
+
/** Permanently delete the agent's persisted record (hard delete — no trace, cannot resume). */
|
|
71
|
+
delete(): Promise<unknown>;
|
|
72
|
+
/** Subscribe to `agent_update` events scoped to this agent. */
|
|
73
|
+
onUpdate(handler: PiStudioAgentUpdateHandler): () => void;
|
|
74
|
+
}
|
|
75
|
+
export interface PiStudioWorkspaceActions {
|
|
76
|
+
readonly workspaceId: string;
|
|
77
|
+
/** Subscribe to `workspace_update` events scoped to this workspace. */
|
|
78
|
+
onUpdate(handler: PiStudioWorkspaceUpdateHandler): () => void;
|
|
79
|
+
}
|
|
80
|
+
export interface PiStudioProviderActions {
|
|
81
|
+
/** List available providers. */
|
|
82
|
+
listProviders(): Promise<unknown>;
|
|
83
|
+
/** List models for a provider. */
|
|
84
|
+
listModels(provider: string): Promise<unknown>;
|
|
85
|
+
/** List modes for a provider. */
|
|
86
|
+
listModes(provider: string): Promise<unknown>;
|
|
87
|
+
/** Trigger an explicit provider snapshot refresh (no hidden revalidation). */
|
|
88
|
+
refreshSnapshot(): Promise<unknown>;
|
|
89
|
+
}
|
|
90
|
+
export declare class PiStudioClient {
|
|
91
|
+
private readonly daemon;
|
|
92
|
+
constructor(daemon: DaemonClient);
|
|
93
|
+
get connection(): DaemonClient;
|
|
94
|
+
/**
|
|
95
|
+
* Create a new agent session. Returns the response payload (includes `agentId`). When
|
|
96
|
+
* `initialPrompt` is set, the daemon runs the first turn and streams events to subscribers.
|
|
97
|
+
*/
|
|
98
|
+
createAgent(req: Omit<CreateAgentRequest, "type" | "requestId"> & {
|
|
99
|
+
requestId?: string;
|
|
100
|
+
}): Promise<{
|
|
101
|
+
agentId: string;
|
|
102
|
+
[key: string]: unknown;
|
|
103
|
+
}>;
|
|
104
|
+
/** Get an agent handle for an existing agentId. */
|
|
105
|
+
agent(agentId: string): PiStudioAgentActions;
|
|
106
|
+
/** Get a workspace handle for an existing workspaceId. */
|
|
107
|
+
workspace(workspaceId: string): PiStudioWorkspaceActions;
|
|
108
|
+
/** Provider actions (list providers/models/modes, refresh snapshot). */
|
|
109
|
+
get providers(): PiStudioProviderActions;
|
|
110
|
+
/** Subscribe to ALL `agent_update` events (any agent). */
|
|
111
|
+
onAgentUpdate(handler: PiStudioAgentUpdateHandler): () => void;
|
|
112
|
+
/** Subscribe to ALL `workspace_update` events (any workspace). */
|
|
113
|
+
onWorkspaceUpdate(handler: PiStudioWorkspaceUpdateHandler): () => void;
|
|
114
|
+
}
|
|
115
|
+
/** Convenience re-export of the import operation (not agent-scoped). */
|
|
116
|
+
export declare function importAgentSession(daemon: DaemonClient, args: {
|
|
117
|
+
provider: string;
|
|
118
|
+
cwd: string;
|
|
119
|
+
providerHandleId: string;
|
|
120
|
+
}): Promise<unknown>;
|
|
121
|
+
export type { SessionMessage };
|
|
122
|
+
//# sourceMappingURL=pistudio-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pistudio-client.d.ts","sourceRoot":"","sources":["../src/pistudio-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// ─── Facade implementation ──────────────────────────────────────────────────────
|
|
2
|
+
export class PiStudioClient {
|
|
3
|
+
daemon;
|
|
4
|
+
constructor(daemon) {
|
|
5
|
+
this.daemon = daemon;
|
|
6
|
+
}
|
|
7
|
+
get connection() {
|
|
8
|
+
return this.daemon;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Create a new agent session. Returns the response payload (includes `agentId`). When
|
|
12
|
+
* `initialPrompt` is set, the daemon runs the first turn and streams events to subscribers.
|
|
13
|
+
*/
|
|
14
|
+
async createAgent(req) {
|
|
15
|
+
const payload = await this.daemon.request("create_agent_request", {
|
|
16
|
+
...req,
|
|
17
|
+
});
|
|
18
|
+
return payload;
|
|
19
|
+
}
|
|
20
|
+
/** Get an agent handle for an existing agentId. */
|
|
21
|
+
agent(agentId) {
|
|
22
|
+
return new AgentHandle(this.daemon, agentId);
|
|
23
|
+
}
|
|
24
|
+
/** Get a workspace handle for an existing workspaceId. */
|
|
25
|
+
workspace(workspaceId) {
|
|
26
|
+
return new WorkspaceHandle(this.daemon, workspaceId);
|
|
27
|
+
}
|
|
28
|
+
/** Provider actions (list providers/models/modes, refresh snapshot). */
|
|
29
|
+
get providers() {
|
|
30
|
+
return new ProviderHandle(this.daemon);
|
|
31
|
+
}
|
|
32
|
+
/** Subscribe to ALL `agent_update` events (any agent). */
|
|
33
|
+
onAgentUpdate(handler) {
|
|
34
|
+
return this.daemon.onSessionMessage((msg) => {
|
|
35
|
+
if (msg.type === "agent_update") {
|
|
36
|
+
handler(msg);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** Subscribe to ALL `workspace_update` events (any workspace). */
|
|
41
|
+
onWorkspaceUpdate(handler) {
|
|
42
|
+
return this.daemon.onSessionMessage((msg) => {
|
|
43
|
+
if (msg.type === "workspace_update") {
|
|
44
|
+
handler(msg);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// ─── Handle classes ──────────────────────────────────────────────────────────────
|
|
50
|
+
class TimelineHandle {
|
|
51
|
+
daemon;
|
|
52
|
+
agentId;
|
|
53
|
+
constructor(daemon, agentId) {
|
|
54
|
+
this.daemon = daemon;
|
|
55
|
+
this.agentId = agentId;
|
|
56
|
+
}
|
|
57
|
+
fetch(opts = {}) {
|
|
58
|
+
return this.daemon.request("fetch_agent_timeline_request", {
|
|
59
|
+
agentId: this.agentId,
|
|
60
|
+
cursor: opts.cursor,
|
|
61
|
+
direction: opts.direction,
|
|
62
|
+
limit: opts.limit,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
subscribe(handler) {
|
|
66
|
+
return this.daemon.onSessionMessage((msg) => {
|
|
67
|
+
const m = msg;
|
|
68
|
+
if (m.type === "agent_stream" && m.agentId === this.agentId && m.event) {
|
|
69
|
+
handler(m.event);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
class AgentHandle {
|
|
75
|
+
daemon;
|
|
76
|
+
agentId;
|
|
77
|
+
timeline;
|
|
78
|
+
constructor(daemon, agentId) {
|
|
79
|
+
this.daemon = daemon;
|
|
80
|
+
this.agentId = agentId;
|
|
81
|
+
this.timeline = new TimelineHandle(daemon, agentId);
|
|
82
|
+
}
|
|
83
|
+
send(prompt, opts = {}) {
|
|
84
|
+
return this.daemon.request("send_agent_prompt", {
|
|
85
|
+
agentId: this.agentId,
|
|
86
|
+
prompt,
|
|
87
|
+
clientMessageId: opts.clientMessageId,
|
|
88
|
+
images: opts.images,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
run(prompt, opts) {
|
|
92
|
+
return this.send(prompt, opts);
|
|
93
|
+
}
|
|
94
|
+
interrupt() {
|
|
95
|
+
return this.daemon.request("interrupt_agent", { agentId: this.agentId });
|
|
96
|
+
}
|
|
97
|
+
update(patch) {
|
|
98
|
+
return this.daemon.request("update_agent", { agentId: this.agentId, ...patch });
|
|
99
|
+
}
|
|
100
|
+
resume() {
|
|
101
|
+
return this.daemon.request("resume_agent", { agentId: this.agentId });
|
|
102
|
+
}
|
|
103
|
+
archive() {
|
|
104
|
+
return this.daemon.request("archive_agent", { agentId: this.agentId });
|
|
105
|
+
}
|
|
106
|
+
delete() {
|
|
107
|
+
return this.daemon.request("delete_agent", { agentId: this.agentId });
|
|
108
|
+
}
|
|
109
|
+
onUpdate(handler) {
|
|
110
|
+
return this.daemon.onSessionMessage((msg) => {
|
|
111
|
+
const m = msg;
|
|
112
|
+
if (m.type === "agent_update" && m.agentId === this.agentId)
|
|
113
|
+
handler(m);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
class WorkspaceHandle {
|
|
118
|
+
daemon;
|
|
119
|
+
workspaceId;
|
|
120
|
+
constructor(daemon, workspaceId) {
|
|
121
|
+
this.daemon = daemon;
|
|
122
|
+
this.workspaceId = workspaceId;
|
|
123
|
+
}
|
|
124
|
+
onUpdate(handler) {
|
|
125
|
+
return this.daemon.onSessionMessage((msg) => {
|
|
126
|
+
const m = msg;
|
|
127
|
+
if (m.type === "workspace_update" && m.workspaceId === this.workspaceId)
|
|
128
|
+
handler(m);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
class ProviderHandle {
|
|
133
|
+
daemon;
|
|
134
|
+
constructor(daemon) {
|
|
135
|
+
this.daemon = daemon;
|
|
136
|
+
}
|
|
137
|
+
listProviders() {
|
|
138
|
+
return this.daemon.request("list_providers", {});
|
|
139
|
+
}
|
|
140
|
+
listModels(provider) {
|
|
141
|
+
return this.daemon.request("list_provider_models", { provider });
|
|
142
|
+
}
|
|
143
|
+
listModes(provider) {
|
|
144
|
+
return this.daemon.request("list_provider_modes", { provider });
|
|
145
|
+
}
|
|
146
|
+
refreshSnapshot() {
|
|
147
|
+
// Dotted-namespace RPC per the protocol convention.
|
|
148
|
+
return this.daemon.request("providers.snapshot.refresh.request", {});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** Convenience re-export of the import operation (not agent-scoped). */
|
|
152
|
+
export function importAgentSession(daemon, args) {
|
|
153
|
+
return daemon.request("import_agent_session", args);
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=pistudio-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pistudio-client.js","sourceRoot":"","sources":["../src/pistudio-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { DaemonClient } from "./daemon-client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reconnection + capability-rehydrate driver (architecture/client-app-runtime.md § Connection,
|
|
4
|
+
* § Error Handling; architecture/websocket-protocol.md § Behavior / on reconnect).
|
|
5
|
+
*
|
|
6
|
+
* On socket drop, backoff-reconnect, re-`hello` (the `DaemonClient.connect()` resends the same
|
|
7
|
+
* capabilities), and rehydrate the recorded `serverId`/`features`. Timeline resume planning lives
|
|
8
|
+
* in sprint-012; this driver exposes the hooks (`onReconnected`) the planner rides on.
|
|
9
|
+
*
|
|
10
|
+
* Reconnection backoff parameters are TODO(verify) — defaults below are conservative.
|
|
11
|
+
*/
|
|
12
|
+
export interface ReconnectionOptions {
|
|
13
|
+
/** Initial backoff delay (ms). Default 500. */
|
|
14
|
+
initialDelayMs?: number;
|
|
15
|
+
/** Maximum backoff delay (ms). Default 30_000. */
|
|
16
|
+
maxDelayMs?: number;
|
|
17
|
+
/** Exponential growth factor. Default 2. */
|
|
18
|
+
factor?: number;
|
|
19
|
+
/** Random jitter ratio [0..1] applied to each delay. Default 0.2. */
|
|
20
|
+
jitter?: number;
|
|
21
|
+
/** Max reconnect attempts before giving up (Infinity = never). Default Infinity. */
|
|
22
|
+
maxAttempts?: number;
|
|
23
|
+
/** Injected timer scheduler (tests). Defaults to setTimeout. */
|
|
24
|
+
setTimer?: (cb: () => void, ms: number) => unknown;
|
|
25
|
+
clearTimer?: (handle: unknown) => void;
|
|
26
|
+
/** Injected RNG in [0,1) (tests). Defaults to Math.random. */
|
|
27
|
+
random?: () => number;
|
|
28
|
+
}
|
|
29
|
+
export type ReconnectedHandler = (info: {
|
|
30
|
+
attempt: number;
|
|
31
|
+
serverId: string | null;
|
|
32
|
+
}) => void;
|
|
33
|
+
export type ReconnectFailedHandler = (error: unknown, attempt: number) => void;
|
|
34
|
+
export declare class ReconnectionManager {
|
|
35
|
+
private readonly daemon;
|
|
36
|
+
private readonly initialDelayMs;
|
|
37
|
+
private readonly maxDelayMs;
|
|
38
|
+
private readonly factor;
|
|
39
|
+
private readonly jitter;
|
|
40
|
+
private readonly maxAttempts;
|
|
41
|
+
private readonly setTimer;
|
|
42
|
+
private readonly clearTimer;
|
|
43
|
+
private readonly random;
|
|
44
|
+
private attempt;
|
|
45
|
+
private timer;
|
|
46
|
+
private active;
|
|
47
|
+
private detachState;
|
|
48
|
+
private readonly reconnectedHandlers;
|
|
49
|
+
private readonly failedHandlers;
|
|
50
|
+
constructor(daemon: DaemonClient, options?: ReconnectionOptions);
|
|
51
|
+
/** Compute the backoff delay for a given attempt number (1-based), with jitter. */
|
|
52
|
+
delayForAttempt(attempt: number): number;
|
|
53
|
+
/** Subscribe to successful reconnections (after re-handshake + rehydrate). */
|
|
54
|
+
onReconnected(handler: ReconnectedHandler): () => void;
|
|
55
|
+
/** Subscribe to reconnect attempt failures. */
|
|
56
|
+
onReconnectFailed(handler: ReconnectFailedHandler): () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Start watching the daemon connection. On a `closed` transition, schedule a backoff reconnect.
|
|
59
|
+
*/
|
|
60
|
+
start(): void;
|
|
61
|
+
/** Stop watching and cancel any pending reconnect. */
|
|
62
|
+
stop(): void;
|
|
63
|
+
/** Number of reconnect attempts made since the last healthy open. */
|
|
64
|
+
get attemptCount(): number;
|
|
65
|
+
private scheduleReconnect;
|
|
66
|
+
private tryReconnect;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=reconnect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../src/reconnect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;;;;;GASG;AAEH,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,KAAK,IAAI,CAAC;AAC9F,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAE/E,qBAAa,mBAAmB;IAmB5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAlBzB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IAEtC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAA6B;IAEhD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAiC;IACrE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqC;gBAGjD,MAAM,EAAE,YAAY,EACrC,OAAO,GAAE,mBAAwB;IAanC,mFAAmF;IACnF,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAMxC,8EAA8E;IAC9E,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI;IAKtD,+CAA+C;IAC/C,iBAAiB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,IAAI;IAK9D;;OAEG;IACH,KAAK,IAAI,IAAI;IASb,sDAAsD;IACtD,IAAI,IAAI,IAAI;IAQZ,qEAAqE;IACrE,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,OAAO,CAAC,iBAAiB;YAWX,YAAY;CAe3B"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export class ReconnectionManager {
|
|
2
|
+
daemon;
|
|
3
|
+
initialDelayMs;
|
|
4
|
+
maxDelayMs;
|
|
5
|
+
factor;
|
|
6
|
+
jitter;
|
|
7
|
+
maxAttempts;
|
|
8
|
+
setTimer;
|
|
9
|
+
clearTimer;
|
|
10
|
+
random;
|
|
11
|
+
attempt = 0;
|
|
12
|
+
timer = null;
|
|
13
|
+
active = false;
|
|
14
|
+
detachState = null;
|
|
15
|
+
reconnectedHandlers = new Set();
|
|
16
|
+
failedHandlers = new Set();
|
|
17
|
+
constructor(daemon, options = {}) {
|
|
18
|
+
this.daemon = daemon;
|
|
19
|
+
this.initialDelayMs = options.initialDelayMs ?? 500;
|
|
20
|
+
this.maxDelayMs = options.maxDelayMs ?? 30_000;
|
|
21
|
+
this.factor = options.factor ?? 2;
|
|
22
|
+
this.jitter = options.jitter ?? 0.2;
|
|
23
|
+
this.maxAttempts = options.maxAttempts ?? Number.POSITIVE_INFINITY;
|
|
24
|
+
this.setTimer = options.setTimer ?? ((cb, ms) => setTimeout(cb, ms));
|
|
25
|
+
this.clearTimer =
|
|
26
|
+
options.clearTimer ?? ((h) => clearTimeout(h));
|
|
27
|
+
this.random = options.random ?? Math.random;
|
|
28
|
+
}
|
|
29
|
+
/** Compute the backoff delay for a given attempt number (1-based), with jitter. */
|
|
30
|
+
delayForAttempt(attempt) {
|
|
31
|
+
const base = Math.min(this.maxDelayMs, this.initialDelayMs * this.factor ** (attempt - 1));
|
|
32
|
+
const jitterAmount = base * this.jitter * (this.random() * 2 - 1);
|
|
33
|
+
return Math.max(0, Math.round(base + jitterAmount));
|
|
34
|
+
}
|
|
35
|
+
/** Subscribe to successful reconnections (after re-handshake + rehydrate). */
|
|
36
|
+
onReconnected(handler) {
|
|
37
|
+
this.reconnectedHandlers.add(handler);
|
|
38
|
+
return () => this.reconnectedHandlers.delete(handler);
|
|
39
|
+
}
|
|
40
|
+
/** Subscribe to reconnect attempt failures. */
|
|
41
|
+
onReconnectFailed(handler) {
|
|
42
|
+
this.failedHandlers.add(handler);
|
|
43
|
+
return () => this.failedHandlers.delete(handler);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Start watching the daemon connection. On a `closed` transition, schedule a backoff reconnect.
|
|
47
|
+
*/
|
|
48
|
+
start() {
|
|
49
|
+
if (this.active)
|
|
50
|
+
return;
|
|
51
|
+
this.active = true;
|
|
52
|
+
this.detachState = this.daemon.onStateChange((state) => {
|
|
53
|
+
if (state === "closed" && this.active)
|
|
54
|
+
this.scheduleReconnect();
|
|
55
|
+
if (state === "open")
|
|
56
|
+
this.attempt = 0; // reset backoff on a healthy connection
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Stop watching and cancel any pending reconnect. */
|
|
60
|
+
stop() {
|
|
61
|
+
this.active = false;
|
|
62
|
+
if (this.timer)
|
|
63
|
+
this.clearTimer(this.timer);
|
|
64
|
+
this.timer = null;
|
|
65
|
+
this.detachState?.();
|
|
66
|
+
this.detachState = null;
|
|
67
|
+
}
|
|
68
|
+
/** Number of reconnect attempts made since the last healthy open. */
|
|
69
|
+
get attemptCount() {
|
|
70
|
+
return this.attempt;
|
|
71
|
+
}
|
|
72
|
+
scheduleReconnect() {
|
|
73
|
+
if (!this.active)
|
|
74
|
+
return;
|
|
75
|
+
if (this.attempt >= this.maxAttempts)
|
|
76
|
+
return;
|
|
77
|
+
this.attempt += 1;
|
|
78
|
+
const delay = this.delayForAttempt(this.attempt);
|
|
79
|
+
this.timer = this.setTimer(() => {
|
|
80
|
+
this.timer = null;
|
|
81
|
+
void this.tryReconnect();
|
|
82
|
+
}, delay);
|
|
83
|
+
}
|
|
84
|
+
async tryReconnect() {
|
|
85
|
+
if (!this.active)
|
|
86
|
+
return;
|
|
87
|
+
const attempt = this.attempt;
|
|
88
|
+
try {
|
|
89
|
+
// connect() re-sends hello with the same capabilities → daemon rehydrates them, and the
|
|
90
|
+
// client re-records serverId + features from the fresh server_info.
|
|
91
|
+
await this.daemon.connect();
|
|
92
|
+
for (const handler of this.reconnectedHandlers) {
|
|
93
|
+
handler({ attempt, serverId: this.daemon.serverId });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
for (const handler of this.failedHandlers)
|
|
98
|
+
handler(error, attempt);
|
|
99
|
+
this.scheduleReconnect(); // back off and retry
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=reconnect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconnect.js","sourceRoot":"","sources":["../src/reconnect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { DaemonClient } from "./daemon-client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Client-side demux of binary terminal frames to per-slot subscribers, plus outbound input/resize
|
|
4
|
+
* encoding (architecture/client-app-runtime.md § Router; features/terminals.md § Binary stream
|
|
5
|
+
* protocol).
|
|
6
|
+
*
|
|
7
|
+
* Inbound `Output`/`Snapshot`/`Restore` frames are dispatched to the subscriber registered for that
|
|
8
|
+
* `slot`. Outbound `Input`/`Resize` are encoded with the right opcode + slot and sent on the data
|
|
9
|
+
* path.
|
|
10
|
+
*/
|
|
11
|
+
export interface TerminalSlotSubscriber {
|
|
12
|
+
/** Live terminal output bytes. */
|
|
13
|
+
onOutput?: (data: Uint8Array) => void;
|
|
14
|
+
/** Full-screen snapshot bytes (sent on (re)subscribe). */
|
|
15
|
+
onSnapshot?: (data: Uint8Array) => void;
|
|
16
|
+
/** Restore snapshot bytes (reflowable/mode-gated). */
|
|
17
|
+
onRestore?: (data: Uint8Array) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare class TerminalStreamRouter {
|
|
20
|
+
private readonly daemon;
|
|
21
|
+
private readonly subscribers;
|
|
22
|
+
private detach;
|
|
23
|
+
constructor(daemon: DaemonClient);
|
|
24
|
+
/** Begin routing inbound terminal frames. Idempotent. */
|
|
25
|
+
start(): void;
|
|
26
|
+
/** Stop routing inbound frames (subscribers retained). */
|
|
27
|
+
stop(): void;
|
|
28
|
+
/** Register (or replace) the subscriber for a slot. Returns an unsubscribe fn. */
|
|
29
|
+
subscribeSlot(slot: number, subscriber: TerminalSlotSubscriber): () => void;
|
|
30
|
+
/** True iff a subscriber is registered for the slot. */
|
|
31
|
+
hasSlot(slot: number): boolean;
|
|
32
|
+
/** Send raw input bytes to a slot's PTY (opcode `Input = 0x02`). */
|
|
33
|
+
sendInput(slot: number, data: Uint8Array): void;
|
|
34
|
+
/** Send a resize (opcode `Resize = 0x03`, JSON `{ rows, cols }` payload). */
|
|
35
|
+
sendResize(slot: number, rows: number, cols: number): void;
|
|
36
|
+
private dispatch;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=terminal-stream-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-stream-router.d.ts","sourceRoot":"","sources":["../src/terminal-stream-router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;;;;GAQG;AAEH,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,0DAA0D;IAC1D,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACxC,sDAAsD;IACtD,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAED,qBAAa,oBAAoB;IAInB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6C;IACzE,OAAO,CAAC,MAAM,CAA6B;gBAEd,MAAM,EAAE,YAAY;IAEjD,yDAAyD;IACzD,KAAK,IAAI,IAAI;IAKb,0DAA0D;IAC1D,IAAI,IAAI,IAAI;IAKZ,kFAAkF;IAClF,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,sBAAsB,GAAG,MAAM,IAAI;IAO3E,wDAAwD;IACxD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAM9B,oEAAoE;IACpE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI;IAI/C,6EAA6E;IAC7E,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAM1D,OAAO,CAAC,QAAQ;CAkBjB"}
|