@relaymessenger/cli 0.4.5 → 0.5.0-staging.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/README.md +108 -118
- package/dist/cli.js +2 -172
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +13 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +206 -0
- package/dist/config.js.map +1 -0
- package/dist/doctor.d.ts +20 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +73 -112
- package/dist/doctor.js.map +1 -1
- package/dist/event-listen.d.ts +11 -0
- package/dist/event-listen.d.ts.map +1 -0
- package/dist/event-listen.js +37 -0
- package/dist/event-listen.js.map +1 -0
- package/dist/output.d.ts +4 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +26 -0
- package/dist/output.js.map +1 -0
- package/dist/program.d.ts +14 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +655 -0
- package/dist/program.js.map +1 -0
- package/package.json +31 -37
- package/claude-plugin/marketplace/.claude-plugin/marketplace.json +0 -14
- package/claude-plugin/marketplace/plugins/relay/.claude-plugin/plugin.json +0 -27
- package/claude-plugin/marketplace/plugins/relay/LICENSE +0 -21
- package/claude-plugin/marketplace/plugins/relay/README.md +0 -173
- package/claude-plugin/marketplace/plugins/relay/commands/configure.md +0 -71
- package/claude-plugin/marketplace/plugins/relay/runtime/server.mjs +0 -26197
- package/dist/api.d.ts +0 -114
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js +0 -162
- package/dist/api.js.map +0 -1
- package/dist/claude-settings.d.ts +0 -14
- package/dist/claude-settings.d.ts.map +0 -1
- package/dist/claude-settings.js +0 -47
- package/dist/claude-settings.js.map +0 -1
- package/dist/codex.d.ts +0 -25
- package/dist/codex.d.ts.map +0 -1
- package/dist/codex.js +0 -237
- package/dist/codex.js.map +0 -1
- package/dist/engine/acp.d.ts +0 -74
- package/dist/engine/acp.d.ts.map +0 -1
- package/dist/engine/acp.js +0 -413
- package/dist/engine/acp.js.map +0 -1
- package/dist/engine/catalog.d.ts +0 -26
- package/dist/engine/catalog.d.ts.map +0 -1
- package/dist/engine/catalog.js +0 -41
- package/dist/engine/catalog.js.map +0 -1
- package/dist/engine/process.d.ts +0 -12
- package/dist/engine/process.d.ts.map +0 -1
- package/dist/engine/process.js +0 -54
- package/dist/engine/process.js.map +0 -1
- package/dist/engine/types.d.ts +0 -57
- package/dist/engine/types.d.ts.map +0 -1
- package/dist/engine/types.js +0 -8
- package/dist/engine/types.js.map +0 -1
- package/dist/flags.d.ts +0 -9
- package/dist/flags.d.ts.map +0 -1
- package/dist/flags.js +0 -34
- package/dist/flags.js.map +0 -1
- package/dist/install.d.ts +0 -69
- package/dist/install.d.ts.map +0 -1
- package/dist/install.js +0 -513
- package/dist/install.js.map +0 -1
- package/dist/mcp.d.ts +0 -16
- package/dist/mcp.d.ts.map +0 -1
- package/dist/mcp.js +0 -127
- package/dist/mcp.js.map +0 -1
- package/dist/pair.d.ts +0 -20
- package/dist/pair.d.ts.map +0 -1
- package/dist/pair.js +0 -135
- package/dist/pair.js.map +0 -1
- package/dist/permissions.d.ts +0 -90
- package/dist/permissions.d.ts.map +0 -1
- package/dist/permissions.js +0 -361
- package/dist/permissions.js.map +0 -1
- package/dist/receive.d.ts +0 -113
- package/dist/receive.d.ts.map +0 -1
- package/dist/receive.js +0 -596
- package/dist/receive.js.map +0 -1
- package/dist/store.d.ts +0 -301
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -551
- package/dist/store.js.map +0 -1
- package/openclaw-plugin/relaymessenger-openclaw-plugin-0.3.4.tgz +0 -0
package/dist/receive.js
DELETED
|
@@ -1,596 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Receive loop: long-poll GET /v1/events → durable queue → engine turn →
|
|
3
|
-
* one finalized POST /v1/messages per turn.
|
|
4
|
-
*
|
|
5
|
-
* Reliability contract:
|
|
6
|
-
* - Durable-before-ack: inbound events are appended to state.json's
|
|
7
|
-
* pending_events queue in the SAME atomic write that advances the cursor,
|
|
8
|
-
* so an acked event is always durable and a crash replays, never drops.
|
|
9
|
-
* - Dedupe: delivery is at-least-once; event_id is checked against a
|
|
10
|
-
* persisted seen-set before enqueueing.
|
|
11
|
-
* - Debounce: rapid messages in one conversation coalesce for ~800 ms into a
|
|
12
|
-
* single engine turn.
|
|
13
|
-
* - Supervisor: poll/turn failures restart with exponential backoff + jitter.
|
|
14
|
-
* - Cursor faults: Relay rejects a cursor it never delivered (422) and one
|
|
15
|
-
* that fell behind the seven-day event retention (410 cursor_expired).
|
|
16
|
-
* Neither is retryable on the same cursor, so both reconcile from
|
|
17
|
-
* conversation history first and then resume or stop, never re-poll blind.
|
|
18
|
-
*/
|
|
19
|
-
import { createHash } from "node:crypto";
|
|
20
|
-
import { RelayApiError } from "./api.js";
|
|
21
|
-
import { engineDisplayName } from "./engine/catalog.js";
|
|
22
|
-
export function turnIdempotencyKey(conversationId, eventIds) {
|
|
23
|
-
const digest = createHash("sha256")
|
|
24
|
-
.update(JSON.stringify([conversationId, eventIds]))
|
|
25
|
-
.digest("hex");
|
|
26
|
-
return `relay-turn-${digest.slice(0, 40)}`;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Group events carry `data.invocation_id`; direct events do not. Its presence
|
|
30
|
-
* is how the bridge tells the two apart, and the id is required on every
|
|
31
|
-
* outbound call for that turn.
|
|
32
|
-
*/
|
|
33
|
-
export function invocationIdForEvent(event) {
|
|
34
|
-
const value = event?.data?.invocation_id;
|
|
35
|
-
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* The batch a single turn may consume. Direct conversations coalesce a burst
|
|
39
|
-
* into one turn as before. A group invocation is single-use server-side (one
|
|
40
|
-
* message completes it), so a group turn is capped at the oldest invocation
|
|
41
|
-
* and later invocations stay queued for their own turns and their own replies.
|
|
42
|
-
*/
|
|
43
|
-
export function batchForTurn(queue) {
|
|
44
|
-
const invocationId = invocationIdForEvent(queue[0]);
|
|
45
|
-
if (!invocationId)
|
|
46
|
-
return [...queue];
|
|
47
|
-
return queue.filter((event) => invocationIdForEvent(event) === invocationId);
|
|
48
|
-
}
|
|
49
|
-
/** Conversations read (and named in the recovery log line) after a cursor fault. */
|
|
50
|
-
const CURSOR_RECOVERY_CONVERSATIONS = 25;
|
|
51
|
-
/**
|
|
52
|
-
* Relay's undelivered-cursor fault names its own recovery target in
|
|
53
|
-
* `error.details`: `highest_delivered_cursor` for a cursor the ledger never
|
|
54
|
-
* handed out, `latest_sequence` for one past the agent's newest event. A
|
|
55
|
-
* recovery only ever lowers the cursor. Raising it would acknowledge, and let
|
|
56
|
-
* the retention sweep delete, events this bridge has never read.
|
|
57
|
-
*/
|
|
58
|
-
export function undeliveredCursorTarget(error, cursor) {
|
|
59
|
-
if (error.status !== 422)
|
|
60
|
-
return undefined;
|
|
61
|
-
for (const key of ["highest_delivered_cursor", "latest_sequence"]) {
|
|
62
|
-
const value = error.details?.[key];
|
|
63
|
-
if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value < cursor) {
|
|
64
|
-
return value;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return undefined;
|
|
68
|
-
}
|
|
69
|
-
export function promptTextFromMessages(messages) {
|
|
70
|
-
const chunks = [];
|
|
71
|
-
for (const message of messages) {
|
|
72
|
-
const text = message.parts
|
|
73
|
-
.filter((part) => part.type === "text" && typeof part.text === "string")
|
|
74
|
-
.map((part) => part.text)
|
|
75
|
-
.join("\n")
|
|
76
|
-
.trim();
|
|
77
|
-
chunks.push(text.length > 0 ? text : message.fallback_text);
|
|
78
|
-
}
|
|
79
|
-
return chunks.filter((chunk) => chunk && chunk.length > 0).join("\n\n");
|
|
80
|
-
}
|
|
81
|
-
export class ReceiveLoop {
|
|
82
|
-
client;
|
|
83
|
-
state;
|
|
84
|
-
engine;
|
|
85
|
-
broker;
|
|
86
|
-
ownerUserId;
|
|
87
|
-
debounceMs;
|
|
88
|
-
cwd;
|
|
89
|
-
log;
|
|
90
|
-
setTimeoutImpl;
|
|
91
|
-
debounceTimers = new Map();
|
|
92
|
-
/** Serializes turns per conversation. */
|
|
93
|
-
turnChains = new Map();
|
|
94
|
-
stopped = false;
|
|
95
|
-
constructor(client, state, engine, broker, options) {
|
|
96
|
-
this.client = client;
|
|
97
|
-
this.state = state;
|
|
98
|
-
this.engine = engine;
|
|
99
|
-
this.broker = broker;
|
|
100
|
-
this.ownerUserId = options.ownerUserId;
|
|
101
|
-
this.debounceMs = options.debounceMs ?? 800;
|
|
102
|
-
this.cwd = options.cwd ?? process.cwd();
|
|
103
|
-
this.log = options.log ?? (() => { });
|
|
104
|
-
this.setTimeoutImpl = options.setTimeoutImpl ?? setTimeout;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* One poll cycle: fetch, dedupe, durably enqueue + ack, schedule flushes.
|
|
108
|
-
* Exposed for tests; `run()` supervises it forever.
|
|
109
|
-
*/
|
|
110
|
-
async pollOnce(timeoutS = 25) {
|
|
111
|
-
const page = await this.client.getEvents(this.state.current.cursor, timeoutS);
|
|
112
|
-
const touched = new Set();
|
|
113
|
-
let accepted = 0;
|
|
114
|
-
for (const event of page.events ?? []) {
|
|
115
|
-
if (!event.event_id || this.state.hasSeen(event.event_id))
|
|
116
|
-
continue;
|
|
117
|
-
this.state.markSeen(event.event_id);
|
|
118
|
-
const routed = this.routeEvent(event);
|
|
119
|
-
if (routed) {
|
|
120
|
-
touched.add(routed);
|
|
121
|
-
accepted += 1;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// Durable-before-ack: queue mutation and cursor advance are one atomic write.
|
|
125
|
-
if (typeof page.next_cursor === "number") {
|
|
126
|
-
this.state.current.cursor = page.next_cursor;
|
|
127
|
-
}
|
|
128
|
-
this.state.persist();
|
|
129
|
-
for (const conversationId of touched) {
|
|
130
|
-
this.scheduleFlush(conversationId);
|
|
131
|
-
this.ackQueuedBehindTurn(conversationId);
|
|
132
|
-
}
|
|
133
|
-
return accepted;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* A turn snapshots its batch at start, so a message that lands while the
|
|
137
|
-
* turn runs cannot advance that turn's /responding watermark and would sit
|
|
138
|
-
* at "Delivered" until its own turn — after the reply, plus another
|
|
139
|
-
* debounce. Mark the queue head read now instead. /read is the receipt
|
|
140
|
-
* without /responding's typing side effect, so the running turn's tool
|
|
141
|
-
* label survives. Best-effort: the next turn's /responding still covers
|
|
142
|
-
* the same watermark durably, so a failure here only delays the receipt.
|
|
143
|
-
*/
|
|
144
|
-
ackQueuedBehindTurn(conversationId) {
|
|
145
|
-
if (!this.turnChains.has(conversationId))
|
|
146
|
-
return;
|
|
147
|
-
const queue = this.state.current.pending_events[conversationId] ?? [];
|
|
148
|
-
const newest = queue[queue.length - 1]?.data?.message;
|
|
149
|
-
if (!newest)
|
|
150
|
-
return;
|
|
151
|
-
void this.client
|
|
152
|
-
.markRead(conversationId, newest.id)
|
|
153
|
-
.catch((error) => this.log(`mid-turn read receipt failed for ${conversationId}: ${error}`));
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Read the canonical record after a cursor fault. Conversation history is
|
|
157
|
-
* Relay's documented recovery path: the event log can no longer say what
|
|
158
|
-
* moved, so the bridge names the head of every conversation it can still
|
|
159
|
-
* see. Nothing is replayed into the engine and nothing is invented for the
|
|
160
|
-
* events Relay deleted.
|
|
161
|
-
*/
|
|
162
|
-
async reconcileHistory() {
|
|
163
|
-
const conversationIds = new Set(Object.keys(this.state.current.pending_events));
|
|
164
|
-
const owner = this.state.current.owner_conversation_id;
|
|
165
|
-
if (owner)
|
|
166
|
-
conversationIds.add(owner);
|
|
167
|
-
try {
|
|
168
|
-
const listed = await this.client.listConversations(CURSOR_RECOVERY_CONVERSATIONS);
|
|
169
|
-
for (const conversation of listed.conversations ?? []) {
|
|
170
|
-
if (conversation?.id)
|
|
171
|
-
conversationIds.add(conversation.id);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
catch (error) {
|
|
175
|
-
this.log(`conversation listing failed during cursor recovery: ${error}`);
|
|
176
|
-
}
|
|
177
|
-
const heads = [];
|
|
178
|
-
const readable = [...conversationIds].slice(0, CURSOR_RECOVERY_CONVERSATIONS);
|
|
179
|
-
for (const conversationId of readable) {
|
|
180
|
-
try {
|
|
181
|
-
const { messages } = await this.client.listMessages(conversationId, 1);
|
|
182
|
-
const newest = messages?.[0];
|
|
183
|
-
heads.push(newest
|
|
184
|
-
? `${conversationId} head ${newest.id} seq ${newest.sequence}` +
|
|
185
|
-
`${newest.created_at ? ` at ${newest.created_at}` : ""}`
|
|
186
|
-
: `${conversationId} empty`);
|
|
187
|
-
}
|
|
188
|
-
catch (error) {
|
|
189
|
-
heads.push(`${conversationId} unreadable (${error instanceof Error ? error.message : error})`);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (conversationIds.size > readable.length) {
|
|
193
|
-
heads.push(`${conversationIds.size - readable.length} further conversations not read`);
|
|
194
|
-
}
|
|
195
|
-
return heads.length > 0 ? heads.join("; ") : "no conversations were visible to reconcile";
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Apply Relay's cursor-fault contract. Both faults are permanent for the
|
|
199
|
-
* cursor that produced them, so neither may fall through to the generic
|
|
200
|
-
* retry: an undelivered cursor resumes from the ledger position Relay
|
|
201
|
-
* reports. For an expired cursor, the bridge first reads canonical history,
|
|
202
|
-
* then explicitly confirms that reconciliation so Relay can advance only
|
|
203
|
-
* across the proven retention gap.
|
|
204
|
-
*/
|
|
205
|
-
async recoverFromCursorFault(error) {
|
|
206
|
-
const cursor = this.state.current.cursor;
|
|
207
|
-
const target = undeliveredCursorTarget(error, cursor);
|
|
208
|
-
if (target !== undefined) {
|
|
209
|
-
const history = await this.reconcileHistory();
|
|
210
|
-
this.state.current.cursor = target;
|
|
211
|
-
this.state.persist();
|
|
212
|
-
this.log(`poll cursor ${cursor} was never delivered by Relay (422 ${error.code ?? "invalid_request"}); ` +
|
|
213
|
-
`reconciled conversation history and resumed from Relay's highest delivered cursor ${target}. ` +
|
|
214
|
-
`Events after ${target} are redelivered and deduplicated by event_id, so nothing is skipped. ` +
|
|
215
|
-
`History head: ${history}`);
|
|
216
|
-
return "resumed";
|
|
217
|
-
}
|
|
218
|
-
if (error.status === 410 && error.code === "cursor_expired") {
|
|
219
|
-
const history = await this.reconcileHistory();
|
|
220
|
-
const highestDelivered = error.details?.highest_delivered_cursor;
|
|
221
|
-
const advertisedResume = error.details?.resume_cursor;
|
|
222
|
-
const reconciliationRequired = error.details?.reconciliation_required;
|
|
223
|
-
if (reconciliationRequired === true
|
|
224
|
-
&& typeof highestDelivered === "number"
|
|
225
|
-
&& Number.isSafeInteger(highestDelivered)
|
|
226
|
-
&& highestDelivered >= 0
|
|
227
|
-
&& highestDelivered <= cursor) {
|
|
228
|
-
const reconciled = await this.client.reconcileEvents(highestDelivered);
|
|
229
|
-
if (reconciled.reconciled !== true
|
|
230
|
-
|| !Number.isSafeInteger(reconciled.resume_cursor)
|
|
231
|
-
|| reconciled.resume_cursor < 0
|
|
232
|
-
|| (typeof advertisedResume === "number"
|
|
233
|
-
&& reconciled.resume_cursor !== advertisedResume)) {
|
|
234
|
-
throw new Error(`Relay returned an invalid cursor reconciliation response for expired cursor ${cursor}`);
|
|
235
|
-
}
|
|
236
|
-
this.state.current.cursor = reconciled.resume_cursor;
|
|
237
|
-
this.state.persist();
|
|
238
|
-
this.log(`Relay expired poll cursor ${cursor} (410 cursor_expired); reconciled canonical conversation ` +
|
|
239
|
-
`history, confirmed the retention gap, and resumed from ${reconciled.resume_cursor}. ` +
|
|
240
|
-
`Deleted events cannot be replayed, but polling is live again. History head: ${history}`);
|
|
241
|
-
return "resumed";
|
|
242
|
-
}
|
|
243
|
-
this.log(`fatal: Relay expired this bridge's poll cursor ${cursor} (410 cursor_expired). Relay keeps the event ` +
|
|
244
|
-
`log for seven days, so events recorded after that cursor were deleted before this bridge read them. ` +
|
|
245
|
-
`They cannot be replayed, and any message they carried stays unanswered and is unrecoverable from the ` +
|
|
246
|
-
`event log; conversation history below is the only record of it. History head: ${history}. Polling ` +
|
|
247
|
-
`stops because this server did not advertise the explicit reconciliation contract.`);
|
|
248
|
-
return "terminal";
|
|
249
|
-
}
|
|
250
|
-
return "unhandled";
|
|
251
|
-
}
|
|
252
|
-
/** Returns the conversation id when the event was enqueued for the engine. */
|
|
253
|
-
routeEvent(event) {
|
|
254
|
-
if (event.event_type !== "message.received")
|
|
255
|
-
return undefined;
|
|
256
|
-
const message = event.data?.message;
|
|
257
|
-
if (!message || message.sender?.kind !== "user")
|
|
258
|
-
return undefined;
|
|
259
|
-
// Owner gate before any content is interpreted: non-owner senders can
|
|
260
|
-
// neither prompt the engine nor answer a permission card.
|
|
261
|
-
if (message.sender.id !== this.ownerUserId) {
|
|
262
|
-
this.log(`ignoring message from non-owner sender ${message.sender.id}`);
|
|
263
|
-
return undefined;
|
|
264
|
-
}
|
|
265
|
-
// First owner message pins the default notify/MCP conversation. A group
|
|
266
|
-
// is never that conversation: sends there need an invocation this agent
|
|
267
|
-
// does not have, and approvals must reach the owner alone.
|
|
268
|
-
if (!invocationIdForEvent(event)) {
|
|
269
|
-
this.state.current.owner_conversation_id ??= message.conversation_id;
|
|
270
|
-
}
|
|
271
|
-
if (this.broker.consumeReply(message))
|
|
272
|
-
return undefined;
|
|
273
|
-
const queue = (this.state.current.pending_events[message.conversation_id] ??= []);
|
|
274
|
-
queue.push(event);
|
|
275
|
-
return message.conversation_id;
|
|
276
|
-
}
|
|
277
|
-
scheduleFlush(conversationId) {
|
|
278
|
-
if (this.stopped)
|
|
279
|
-
return;
|
|
280
|
-
const existing = this.debounceTimers.get(conversationId);
|
|
281
|
-
if (existing)
|
|
282
|
-
clearTimeout(existing);
|
|
283
|
-
const timer = this.setTimeoutImpl(() => {
|
|
284
|
-
this.debounceTimers.delete(conversationId);
|
|
285
|
-
this.chainTurn(conversationId);
|
|
286
|
-
}, this.debounceMs);
|
|
287
|
-
timer.unref?.();
|
|
288
|
-
this.debounceTimers.set(conversationId, timer);
|
|
289
|
-
}
|
|
290
|
-
chainTurn(conversationId) {
|
|
291
|
-
const previous = this.turnChains.get(conversationId) ?? Promise.resolve();
|
|
292
|
-
const next = previous
|
|
293
|
-
.then(() => this.runTurn(conversationId))
|
|
294
|
-
.catch((error) => {
|
|
295
|
-
this.log(`turn failed for ${conversationId}: ${error}`);
|
|
296
|
-
});
|
|
297
|
-
this.turnChains.set(conversationId, next);
|
|
298
|
-
void next.finally(() => {
|
|
299
|
-
if (this.turnChains.get(conversationId) === next)
|
|
300
|
-
this.turnChains.delete(conversationId);
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
/** Waits for in-flight turns (tests + graceful shutdown). */
|
|
304
|
-
async settle() {
|
|
305
|
-
await Promise.allSettled([...this.turnChains.values()]);
|
|
306
|
-
}
|
|
307
|
-
/** Removes THIS turn's consumed events (and its attempt marker) durably. */
|
|
308
|
-
clearBatch(conversationId, events, turnKey) {
|
|
309
|
-
const queue = this.state.current.pending_events[conversationId] ?? [];
|
|
310
|
-
const remaining = queue.filter((event) => !events.some((consumed) => consumed.event_id === event.event_id));
|
|
311
|
-
if (remaining.length === 0) {
|
|
312
|
-
delete this.state.current.pending_events[conversationId];
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
this.state.current.pending_events[conversationId] = remaining;
|
|
316
|
-
// New messages arrived mid-turn; run again.
|
|
317
|
-
this.scheduleFlush(conversationId);
|
|
318
|
-
}
|
|
319
|
-
const attempted = (this.state.current.attempted_turns ??= {})[conversationId];
|
|
320
|
-
if (attempted && (!turnKey || attempted.turn_key === turnKey)) {
|
|
321
|
-
delete this.state.current.attempted_turns[conversationId];
|
|
322
|
-
}
|
|
323
|
-
if (turnKey)
|
|
324
|
-
delete (this.state.current.pending_replies ??= {})[turnKey];
|
|
325
|
-
this.state.persist();
|
|
326
|
-
}
|
|
327
|
-
async postNotice(conversationId, text, key, invocationId) {
|
|
328
|
-
try {
|
|
329
|
-
await this.client.postMessage({
|
|
330
|
-
conversation_id: conversationId,
|
|
331
|
-
parts: [{ type: "text", text }],
|
|
332
|
-
...(invocationId ? { invocation_id: invocationId } : {}),
|
|
333
|
-
}, key);
|
|
334
|
-
}
|
|
335
|
-
catch (error) {
|
|
336
|
-
this.log(`notice post failed for ${conversationId}: ${error}`);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
pendingReplyForConversation(conversationId) {
|
|
340
|
-
return Object.entries(this.state.current.pending_replies ?? {}).find(([, reply]) => reply.conversation_id === conversationId);
|
|
341
|
-
}
|
|
342
|
-
/** Idempotently deliver an engine-completed reply without rerunning tools. */
|
|
343
|
-
async deliverPendingReply(turnKey, reply) {
|
|
344
|
-
let lastError;
|
|
345
|
-
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
346
|
-
try {
|
|
347
|
-
await this.client.postMessage({
|
|
348
|
-
conversation_id: reply.conversation_id,
|
|
349
|
-
parts: [{ type: "text", text: reply.text }],
|
|
350
|
-
...(reply.invocation_id ? { invocation_id: reply.invocation_id } : {}),
|
|
351
|
-
}, turnKey);
|
|
352
|
-
return true;
|
|
353
|
-
}
|
|
354
|
-
catch (error) {
|
|
355
|
-
lastError = error;
|
|
356
|
-
if (attempt < 2) {
|
|
357
|
-
await new Promise((resolve) => this.setTimeoutImpl(resolve, 1_000 * (attempt + 1)));
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
this.log(`final reply post failed for ${reply.conversation_id}: ${lastError}`);
|
|
362
|
-
return false;
|
|
363
|
-
}
|
|
364
|
-
async runTurn(conversationId) {
|
|
365
|
-
// Delivery is its own durable phase. Finish an older reply before looking
|
|
366
|
-
// at newer queued prompts, otherwise appending a message after an unknown
|
|
367
|
-
// POST outcome could cause the older tool turn to execute again.
|
|
368
|
-
const queuedReply = this.pendingReplyForConversation(conversationId);
|
|
369
|
-
if (queuedReply) {
|
|
370
|
-
const [turnKey, reply] = queuedReply;
|
|
371
|
-
const queuedEvents = this.state.current.pending_events[conversationId] ?? [];
|
|
372
|
-
const consumed = queuedEvents.filter((event) => reply.event_ids.includes(event.event_id));
|
|
373
|
-
if (await this.deliverPendingReply(turnKey, reply)) {
|
|
374
|
-
this.clearBatch(conversationId, consumed, turnKey);
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
this.scheduleFlush(conversationId);
|
|
378
|
-
}
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
// Recover the exact prefix a previous invocation durably claimed before
|
|
382
|
-
// it disappeared. Later events may already be queued; they must survive
|
|
383
|
-
// and run separately, while the attempted prefix is never re-executed.
|
|
384
|
-
const attempted = (this.state.current.attempted_turns ??= {})[conversationId];
|
|
385
|
-
if (attempted) {
|
|
386
|
-
const queue = this.state.current.pending_events[conversationId] ?? [];
|
|
387
|
-
const prefix = queue.slice(0, attempted.event_ids.length);
|
|
388
|
-
if (prefix.length !== attempted.event_ids.length ||
|
|
389
|
-
prefix.some((event, index) => event.event_id !== attempted.event_ids[index])) {
|
|
390
|
-
throw new Error(`attempt ledger mismatch for ${conversationId}; refusing to execute queued events`);
|
|
391
|
-
}
|
|
392
|
-
this.log(`turn ${attempted.turn_key} was interrupted; dropping its ${prefix.length}-event prefix, not re-executing`);
|
|
393
|
-
const interruptedInvocation = invocationIdForEvent(prefix[prefix.length - 1]);
|
|
394
|
-
this.clearBatch(conversationId, prefix, attempted.turn_key);
|
|
395
|
-
await this.postNotice(conversationId, "The bridge restarted while working on your last message, so it was not retried " +
|
|
396
|
-
"automatically (its tools may have partially run). Send it again to retry.", `${attempted.turn_key}-crashed`, interruptedInvocation);
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
// Snapshot: routeEvent keeps appending to the live queue while the turn
|
|
400
|
-
// runs, and the post-turn filter must only remove what THIS turn consumed.
|
|
401
|
-
const events = batchForTurn(this.state.current.pending_events[conversationId] ?? []);
|
|
402
|
-
if (events.length === 0)
|
|
403
|
-
return;
|
|
404
|
-
const invocationId = invocationIdForEvent(events[events.length - 1]);
|
|
405
|
-
const messages = events
|
|
406
|
-
.map((event) => event.data?.message)
|
|
407
|
-
.filter((message) => message !== undefined);
|
|
408
|
-
const promptText = promptTextFromMessages(messages);
|
|
409
|
-
if (promptText.length === 0) {
|
|
410
|
-
// Nothing promptable; drop only THIS batch durably — later events must
|
|
411
|
-
// survive for their own turns — and still mark it read, or a
|
|
412
|
-
// media-only message with no fallback text pins at Delivered forever.
|
|
413
|
-
this.clearBatch(conversationId, events);
|
|
414
|
-
const newestUnpromptable = messages[messages.length - 1];
|
|
415
|
-
if (newestUnpromptable) {
|
|
416
|
-
try {
|
|
417
|
-
await this.client.markRead(conversationId, newestUnpromptable.id);
|
|
418
|
-
}
|
|
419
|
-
catch (error) {
|
|
420
|
-
this.log(`read receipt for unpromptable batch failed for ${conversationId}: ${error}`);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
const lastMessage = messages[messages.length - 1];
|
|
426
|
-
const respondingLabel = engineDisplayName(this.engine.engine);
|
|
427
|
-
// Mark the complete debounced watermark before engine execution. A
|
|
428
|
-
// rejected /responding call propagates visibly and leaves the batch
|
|
429
|
-
// unattempted, so no tool turn can run behind a stale Delivered receipt.
|
|
430
|
-
await this.client.setResponding(conversationId, lastMessage.id, respondingLabel, invocationId);
|
|
431
|
-
const typing = this.startTyping(conversationId, invocationId, respondingLabel);
|
|
432
|
-
try {
|
|
433
|
-
// Crash semantics: engine/tool side effects are at-most-once per batch.
|
|
434
|
-
// The exact event-id batch is persisted AFTER replay-safe lifecycle
|
|
435
|
-
// preflight and BEFORE the engine starts. A later message cannot change
|
|
436
|
-
// or overwrite which prefix was already attempted.
|
|
437
|
-
const eventIds = events.map((event) => event.event_id);
|
|
438
|
-
const turnKey = turnIdempotencyKey(conversationId, eventIds);
|
|
439
|
-
(this.state.current.attempted_turns ??= {})[conversationId] = {
|
|
440
|
-
turn_key: turnKey,
|
|
441
|
-
event_ids: eventIds,
|
|
442
|
-
started_at: new Date().toISOString(),
|
|
443
|
-
};
|
|
444
|
-
this.state.persist();
|
|
445
|
-
let result;
|
|
446
|
-
try {
|
|
447
|
-
result = await this.engine.startTurn({ conversationId, cwd: this.cwd }, promptText, {
|
|
448
|
-
onToolEvent: (event) => typing.setLabel(event.title ?? "Working…"),
|
|
449
|
-
onPermissionAsk: (ask) => this.askPermission(conversationId, invocationId, ask),
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
catch (error) {
|
|
453
|
-
// A failed engine turn is not silently retried (its side effects may
|
|
454
|
-
// have partially run) and must not strand the queue: tell the owner
|
|
455
|
-
// and clear the batch so the conversation stays usable.
|
|
456
|
-
this.log(`engine turn failed for ${conversationId}: ${error}`);
|
|
457
|
-
this.clearBatch(conversationId, events, turnKey);
|
|
458
|
-
await this.postNotice(conversationId, `The ${this.engine.engine} turn failed: ${String(error instanceof Error ? error.message : error).slice(0, 300)}\n` +
|
|
459
|
-
"Send your message again to retry.", `${turnKey}-failed`, invocationId);
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
const text = result.text.trim().length > 0
|
|
463
|
-
? result.text.trim()
|
|
464
|
-
: `(turn finished: ${result.stopReason})`;
|
|
465
|
-
// Persist the completed output BEFORE delivery. Any crash from here on
|
|
466
|
-
// can retry this idempotent POST without rerunning the engine or tools.
|
|
467
|
-
const pendingReply = {
|
|
468
|
-
conversation_id: conversationId,
|
|
469
|
-
event_ids: events.map((event) => event.event_id),
|
|
470
|
-
text,
|
|
471
|
-
created_at: new Date().toISOString(),
|
|
472
|
-
...(invocationId ? { invocation_id: invocationId } : {}),
|
|
473
|
-
};
|
|
474
|
-
(this.state.current.pending_replies ??= {})[turnKey] = pendingReply;
|
|
475
|
-
this.state.persist();
|
|
476
|
-
// Clearing typing needs the invocation still pending, and the reply is
|
|
477
|
-
// what completes it, so stop before delivering rather than in `finally`.
|
|
478
|
-
if (invocationId)
|
|
479
|
-
await typing.stop();
|
|
480
|
-
if (await this.deliverPendingReply(turnKey, pendingReply)) {
|
|
481
|
-
this.clearBatch(conversationId, events, turnKey);
|
|
482
|
-
}
|
|
483
|
-
else {
|
|
484
|
-
// Keep the queue, attempt marker and completed reply. The scheduled
|
|
485
|
-
// retry enters the delivery-only path above.
|
|
486
|
-
this.scheduleFlush(conversationId);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
finally {
|
|
490
|
-
await typing.stop();
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
/**
|
|
494
|
-
* Route an approval card. A group invocation is spent by the single reply it
|
|
495
|
-
* owes, so a card posted into the group would consume it and leave the turn
|
|
496
|
-
* unable to answer. Group approvals therefore go to the owner's direct
|
|
497
|
-
* conversation with this agent, and deny when there is no such conversation
|
|
498
|
-
* to ask in.
|
|
499
|
-
*/
|
|
500
|
-
async askPermission(conversationId, invocationId, ask) {
|
|
501
|
-
if (!invocationId)
|
|
502
|
-
return this.broker.ask(conversationId, ask, this.engine.engine);
|
|
503
|
-
const direct = this.state.current.owner_conversation_id;
|
|
504
|
-
if (!direct || direct === conversationId) {
|
|
505
|
-
this.log(`group approval for ${ask.toolName ?? "a tool"} denied: no direct conversation with the owner to ask in`);
|
|
506
|
-
return this.broker.denyUnaskable(ask);
|
|
507
|
-
}
|
|
508
|
-
this.log(`group approval routed to the owner's direct conversation ${direct}`);
|
|
509
|
-
return this.broker.ask(direct, ask, this.engine.engine);
|
|
510
|
-
}
|
|
511
|
-
startTyping(conversationId, invocationId, initialLabel) {
|
|
512
|
-
let label = initialLabel;
|
|
513
|
-
let active = true;
|
|
514
|
-
const push = async (reason) => {
|
|
515
|
-
if (!active)
|
|
516
|
-
return;
|
|
517
|
-
try {
|
|
518
|
-
await this.client.setTyping(conversationId, true, label, invocationId);
|
|
519
|
-
}
|
|
520
|
-
catch (error) {
|
|
521
|
-
this.log(`typing ${reason} failed for ${conversationId}: ${error}`);
|
|
522
|
-
}
|
|
523
|
-
};
|
|
524
|
-
void push("start");
|
|
525
|
-
const interval = setInterval(() => {
|
|
526
|
-
void push("keepalive");
|
|
527
|
-
}, 20_000);
|
|
528
|
-
interval.unref?.();
|
|
529
|
-
return {
|
|
530
|
-
setLabel: (next) => {
|
|
531
|
-
label = next.slice(0, 80);
|
|
532
|
-
void push("label");
|
|
533
|
-
},
|
|
534
|
-
stop: async () => {
|
|
535
|
-
if (!active)
|
|
536
|
-
return;
|
|
537
|
-
active = false;
|
|
538
|
-
clearInterval(interval);
|
|
539
|
-
try {
|
|
540
|
-
await this.client.setTyping(conversationId, false, undefined, invocationId);
|
|
541
|
-
}
|
|
542
|
-
catch (error) {
|
|
543
|
-
this.log(`typing stop failed for ${conversationId}: ${error}`);
|
|
544
|
-
}
|
|
545
|
-
},
|
|
546
|
-
};
|
|
547
|
-
}
|
|
548
|
-
stop() {
|
|
549
|
-
this.stopped = true;
|
|
550
|
-
for (const timer of this.debounceTimers.values())
|
|
551
|
-
clearTimeout(timer);
|
|
552
|
-
this.debounceTimers.clear();
|
|
553
|
-
}
|
|
554
|
-
/** Supervisor: restart the poll loop on failure with capped backoff + jitter. */
|
|
555
|
-
async run() {
|
|
556
|
-
let failures = 0;
|
|
557
|
-
// Replay anything a previous process left behind.
|
|
558
|
-
this.broker.sweep();
|
|
559
|
-
for (const conversationId of Object.keys(this.state.current.pending_events)) {
|
|
560
|
-
this.scheduleFlush(conversationId);
|
|
561
|
-
}
|
|
562
|
-
while (!this.stopped) {
|
|
563
|
-
try {
|
|
564
|
-
this.broker.sweep();
|
|
565
|
-
await this.pollOnce();
|
|
566
|
-
failures = 0;
|
|
567
|
-
}
|
|
568
|
-
catch (error) {
|
|
569
|
-
if (error instanceof RelayApiError && (error.status === 410 || error.status === 422)) {
|
|
570
|
-
const outcome = await this.recoverFromCursorFault(error);
|
|
571
|
-
if (outcome === "resumed") {
|
|
572
|
-
failures = 0;
|
|
573
|
-
continue;
|
|
574
|
-
}
|
|
575
|
-
if (outcome === "terminal")
|
|
576
|
-
throw error;
|
|
577
|
-
}
|
|
578
|
-
if (error?.status === 409) {
|
|
579
|
-
// Another consumer (webhook or second long-poll) owns this token.
|
|
580
|
-
this.log(`fatal: ${error.message}`);
|
|
581
|
-
throw error;
|
|
582
|
-
}
|
|
583
|
-
if (error?.status === 401) {
|
|
584
|
-
this.log("fatal: agent token rejected (401); run `relaymessenger pair` again.");
|
|
585
|
-
throw error;
|
|
586
|
-
}
|
|
587
|
-
failures += 1;
|
|
588
|
-
const base = Math.min(500 * 2 ** Math.min(failures, 6), 30_000);
|
|
589
|
-
const jitter = base * (0.7 + Math.random() * 0.6);
|
|
590
|
-
this.log(`poll failed (attempt ${failures}), retrying in ${Math.round(jitter)}ms: ${error}`);
|
|
591
|
-
await new Promise((resolve) => this.setTimeoutImpl(resolve, jitter));
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
//# sourceMappingURL=receive.js.map
|
package/dist/receive.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"receive.js","sourceRoot":"","sources":["../src/receive.ts"],"names":[],"mappings":"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"}
|