@yefengr/remote-pi 0.7.0
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/LICENSE +21 -0
- package/README.md +674 -0
- package/dist/actions/handlers.d.ts +122 -0
- package/dist/actions/handlers.js +160 -0
- package/dist/actions/handlers.js.map +1 -0
- package/dist/actions/registry.d.ts +39 -0
- package/dist/actions/registry.js +58 -0
- package/dist/actions/registry.js.map +1 -0
- package/dist/bin/supervisord.d.ts +2 -0
- package/dist/bin/supervisord.js +86 -0
- package/dist/bin/supervisord.js.map +1 -0
- package/dist/config.d.ts +55 -0
- package/dist/config.js +118 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon/client.d.ts +20 -0
- package/dist/daemon/client.js +131 -0
- package/dist/daemon/client.js.map +1 -0
- package/dist/daemon/control_protocol.d.ts +176 -0
- package/dist/daemon/control_protocol.js +63 -0
- package/dist/daemon/control_protocol.js.map +1 -0
- package/dist/daemon/cron_log.d.ts +45 -0
- package/dist/daemon/cron_log.js +72 -0
- package/dist/daemon/cron_log.js.map +1 -0
- package/dist/daemon/cron_registry.d.ts +80 -0
- package/dist/daemon/cron_registry.js +194 -0
- package/dist/daemon/cron_registry.js.map +1 -0
- package/dist/daemon/id.d.ts +24 -0
- package/dist/daemon/id.js +36 -0
- package/dist/daemon/id.js.map +1 -0
- package/dist/daemon/install.d.ts +170 -0
- package/dist/daemon/install.js +547 -0
- package/dist/daemon/install.js.map +1 -0
- package/dist/daemon/registry.d.ts +63 -0
- package/dist/daemon/registry.js +153 -0
- package/dist/daemon/registry.js.map +1 -0
- package/dist/daemon/rpc_child.d.ts +194 -0
- package/dist/daemon/rpc_child.js +389 -0
- package/dist/daemon/rpc_child.js.map +1 -0
- package/dist/daemon/supervisor.d.ts +93 -0
- package/dist/daemon/supervisor.js +596 -0
- package/dist/daemon/supervisor.js.map +1 -0
- package/dist/extension_ui_bridge.d.ts +26 -0
- package/dist/extension_ui_bridge.js +341 -0
- package/dist/extension_ui_bridge.js.map +1 -0
- package/dist/index.d.ts +214 -0
- package/dist/index.js +5410 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/mesh_result.d.ts +10 -0
- package/dist/mcp/mesh_result.js +42 -0
- package/dist/mcp/mesh_result.js.map +1 -0
- package/dist/mcp/mesh_server.d.ts +16 -0
- package/dist/mcp/mesh_server.js +327 -0
- package/dist/mcp/mesh_server.js.map +1 -0
- package/dist/mesh/canonical.d.ts +30 -0
- package/dist/mesh/canonical.js +61 -0
- package/dist/mesh/canonical.js.map +1 -0
- package/dist/mesh/client.d.ts +18 -0
- package/dist/mesh/client.js +125 -0
- package/dist/mesh/client.js.map +1 -0
- package/dist/mesh/encoding.d.ts +38 -0
- package/dist/mesh/encoding.js +216 -0
- package/dist/mesh/encoding.js.map +1 -0
- package/dist/mesh/self_revoke.d.ts +73 -0
- package/dist/mesh/self_revoke.js +401 -0
- package/dist/mesh/self_revoke.js.map +1 -0
- package/dist/mesh/siblings.d.ts +49 -0
- package/dist/mesh/siblings.js +159 -0
- package/dist/mesh/siblings.js.map +1 -0
- package/dist/mesh/types.d.ts +34 -0
- package/dist/mesh/types.js +11 -0
- package/dist/mesh/types.js.map +1 -0
- package/dist/mesh/verify.d.ts +17 -0
- package/dist/mesh/verify.js +86 -0
- package/dist/mesh/verify.js.map +1 -0
- package/dist/pairing/crypto.d.ts +8 -0
- package/dist/pairing/crypto.js +22 -0
- package/dist/pairing/crypto.js.map +1 -0
- package/dist/pairing/qr.d.ts +59 -0
- package/dist/pairing/qr.js +125 -0
- package/dist/pairing/qr.js.map +1 -0
- package/dist/pairing/storage.d.ts +120 -0
- package/dist/pairing/storage.js +604 -0
- package/dist/pairing/storage.js.map +1 -0
- package/dist/protocol/codec.d.ts +7 -0
- package/dist/protocol/codec.js +49 -0
- package/dist/protocol/codec.js.map +1 -0
- package/dist/protocol/types.d.ts +393 -0
- package/dist/protocol/types.js +2 -0
- package/dist/protocol/types.js.map +1 -0
- package/dist/protocol/v2/codec.d.ts +26 -0
- package/dist/protocol/v2/codec.js +207 -0
- package/dist/protocol/v2/codec.js.map +1 -0
- package/dist/protocol/v2/index.d.ts +3 -0
- package/dist/protocol/v2/index.js +4 -0
- package/dist/protocol/v2/index.js.map +1 -0
- package/dist/protocol/v2/schemas.d.ts +1939 -0
- package/dist/protocol/v2/schemas.js +409 -0
- package/dist/protocol/v2/schemas.js.map +1 -0
- package/dist/protocol/v2/session_state.d.ts +75 -0
- package/dist/protocol/v2/session_state.js +176 -0
- package/dist/protocol/v2/session_state.js.map +1 -0
- package/dist/rooms.d.ts +29 -0
- package/dist/rooms.js +57 -0
- package/dist/rooms.js.map +1 -0
- package/dist/session/bridge.d.ts +37 -0
- package/dist/session/bridge.js +130 -0
- package/dist/session/bridge.js.map +1 -0
- package/dist/session/broker.d.ts +189 -0
- package/dist/session/broker.js +507 -0
- package/dist/session/broker.js.map +1 -0
- package/dist/session/broker_remote.d.ts +74 -0
- package/dist/session/broker_remote.js +583 -0
- package/dist/session/broker_remote.js.map +1 -0
- package/dist/session/cwd_lock.d.ts +33 -0
- package/dist/session/cwd_lock.js +126 -0
- package/dist/session/cwd_lock.js.map +1 -0
- package/dist/session/envelope.d.ts +33 -0
- package/dist/session/envelope.js +117 -0
- package/dist/session/envelope.js.map +1 -0
- package/dist/session/global_config.d.ts +33 -0
- package/dist/session/global_config.js +73 -0
- package/dist/session/global_config.js.map +1 -0
- package/dist/session/ipc.d.ts +27 -0
- package/dist/session/ipc.js +22 -0
- package/dist/session/ipc.js.map +1 -0
- package/dist/session/leader_election.d.ts +32 -0
- package/dist/session/leader_election.js +106 -0
- package/dist/session/leader_election.js.map +1 -0
- package/dist/session/local_config.d.ts +55 -0
- package/dist/session/local_config.js +157 -0
- package/dist/session/local_config.js.map +1 -0
- package/dist/session/mesh_node.d.ts +116 -0
- package/dist/session/mesh_node.js +573 -0
- package/dist/session/mesh_node.js.map +1 -0
- package/dist/session/peer.d.ts +139 -0
- package/dist/session/peer.js +451 -0
- package/dist/session/peer.js.map +1 -0
- package/dist/session/peer_inventory.d.ts +13 -0
- package/dist/session/peer_inventory.js +48 -0
- package/dist/session/peer_inventory.js.map +1 -0
- package/dist/session/peer_limits.d.ts +9 -0
- package/dist/session/peer_limits.js +21 -0
- package/dist/session/peer_limits.js.map +1 -0
- package/dist/session/setup_wizard.d.ts +39 -0
- package/dist/session/setup_wizard.js +63 -0
- package/dist/session/setup_wizard.js.map +1 -0
- package/dist/session/tools.d.ts +24 -0
- package/dist/session/tools.js +252 -0
- package/dist/session/tools.js.map +1 -0
- package/dist/session/wizard.d.ts +13 -0
- package/dist/session/wizard.js +20 -0
- package/dist/session/wizard.js.map +1 -0
- package/dist/timeline/history.d.ts +35 -0
- package/dist/timeline/history.js +381 -0
- package/dist/timeline/history.js.map +1 -0
- package/dist/timeline/runtime.d.ts +76 -0
- package/dist/timeline/runtime.js +428 -0
- package/dist/timeline/runtime.js.map +1 -0
- package/dist/timeline/v2_service.d.ts +54 -0
- package/dist/timeline/v2_service.js +351 -0
- package/dist/timeline/v2_service.js.map +1 -0
- package/dist/transport/peer_channel.d.ts +57 -0
- package/dist/transport/peer_channel.js +170 -0
- package/dist/transport/peer_channel.js.map +1 -0
- package/dist/transport/pi_forward_client.d.ts +29 -0
- package/dist/transport/pi_forward_client.js +62 -0
- package/dist/transport/pi_forward_client.js.map +1 -0
- package/dist/transport/relay_client.d.ts +91 -0
- package/dist/transport/relay_client.js +206 -0
- package/dist/transport/relay_client.js.map +1 -0
- package/dist/ui/footer.d.ts +32 -0
- package/dist/ui/footer.js +34 -0
- package/dist/ui/footer.js.map +1 -0
- package/docs/daemon.md +289 -0
- package/package.json +87 -0
- package/service-templates/launchd.plist.template +35 -0
- package/service-templates/systemd.service.template +19 -0
- package/service-templates/task-launcher.vbs.template +10 -0
- package/service-templates/task-scheduler.xml.template +38 -0
- package/skills/agent-network/SKILL.md +310 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { TimelineEventSchema, V2SessionState, MAX_FRAME_BYTES, MAX_FRAGMENT_DECODE_BYTES, } from "../protocol/v2/index.js";
|
|
2
|
+
import { TimelineHistoryPager } from "./history.js";
|
|
3
|
+
export class TimelineV2Service {
|
|
4
|
+
state;
|
|
5
|
+
pager;
|
|
6
|
+
sessionManager;
|
|
7
|
+
senderRef;
|
|
8
|
+
runtime;
|
|
9
|
+
onUserMessage;
|
|
10
|
+
onCancel;
|
|
11
|
+
requestChannels = new Map();
|
|
12
|
+
generationValue;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.sessionManager = options.sessionManager;
|
|
15
|
+
this.senderRef = options.senderRef;
|
|
16
|
+
this.generationValue = options.generation ?? options.sessionManager.getSessionId();
|
|
17
|
+
this.state = new V2SessionState({ generation: this.generationValue });
|
|
18
|
+
this.runtime = options.runtime;
|
|
19
|
+
this.onUserMessage = options.onUserMessage;
|
|
20
|
+
this.onCancel = options.onCancel;
|
|
21
|
+
this.pager = new TimelineHistoryPager(this.sessionManager, (manager) => this.runtime.recover(manager), () => this.generationValue);
|
|
22
|
+
}
|
|
23
|
+
get generation() {
|
|
24
|
+
return this.generationValue;
|
|
25
|
+
}
|
|
26
|
+
reset(reason) {
|
|
27
|
+
return this.state.snapshot().channels.map((channel) => ({
|
|
28
|
+
protocol_version: 2,
|
|
29
|
+
type: "reset",
|
|
30
|
+
target_channel_id: channel.channelId,
|
|
31
|
+
session_id: this.sessionManager.getSessionId(),
|
|
32
|
+
history_generation: this.generation,
|
|
33
|
+
reason,
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
refreshGeneration(next) {
|
|
37
|
+
if (!next || next === this.generationValue)
|
|
38
|
+
return false;
|
|
39
|
+
this.generationValue = next;
|
|
40
|
+
this.state.setGeneration(next);
|
|
41
|
+
this.requestChannels.clear();
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
handle(frame) {
|
|
45
|
+
switch (frame.type) {
|
|
46
|
+
case "session_hello":
|
|
47
|
+
return [this.ready(frame)];
|
|
48
|
+
case "pair_request":
|
|
49
|
+
return [this.error(frame.id, "protocol_upgrade_required", "pairing is handled before session_hello")];
|
|
50
|
+
case "session_sync":
|
|
51
|
+
return this.handleHistory(frame);
|
|
52
|
+
case "ping":
|
|
53
|
+
return this.handlePing(frame);
|
|
54
|
+
case "cancel":
|
|
55
|
+
return this.handleCancel(frame);
|
|
56
|
+
case "user_message":
|
|
57
|
+
return this.handleUserMessage(frame);
|
|
58
|
+
case "user_message_observed":
|
|
59
|
+
return this.handleObserved(frame);
|
|
60
|
+
case "queued_message_set":
|
|
61
|
+
case "queued_message_clear":
|
|
62
|
+
case "approve_tool":
|
|
63
|
+
case "session_new":
|
|
64
|
+
case "session_compact":
|
|
65
|
+
case "model_set":
|
|
66
|
+
case "thinking_set":
|
|
67
|
+
case "list_models":
|
|
68
|
+
case "extension_ui_response":
|
|
69
|
+
return this.requireReady(frame);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
started(started) {
|
|
73
|
+
const clientRequestId = started.correlation.clientRequestId;
|
|
74
|
+
if (!clientRequestId)
|
|
75
|
+
return [];
|
|
76
|
+
const request = this.findRecord(clientRequestId);
|
|
77
|
+
if (!request)
|
|
78
|
+
return [];
|
|
79
|
+
this.state.update(request.key, "accepted", { messageId: started.eventId, groupId: started.groupId });
|
|
80
|
+
const message = {
|
|
81
|
+
id: started.eventId,
|
|
82
|
+
group_id: started.groupId,
|
|
83
|
+
blocks: started.blocks,
|
|
84
|
+
origin: started.correlation.origin,
|
|
85
|
+
...(started.correlation.senderRef ? { sender_ref: started.correlation.senderRef } : {}),
|
|
86
|
+
delivery: started.correlation.delivery,
|
|
87
|
+
};
|
|
88
|
+
return [
|
|
89
|
+
...this.direct(request.channelId, {
|
|
90
|
+
type: "user_message_status",
|
|
91
|
+
in_reply_to: started.correlation.requestId ?? clientRequestId,
|
|
92
|
+
session_id: this.sessionManager.getSessionId(),
|
|
93
|
+
history_generation: this.generation,
|
|
94
|
+
client_request_id: clientRequestId,
|
|
95
|
+
status: "accepted",
|
|
96
|
+
message_id: started.eventId,
|
|
97
|
+
group_id: started.groupId,
|
|
98
|
+
}),
|
|
99
|
+
...this.direct(request.channelId, {
|
|
100
|
+
type: "user_message_started",
|
|
101
|
+
in_reply_to: started.correlation.requestId ?? clientRequestId,
|
|
102
|
+
session_id: this.sessionManager.getSessionId(),
|
|
103
|
+
history_generation: this.generation,
|
|
104
|
+
message,
|
|
105
|
+
}),
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
commit(clientRequestId, messageId, groupId) {
|
|
109
|
+
const request = this.findRecord(clientRequestId);
|
|
110
|
+
if (!request)
|
|
111
|
+
return [];
|
|
112
|
+
const record = this.state.update(request.key, "committed", { messageId, groupId });
|
|
113
|
+
if (!record)
|
|
114
|
+
return [];
|
|
115
|
+
return this.direct(request.channelId, {
|
|
116
|
+
type: "user_message_status",
|
|
117
|
+
in_reply_to: clientRequestId,
|
|
118
|
+
session_id: this.sessionManager.getSessionId(),
|
|
119
|
+
history_generation: this.generation,
|
|
120
|
+
client_request_id: clientRequestId,
|
|
121
|
+
status: "committed",
|
|
122
|
+
message_id: messageId,
|
|
123
|
+
...(groupId ? { group_id: groupId } : {}),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
canDrain(clientRequestId) {
|
|
127
|
+
return this.findRecord(clientRequestId)?.status === "received";
|
|
128
|
+
}
|
|
129
|
+
unknownDelivery(clientRequestId) {
|
|
130
|
+
const request = this.findRecord(clientRequestId);
|
|
131
|
+
if (!request)
|
|
132
|
+
return [];
|
|
133
|
+
const updated = this.state.rememberUnknownDelivery(request.key);
|
|
134
|
+
if (!updated)
|
|
135
|
+
return [];
|
|
136
|
+
return this.direct(request.channelId, {
|
|
137
|
+
type: "user_message_status",
|
|
138
|
+
in_reply_to: clientRequestId,
|
|
139
|
+
session_id: this.sessionManager.getSessionId(),
|
|
140
|
+
history_generation: this.generation,
|
|
141
|
+
client_request_id: clientRequestId,
|
|
142
|
+
status: "unknown_delivery",
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
partial(partial) {
|
|
146
|
+
if (partial.session_id !== this.sessionManager.getSessionId() || partial.history_generation !== this.generation)
|
|
147
|
+
return null;
|
|
148
|
+
return partial;
|
|
149
|
+
}
|
|
150
|
+
publish(event) {
|
|
151
|
+
return this.publishFrames(event)[0] ?? null;
|
|
152
|
+
}
|
|
153
|
+
publishFrames(event) {
|
|
154
|
+
const parsed = TimelineEventSchema.safeParse(event);
|
|
155
|
+
if (!parsed.success)
|
|
156
|
+
return [];
|
|
157
|
+
const complete = {
|
|
158
|
+
protocol_version: 2,
|
|
159
|
+
type: "timeline_event",
|
|
160
|
+
session_id: this.sessionManager.getSessionId(),
|
|
161
|
+
history_generation: this.generation,
|
|
162
|
+
event: parsed.data,
|
|
163
|
+
};
|
|
164
|
+
if (new TextEncoder().encode(JSON.stringify(complete)).byteLength <= MAX_FRAME_BYTES)
|
|
165
|
+
return [complete];
|
|
166
|
+
const bytes = new TextEncoder().encode(JSON.stringify(parsed.data));
|
|
167
|
+
const frames = [];
|
|
168
|
+
for (let offset = 0, index = 0; offset < bytes.byteLength; offset += MAX_FRAGMENT_DECODE_BYTES, index += 1) {
|
|
169
|
+
const slice = bytes.slice(offset, offset + MAX_FRAGMENT_DECODE_BYTES);
|
|
170
|
+
frames.push({
|
|
171
|
+
protocol_version: 2,
|
|
172
|
+
type: "timeline_event_fragment",
|
|
173
|
+
session_id: this.sessionManager.getSessionId(),
|
|
174
|
+
history_generation: this.generation,
|
|
175
|
+
event_id: parsed.data.event_id,
|
|
176
|
+
index,
|
|
177
|
+
data_base64: Buffer.from(slice).toString("base64"),
|
|
178
|
+
final: offset + slice.byteLength >= bytes.byteLength,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return frames;
|
|
182
|
+
}
|
|
183
|
+
ready(frame) {
|
|
184
|
+
this.state.hello(this.senderRef, frame.channel_id);
|
|
185
|
+
return {
|
|
186
|
+
protocol_version: 2,
|
|
187
|
+
type: "session_ready",
|
|
188
|
+
in_reply_to: frame.id,
|
|
189
|
+
target_channel_id: frame.channel_id,
|
|
190
|
+
session_id: this.sessionManager.getSessionId(),
|
|
191
|
+
history_generation: this.generation,
|
|
192
|
+
self_sender_ref: this.senderRef,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
handleHistory(frame) {
|
|
196
|
+
const error = this.ensureReady(frame);
|
|
197
|
+
if (error)
|
|
198
|
+
return [error];
|
|
199
|
+
return this.pager.sync({
|
|
200
|
+
requestId: frame.id,
|
|
201
|
+
targetChannelId: frame.channel_id,
|
|
202
|
+
before: frame.before,
|
|
203
|
+
limit: frame.limit,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
handlePing(frame) {
|
|
207
|
+
const error = this.ensureReady(frame);
|
|
208
|
+
if (error)
|
|
209
|
+
return [error];
|
|
210
|
+
return this.direct(frame.channel_id, { type: "pong", in_reply_to: frame.id });
|
|
211
|
+
}
|
|
212
|
+
handleCancel(frame) {
|
|
213
|
+
const error = this.ensureReady(frame);
|
|
214
|
+
if (error)
|
|
215
|
+
return [error];
|
|
216
|
+
try {
|
|
217
|
+
if (!(this.onCancel?.(frame.target_id) ?? false)) {
|
|
218
|
+
return [this.error(frame.id, "internal_error", "no active request to cancel", frame.channel_id)];
|
|
219
|
+
}
|
|
220
|
+
return this.direct(frame.channel_id, {
|
|
221
|
+
type: "cancelled",
|
|
222
|
+
in_reply_to: frame.id,
|
|
223
|
+
target_id: frame.target_id,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
catch (cancelError) {
|
|
227
|
+
const detail = cancelError instanceof Error ? cancelError.message : String(cancelError);
|
|
228
|
+
return [this.error(frame.id, "internal_error", `cancel failed: ${detail}`, frame.channel_id)];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
handleObserved(frame) {
|
|
232
|
+
const error = this.ensureReady(frame);
|
|
233
|
+
if (error)
|
|
234
|
+
return [error];
|
|
235
|
+
const record = this.state.getRecord(this.recordKey(frame.client_request_id));
|
|
236
|
+
if (!record || record.senderRef !== this.senderRef) {
|
|
237
|
+
return [this.error(frame.id, "invalid_message", "unknown observed request", frame.channel_id)];
|
|
238
|
+
}
|
|
239
|
+
this.state.forget(record.key);
|
|
240
|
+
this.requestChannels.delete(frame.client_request_id);
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
handleUserMessage(frame) {
|
|
244
|
+
const error = this.ensureReady(frame);
|
|
245
|
+
if (error)
|
|
246
|
+
return [error];
|
|
247
|
+
const result = this.state.begin({
|
|
248
|
+
senderRef: this.senderRef,
|
|
249
|
+
clientRequestId: frame.client_request_id,
|
|
250
|
+
payload: this.idempotencyPayload(frame),
|
|
251
|
+
});
|
|
252
|
+
if (result.kind === "conflict") {
|
|
253
|
+
return [this.error(frame.id, "invalid_message", "client_request_id payload conflict", frame.channel_id)];
|
|
254
|
+
}
|
|
255
|
+
if (result.kind === "replay")
|
|
256
|
+
return this.replay(frame, result.record);
|
|
257
|
+
this.requestChannels.set(frame.client_request_id, frame.channel_id);
|
|
258
|
+
const correlation = frame.streaming_behavior === "steer"
|
|
259
|
+
? { origin: "unknown", delivery: "unknown", channelId: frame.channel_id, requestId: frame.id }
|
|
260
|
+
: {
|
|
261
|
+
origin: "pwa",
|
|
262
|
+
delivery: "normal",
|
|
263
|
+
senderRef: this.senderRef,
|
|
264
|
+
channelId: frame.channel_id,
|
|
265
|
+
requestId: frame.id,
|
|
266
|
+
clientRequestId: frame.client_request_id,
|
|
267
|
+
};
|
|
268
|
+
try {
|
|
269
|
+
const acceptedForDelivery = this.onUserMessage(frame, correlation);
|
|
270
|
+
if (!acceptedForDelivery)
|
|
271
|
+
return this.unknownDelivery(frame.client_request_id);
|
|
272
|
+
if (frame.streaming_behavior === "steer")
|
|
273
|
+
return this.unknownDelivery(frame.client_request_id);
|
|
274
|
+
return [this.status(frame, "received")];
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
return this.unknownDelivery(frame.client_request_id);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
replay(frame, record) {
|
|
281
|
+
if (record.status === "unknown_delivery")
|
|
282
|
+
return this.unknownDelivery(frame.client_request_id);
|
|
283
|
+
if (record.status === "received")
|
|
284
|
+
return [this.status(frame, "received")];
|
|
285
|
+
return [this.status(frame, record.status === "committed" ? "committed" : "accepted", record.messageId, record.groupId)];
|
|
286
|
+
}
|
|
287
|
+
status(frame, status, messageId, groupId) {
|
|
288
|
+
return this.direct(frame.channel_id, {
|
|
289
|
+
type: "user_message_status",
|
|
290
|
+
in_reply_to: frame.id,
|
|
291
|
+
session_id: this.sessionManager.getSessionId(),
|
|
292
|
+
history_generation: this.generation,
|
|
293
|
+
client_request_id: frame.client_request_id,
|
|
294
|
+
status,
|
|
295
|
+
...(messageId ? { message_id: messageId } : {}),
|
|
296
|
+
...(groupId ? { group_id: groupId } : {}),
|
|
297
|
+
})[0];
|
|
298
|
+
}
|
|
299
|
+
requireReady(frame) {
|
|
300
|
+
const error = this.ensureReady(frame);
|
|
301
|
+
return [error ?? this.error("id" in frame ? frame.id : "v2", "unsupported_type", "frame is not implemented", "channel_id" in frame ? frame.channel_id : undefined)];
|
|
302
|
+
}
|
|
303
|
+
ensureReady(frame) {
|
|
304
|
+
if (!("channel_id" in frame) || !this.state.get(this.senderRef, frame.channel_id)) {
|
|
305
|
+
return this.error("id" in frame ? frame.id : "v2", "invalid_channel", "session_hello required", "channel_id" in frame ? frame.channel_id : undefined);
|
|
306
|
+
}
|
|
307
|
+
if ("history_generation" in frame && frame.history_generation !== this.generation) {
|
|
308
|
+
return {
|
|
309
|
+
protocol_version: 2,
|
|
310
|
+
type: "reset",
|
|
311
|
+
target_channel_id: frame.channel_id,
|
|
312
|
+
session_id: this.sessionManager.getSessionId(),
|
|
313
|
+
history_generation: this.generation,
|
|
314
|
+
reason: "generation_changed",
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
this.state.touch(this.senderRef, frame.channel_id);
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
direct(channelId, frame) {
|
|
321
|
+
return [{ ...frame, protocol_version: 2, target_channel_id: channelId }];
|
|
322
|
+
}
|
|
323
|
+
error(inReplyTo, code, message, channelId) {
|
|
324
|
+
return {
|
|
325
|
+
protocol_version: 2,
|
|
326
|
+
type: "protocol_error",
|
|
327
|
+
...(channelId ? { target_channel_id: channelId } : {}),
|
|
328
|
+
in_reply_to: inReplyTo,
|
|
329
|
+
code,
|
|
330
|
+
message,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
idempotencyPayload(frame) {
|
|
334
|
+
return {
|
|
335
|
+
text: frame.text,
|
|
336
|
+
images: frame.images ?? [],
|
|
337
|
+
streaming_behavior: frame.streaming_behavior ?? null,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
recordKey(clientRequestId) {
|
|
341
|
+
return `${this.generation}\u0000${this.senderRef}\u0000${clientRequestId}`;
|
|
342
|
+
}
|
|
343
|
+
findRecord(clientRequestId) {
|
|
344
|
+
const record = this.state.getRecord(this.recordKey(clientRequestId));
|
|
345
|
+
const channelId = this.requestChannels.get(clientRequestId);
|
|
346
|
+
if (!record || !channelId)
|
|
347
|
+
return undefined;
|
|
348
|
+
return { ...record, channelId };
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
//# sourceMappingURL=v2_service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2_service.js","sourceRoot":"","sources":["../../src/timeline/v2_service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ClientMessage, ServerMessage } from "../protocol/types.js";
|
|
2
|
+
import { type ClientFrame, type ServerFrame } from "../protocol/v2/index.js";
|
|
3
|
+
import type { RelayClient } from "./relay_client.js";
|
|
4
|
+
/** Sink for ServerMessage outbound to the remote app. */
|
|
5
|
+
export interface PeerChannel {
|
|
6
|
+
send(msg: ServerMessage): void;
|
|
7
|
+
}
|
|
8
|
+
export interface V2Channel {
|
|
9
|
+
getPeerId(): string;
|
|
10
|
+
sendV2(msg: ServerFrame): void;
|
|
11
|
+
detach(): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Plaintext PeerChannel backed by a RelayClient WebSocket.
|
|
15
|
+
*
|
|
16
|
+
* Usage (after pair_request handshake completes):
|
|
17
|
+
* const channel = new PlainPeerChannel(relay, appPeerId, myRoomId, onMsg)
|
|
18
|
+
* channel.send(serverMessage) // base64-encodes JSON, routes via relay
|
|
19
|
+
* // incoming relay messages destined for appPeerId are auto-decoded
|
|
20
|
+
* // and delivered via onMessage callback
|
|
21
|
+
*
|
|
22
|
+
* `myRoomId` is the *local* Pi's room id — sent on every outbound envelope
|
|
23
|
+
* so the app can correlate which Pi sent it (multi-pi support, plano 17).
|
|
24
|
+
*/
|
|
25
|
+
export declare class V2PeerChannel implements V2Channel {
|
|
26
|
+
private readonly relay;
|
|
27
|
+
private readonly remotePeerId;
|
|
28
|
+
private readonly onMessage;
|
|
29
|
+
private readonly unsubscribe;
|
|
30
|
+
constructor(relay: RelayClient, remotePeerId: string, onMessage: (msg: ClientFrame) => void);
|
|
31
|
+
getPeerId(): string;
|
|
32
|
+
sendV2(msg: ServerFrame): void;
|
|
33
|
+
detach(): void;
|
|
34
|
+
private onLine;
|
|
35
|
+
}
|
|
36
|
+
/** @deprecated Protocol v1 test helper. Production uses V2PeerChannel. */
|
|
37
|
+
export declare class PlainPeerChannel implements PeerChannel {
|
|
38
|
+
private readonly relay;
|
|
39
|
+
private readonly remotePeerId;
|
|
40
|
+
private readonly onMessage;
|
|
41
|
+
private readonly _unsubscribe;
|
|
42
|
+
constructor(relay: RelayClient, remotePeerId: string,
|
|
43
|
+
/**
|
|
44
|
+
* This Pi's room id. Currently NOT injected in the outer envelope
|
|
45
|
+
* (defensive — relay/app not yet ready). Kept in the constructor for
|
|
46
|
+
* forward-compat so callers don't need to change again when we re-enable.
|
|
47
|
+
*/
|
|
48
|
+
myRoomId: string | undefined, onMessage: (msg: ClientMessage) => void,
|
|
49
|
+
/** Called when this specific peer connection is considered lost. */
|
|
50
|
+
_onDisconnect?: () => void);
|
|
51
|
+
/** Authenticated Owner peer id used as a server-derived sender reference. */
|
|
52
|
+
getPeerId(): string;
|
|
53
|
+
send(msg: ServerMessage): void;
|
|
54
|
+
/** Detaches from relay (does not close the relay itself). */
|
|
55
|
+
detach(): void;
|
|
56
|
+
private _onLine;
|
|
57
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { decodeClientFrameV2, encodeServerFrameV2, } from "../protocol/v2/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Plaintext PeerChannel backed by a RelayClient WebSocket.
|
|
4
|
+
*
|
|
5
|
+
* Usage (after pair_request handshake completes):
|
|
6
|
+
* const channel = new PlainPeerChannel(relay, appPeerId, myRoomId, onMsg)
|
|
7
|
+
* channel.send(serverMessage) // base64-encodes JSON, routes via relay
|
|
8
|
+
* // incoming relay messages destined for appPeerId are auto-decoded
|
|
9
|
+
* // and delivered via onMessage callback
|
|
10
|
+
*
|
|
11
|
+
* `myRoomId` is the *local* Pi's room id — sent on every outbound envelope
|
|
12
|
+
* so the app can correlate which Pi sent it (multi-pi support, plano 17).
|
|
13
|
+
*/
|
|
14
|
+
export class V2PeerChannel {
|
|
15
|
+
relay;
|
|
16
|
+
remotePeerId;
|
|
17
|
+
onMessage;
|
|
18
|
+
unsubscribe;
|
|
19
|
+
constructor(relay, remotePeerId, onMessage) {
|
|
20
|
+
this.relay = relay;
|
|
21
|
+
this.remotePeerId = remotePeerId;
|
|
22
|
+
this.onMessage = onMessage;
|
|
23
|
+
const listener = (line) => this.onLine(line);
|
|
24
|
+
relay.on("message", listener);
|
|
25
|
+
this.unsubscribe = () => relay.off("message", listener);
|
|
26
|
+
}
|
|
27
|
+
getPeerId() {
|
|
28
|
+
return this.remotePeerId;
|
|
29
|
+
}
|
|
30
|
+
sendV2(msg) {
|
|
31
|
+
const ct = Buffer.from(encodeServerFrameV2(msg)).toString("base64");
|
|
32
|
+
try {
|
|
33
|
+
this.relay.send(JSON.stringify({ peer: this.remotePeerId, ct }));
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Reconnect plus authoritative history recovers dropped formal events.
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
detach() {
|
|
40
|
+
this.unsubscribe();
|
|
41
|
+
}
|
|
42
|
+
onLine(line) {
|
|
43
|
+
let outer;
|
|
44
|
+
try {
|
|
45
|
+
outer = JSON.parse(line);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (outer.peer !== this.remotePeerId || !outer.ct)
|
|
51
|
+
return;
|
|
52
|
+
try {
|
|
53
|
+
const plaintext = Buffer.from(outer.ct, "base64").toString("utf8");
|
|
54
|
+
this.onMessage(decodeClientFrameV2(plaintext));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Strict v2 boundary. A parseable legacy/invalid request receives an upgrade
|
|
58
|
+
// error; malformed bytes without an id cannot be safely targeted.
|
|
59
|
+
try {
|
|
60
|
+
const raw = JSON.parse(Buffer.from(outer.ct, "base64").toString("utf8"));
|
|
61
|
+
const id = typeof raw.id === "string" ? raw.id : undefined;
|
|
62
|
+
const channelId = typeof raw.channel_id === "string" ? raw.channel_id : undefined;
|
|
63
|
+
if (id) {
|
|
64
|
+
this.sendV2({
|
|
65
|
+
protocol_version: 2,
|
|
66
|
+
type: "protocol_error",
|
|
67
|
+
...(channelId ? { target_channel_id: channelId } : {}),
|
|
68
|
+
in_reply_to: id,
|
|
69
|
+
code: "protocol_upgrade_required",
|
|
70
|
+
message: "Protocol v2 is required",
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Ignore malformed outer payloads.
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** @deprecated Protocol v1 test helper. Production uses V2PeerChannel. */
|
|
81
|
+
export class PlainPeerChannel {
|
|
82
|
+
relay;
|
|
83
|
+
remotePeerId;
|
|
84
|
+
onMessage;
|
|
85
|
+
_unsubscribe;
|
|
86
|
+
constructor(relay, remotePeerId,
|
|
87
|
+
/**
|
|
88
|
+
* This Pi's room id. Currently NOT injected in the outer envelope
|
|
89
|
+
* (defensive — relay/app not yet ready). Kept in the constructor for
|
|
90
|
+
* forward-compat so callers don't need to change again when we re-enable.
|
|
91
|
+
*/
|
|
92
|
+
myRoomId, onMessage,
|
|
93
|
+
/** Called when this specific peer connection is considered lost. */
|
|
94
|
+
_onDisconnect) {
|
|
95
|
+
this.relay = relay;
|
|
96
|
+
this.remotePeerId = remotePeerId;
|
|
97
|
+
this.onMessage = onMessage;
|
|
98
|
+
const listener = (line) => this._onLine(line);
|
|
99
|
+
relay.on("message", listener);
|
|
100
|
+
this._unsubscribe = () => relay.off("message", listener);
|
|
101
|
+
void _onDisconnect;
|
|
102
|
+
void myRoomId; // intentionally unused — see send() comment
|
|
103
|
+
}
|
|
104
|
+
// ── PeerChannel interface ──────────────────────────────────────────────────
|
|
105
|
+
/** Authenticated Owner peer id used as a server-derived sender reference. */
|
|
106
|
+
getPeerId() {
|
|
107
|
+
return this.remotePeerId;
|
|
108
|
+
}
|
|
109
|
+
send(msg) {
|
|
110
|
+
const ct = Buffer.from(JSON.stringify(msg)).toString("base64");
|
|
111
|
+
// NOTE: `room` removed from the outer envelope until relay (W1.A) + app
|
|
112
|
+
// (W1.C) accept the field. Multi-Pi multiplexing already works via
|
|
113
|
+
// `room_id`/`room_meta` in the WS-level `hello` — outer routing stays by
|
|
114
|
+
// `peer` alone. Re-add the field once downstream is ready.
|
|
115
|
+
const outer = { peer: this.remotePeerId, ct };
|
|
116
|
+
// Best-effort delivery. The relay WS can be mid-reconnect (idle/NAT drop, or
|
|
117
|
+
// a session_new/session-replacement teardown) when we push a server→app frame
|
|
118
|
+
// — notably the action_ok/action_error ack a handler emits right after
|
|
119
|
+
// newSession. `relay.send` throws "relay: not connected" in that window; since
|
|
120
|
+
// this runs inside an async SDK event callback, letting it propagate becomes an
|
|
121
|
+
// uncaughtException that kills the whole pi process. The relay auto-reconnects
|
|
122
|
+
// and the app re-syncs via session_sync, so a dropped frame is recoverable — a
|
|
123
|
+
// crash is not. Mirrors RelayClient.sendControl's no-op-when-closed policy.
|
|
124
|
+
try {
|
|
125
|
+
this.relay.send(JSON.stringify(outer));
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
/* relay down — drop this frame; reconnect + session_sync will recover */
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** Detaches from relay (does not close the relay itself). */
|
|
132
|
+
detach() {
|
|
133
|
+
this._unsubscribe();
|
|
134
|
+
}
|
|
135
|
+
// ── Incoming line from relay ────────────────────────────────────────────────
|
|
136
|
+
_onLine(line) {
|
|
137
|
+
let outer;
|
|
138
|
+
try {
|
|
139
|
+
outer = JSON.parse(line);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return; // malformed line
|
|
143
|
+
}
|
|
144
|
+
if (outer.peer !== this.remotePeerId)
|
|
145
|
+
return;
|
|
146
|
+
if (!outer.ct)
|
|
147
|
+
return;
|
|
148
|
+
let plaintext;
|
|
149
|
+
try {
|
|
150
|
+
plaintext = Buffer.from(outer.ct, "base64").toString("utf8");
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
let msg;
|
|
156
|
+
try {
|
|
157
|
+
msg = JSON.parse(plaintext);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (!msg ||
|
|
163
|
+
typeof msg !== "object" ||
|
|
164
|
+
typeof msg.type !== "string") {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
this.onMessage(msg);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=peer_channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer_channel.js","sourceRoot":"","sources":["../../src/transport/peer_channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import type { RelayClient } from "./relay_client.js";
|
|
3
|
+
import type { Envelope } from "../session/envelope.js";
|
|
4
|
+
/** Outbound API + inbound listener for Pi↔Pi envelope forwarding via relay. */
|
|
5
|
+
export interface PiForwardClientEvents {
|
|
6
|
+
/**
|
|
7
|
+
* Emitted whenever the relay delivers a `pi_envelope_in` frame addressed
|
|
8
|
+
* to this Pi. `fromPc` is the verified Pi-pubkey of the sender (relay
|
|
9
|
+
* authoritative — defense against spoofed `envelope.from`).
|
|
10
|
+
*/
|
|
11
|
+
envelope: [env: Envelope, fromPc: string];
|
|
12
|
+
}
|
|
13
|
+
export declare class PiForwardClient extends EventEmitter {
|
|
14
|
+
private readonly relay;
|
|
15
|
+
private readonly onRelayMessage;
|
|
16
|
+
private detached;
|
|
17
|
+
constructor(relay: RelayClient);
|
|
18
|
+
/**
|
|
19
|
+
* Pack `env` in a `pi_envelope` frame addressed to `toPc` and send via
|
|
20
|
+
* the relay WS. Best-effort: if the relay is not connected, the call is
|
|
21
|
+
* silently dropped. The caller (broker_remote) handles the timeout via
|
|
22
|
+
* its outstanding-ACK map — a missing ACK from the destination wrapper
|
|
23
|
+
* surfaces as `status: "timeout"` upstream regardless.
|
|
24
|
+
*/
|
|
25
|
+
sendEnvelopeToPi(toPc: string, env: Envelope): void;
|
|
26
|
+
/** Stop listening to the relay. Call from `_goIdle` / shutdown. */
|
|
27
|
+
detach(): void;
|
|
28
|
+
private _handleLine;
|
|
29
|
+
}
|