@agentshouse/mdruntime 0.1.0-c2e8a6f99866d → 0.1.0-c2ef9303a058d
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 +11 -9
- package/dist/adapter.d.ts +95 -67
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +5 -11
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +36 -47
- package/dist/binary.d.ts +0 -5
- package/dist/binary.d.ts.map +1 -1
- package/dist/binary.js +1 -1
- package/dist/bootstrap.d.ts +17 -9
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +143 -94
- package/dist/chain.d.ts +2 -1
- package/dist/chain.d.ts.map +1 -1
- package/dist/change-set.d.ts +1 -7
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +1 -4
- package/dist/client.d.ts +15 -12
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +56 -8
- package/dist/collection.d.ts +7 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +24 -19
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +117 -243
- package/dist/connection.d.ts +14 -12
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1466 -1431
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/{chat/context.js → context.js} +1 -4
- package/dist/conversation.d.ts +18 -15
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +273 -185
- package/dist/durability.d.ts +6 -4
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +5 -0
- package/dist/entry.d.ts +3 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +17 -8
- package/dist/file.d.ts +2 -11
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +6 -4
- package/dist/host.d.ts +3 -7
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +55 -38
- package/dist/identity.d.ts +0 -2
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +0 -6
- package/dist/index.d.ts +15 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/job.d.ts +14 -0
- package/dist/job.d.ts.map +1 -0
- package/dist/job.js +28 -0
- package/dist/live.d.ts +2 -1
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +9 -5
- package/dist/media.d.ts +8 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +218 -0
- package/dist/memory.d.ts +12 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +209 -101
- package/dist/messages.d.ts +28 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +89 -0
- package/dist/model.d.ts +8 -8
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +7 -13
- package/dist/observation.d.ts +3 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +8 -3
- package/dist/outcome.d.ts +13 -6
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +16 -5
- package/dist/overlay.js +1 -1
- package/dist/paths.d.ts +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +4 -0
- package/dist/query.d.ts +10 -206
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +3 -494
- package/dist/reach.d.ts +14 -9
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +84 -72
- package/dist/react.d.ts +3 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/readiness.d.ts +14 -17
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +2 -8
- package/dist/recovery.d.ts +1 -0
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +26 -0
- package/dist/refresh.d.ts +10 -4
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +88 -30
- package/dist/replica.d.ts +11 -8
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +30 -15
- package/dist/room-draft.d.ts +22 -5
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +131 -51
- package/dist/rows.d.ts +18 -16
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +45 -153
- package/dist/save.d.ts +2 -0
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +13 -7
- package/dist/search.d.ts +12 -95
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +10 -349
- package/dist/shared.d.ts +0 -1
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +0 -10
- package/dist/status.d.ts +4 -3
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +3 -1
- package/dist/store.d.ts +25 -62
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +43 -282
- package/dist/stored.d.ts +12 -26
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +189 -226
- package/dist/tables.d.ts +55 -48
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +107 -57
- package/dist/transfer.d.ts +0 -5
- package/dist/transfer.d.ts.map +1 -1
- package/dist/validation.d.ts +3 -4
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +39 -97
- package/dist/windows.d.ts +1 -12
- package/dist/windows.d.ts.map +1 -1
- package/dist/windows.js +2 -75
- package/dist/wire.d.ts +14 -9
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +5 -3
- package/package.json +14 -18
- package/AGENTS.md +0 -312
- package/dist/chat/acts.d.ts +0 -33
- package/dist/chat/acts.d.ts.map +0 -1
- package/dist/chat/acts.js +0 -36
- package/dist/chat/context.d.ts +0 -3
- package/dist/chat/context.d.ts.map +0 -1
- package/dist/chat/earlier.d.ts +0 -10
- package/dist/chat/earlier.d.ts.map +0 -1
- package/dist/chat/earlier.js +0 -54
- package/dist/chat/house.d.ts +0 -25
- package/dist/chat/house.d.ts.map +0 -1
- package/dist/chat/house.js +0 -38
- package/dist/chat/input.d.ts +0 -11
- package/dist/chat/input.d.ts.map +0 -1
- package/dist/chat/input.js +0 -92
- package/dist/chat/kit.d.ts +0 -61
- package/dist/chat/kit.d.ts.map +0 -1
- package/dist/chat/kit.js +0 -123
- package/dist/chat/lasting.d.ts +0 -6
- package/dist/chat/lasting.d.ts.map +0 -1
- package/dist/chat/lasting.js +0 -19
- package/dist/chat/list.d.ts +0 -28
- package/dist/chat/list.d.ts.map +0 -1
- package/dist/chat/list.js +0 -103
- package/dist/chat/markdown.d.ts +0 -21
- package/dist/chat/markdown.d.ts.map +0 -1
- package/dist/chat/markdown.js +0 -246
- package/dist/chat/message.d.ts +0 -7
- package/dist/chat/message.d.ts.map +0 -1
- package/dist/chat/message.js +0 -244
- package/dist/chat/messages.d.ts +0 -30
- package/dist/chat/messages.d.ts.map +0 -1
- package/dist/chat/messages.js +0 -198
- package/dist/chat/name.d.ts +0 -7
- package/dist/chat/name.d.ts.map +0 -1
- package/dist/chat/name.js +0 -37
- package/dist/chat/opened.d.ts +0 -12
- package/dist/chat/opened.d.ts.map +0 -1
- package/dist/chat/opened.js +0 -19
- package/dist/chat/overlay.d.ts +0 -32
- package/dist/chat/overlay.d.ts.map +0 -1
- package/dist/chat/overlay.js +0 -103
- package/dist/chat/parts.d.ts +0 -58
- package/dist/chat/parts.d.ts.map +0 -1
- package/dist/chat/parts.js +0 -120
- package/dist/chat/pieces.d.ts +0 -62
- package/dist/chat/pieces.d.ts.map +0 -1
- package/dist/chat/pieces.js +0 -1110
- package/dist/chat/process.d.ts +0 -20
- package/dist/chat/process.d.ts.map +0 -1
- package/dist/chat/process.js +0 -32
- package/dist/chat/provider.d.ts +0 -70
- package/dist/chat/provider.d.ts.map +0 -1
- package/dist/chat/provider.js +0 -635
- package/dist/chat/question.d.ts +0 -9
- package/dist/chat/question.d.ts.map +0 -1
- package/dist/chat/question.js +0 -69
- package/dist/chat/questions.d.ts +0 -31
- package/dist/chat/questions.d.ts.map +0 -1
- package/dist/chat/questions.js +0 -111
- package/dist/chat/read.d.ts +0 -5
- package/dist/chat/read.d.ts.map +0 -1
- package/dist/chat/read.js +0 -13
- package/dist/chat/ready.d.ts +0 -37
- package/dist/chat/ready.d.ts.map +0 -1
- package/dist/chat/ready.js +0 -93
- package/dist/chat/room-file.d.ts +0 -8
- package/dist/chat/room-file.d.ts.map +0 -1
- package/dist/chat/room-file.js +0 -72
- package/dist/chat/steady.d.ts +0 -3
- package/dist/chat/steady.d.ts.map +0 -1
- package/dist/chat/steady.js +0 -26
- package/dist/chat/style.d.ts +0 -4
- package/dist/chat/style.d.ts.map +0 -1
- package/dist/chat/style.js +0 -306
- package/dist/chat.d.ts +0 -15
- package/dist/chat.d.ts.map +0 -1
- package/dist/chat.js +0 -8
- package/dist/reads.d.ts +0 -11
- package/dist/reads.d.ts.map +0 -1
- package/dist/reads.js +0 -98
package/dist/conversation.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { cursorOf, decodedCursor } from '@agentshouse/mdmodel';
|
|
1
2
|
import { conversationChangeSet } from './change-set.js';
|
|
2
3
|
import { runtimeError } from './failure.js';
|
|
3
|
-
import {
|
|
4
|
+
import { refusedForSpace } from './durability.js';
|
|
4
5
|
import { changeBatchIdentity, chatDraftRevision } from './identity.js';
|
|
5
6
|
import { OFFLINE } from './outcome.js';
|
|
6
|
-
import {
|
|
7
|
+
import { untilAnswered } from './recovery.js';
|
|
8
|
+
import { capped, FROM_START, messageOrder, precedes } from './windows.js';
|
|
7
9
|
const QUIET = {
|
|
8
10
|
turn: null,
|
|
9
11
|
questions: [],
|
|
@@ -11,6 +13,7 @@ const QUIET = {
|
|
|
11
13
|
commands: [],
|
|
12
14
|
options: [],
|
|
13
15
|
starting: null,
|
|
16
|
+
subagents: [],
|
|
14
17
|
link: null,
|
|
15
18
|
deliveryUnknown: [],
|
|
16
19
|
};
|
|
@@ -20,6 +23,7 @@ const FACTS = [
|
|
|
20
23
|
'commands',
|
|
21
24
|
'options',
|
|
22
25
|
'starting',
|
|
26
|
+
'subagents',
|
|
23
27
|
'link',
|
|
24
28
|
'deliveryUnknown',
|
|
25
29
|
];
|
|
@@ -30,9 +34,11 @@ export function unheldView(conversation) {
|
|
|
30
34
|
turn: null,
|
|
31
35
|
questions: [],
|
|
32
36
|
process: null,
|
|
37
|
+
processEnded: null,
|
|
33
38
|
commands: [],
|
|
34
39
|
options: [],
|
|
35
40
|
starting: null,
|
|
41
|
+
subagents: [],
|
|
36
42
|
link: null,
|
|
37
43
|
deliveryUnknown: [],
|
|
38
44
|
chatDraft: null,
|
|
@@ -40,16 +46,15 @@ export function unheldView(conversation) {
|
|
|
40
46
|
}
|
|
41
47
|
export const SESSION_STARTED = 'Session started';
|
|
42
48
|
const NEW_CHAT = 'new:';
|
|
49
|
+
export const HISTORY_CONVERSATIONS = 64;
|
|
43
50
|
export function newChat(agent) {
|
|
44
51
|
return `${NEW_CHAT}${agent}`;
|
|
45
52
|
}
|
|
46
53
|
function creationOf(input) {
|
|
47
54
|
if (typeof input !== 'object' || input === null)
|
|
48
55
|
return null;
|
|
49
|
-
const { agent_id: agent, operation_id: operation
|
|
50
|
-
return typeof agent === 'string' && typeof operation === 'string'
|
|
51
|
-
? { agent, operation }
|
|
52
|
-
: null;
|
|
56
|
+
const { agent_id: agent, operation_id: operation } = input;
|
|
57
|
+
return typeof agent === 'string' && typeof operation === 'string' ? { agent, operation } : null;
|
|
53
58
|
}
|
|
54
59
|
function startedTurn(turn, operation) {
|
|
55
60
|
if (operation.op === 'begin')
|
|
@@ -208,7 +213,20 @@ function askedOf(options) {
|
|
|
208
213
|
}
|
|
209
214
|
return { limit: capped(limit), after, before: beforeOf(after), total: total === true };
|
|
210
215
|
}
|
|
211
|
-
|
|
216
|
+
function phraseOf(text) {
|
|
217
|
+
if (text === undefined)
|
|
218
|
+
return null;
|
|
219
|
+
if (typeof text !== 'string' || text === '') {
|
|
220
|
+
throw runtimeError('invalid-text', 'a conversation is found by a phrase');
|
|
221
|
+
}
|
|
222
|
+
return text;
|
|
223
|
+
}
|
|
224
|
+
const DURABLE_WRITE = {
|
|
225
|
+
kind: 'rejected',
|
|
226
|
+
code: 'durable-write',
|
|
227
|
+
fields: {},
|
|
228
|
+
retryable: true,
|
|
229
|
+
};
|
|
212
230
|
function unwritten(draft) {
|
|
213
231
|
return draft.text === '';
|
|
214
232
|
}
|
|
@@ -248,13 +266,19 @@ export function createConversationStore(deps) {
|
|
|
248
266
|
const unsent = new Map();
|
|
249
267
|
const views = new Map();
|
|
250
268
|
const listing = new Map();
|
|
269
|
+
let relisting = null;
|
|
270
|
+
let listCursor = null;
|
|
251
271
|
const creations = new Set();
|
|
252
272
|
const listWatchers = new Set();
|
|
273
|
+
const unlisted = new Set();
|
|
253
274
|
let listKnown = false;
|
|
275
|
+
let listHeld = false;
|
|
276
|
+
let listKept = false;
|
|
254
277
|
const agentWatchers = new Set();
|
|
255
|
-
|
|
256
|
-
let
|
|
257
|
-
let
|
|
278
|
+
const unnamed = new Set();
|
|
279
|
+
let agentsShown = null;
|
|
280
|
+
let listedAgents = null;
|
|
281
|
+
let agentsReading = false;
|
|
258
282
|
let replicated = new Set();
|
|
259
283
|
let handedReplicated;
|
|
260
284
|
function liveOf(conversation) {
|
|
@@ -275,9 +299,11 @@ export function createConversationStore(deps) {
|
|
|
275
299
|
turn: structuredClone(facts.turn),
|
|
276
300
|
questions: structuredClone(facts.questions),
|
|
277
301
|
process: facts.process === null ? null : { ...facts.process },
|
|
302
|
+
processEnded: listing.get(conversation)?.processEnded ?? null,
|
|
278
303
|
commands: structuredClone(facts.commands),
|
|
279
304
|
options: structuredClone(facts.options),
|
|
280
305
|
starting: facts.starting,
|
|
306
|
+
subagents: structuredClone(facts.subagents),
|
|
281
307
|
link: facts.link === null ? null : { ...facts.link },
|
|
282
308
|
deliveryUnknown: [...facts.deliveryUnknown],
|
|
283
309
|
chatDraft: draft === undefined || unwritten(draft)
|
|
@@ -324,9 +350,6 @@ export function createConversationStore(deps) {
|
|
|
324
350
|
}
|
|
325
351
|
}
|
|
326
352
|
}
|
|
327
|
-
function changesOf(conversation, arriving) {
|
|
328
|
-
return arriving.map(({ identity, text }) => ({ conversation, identity, text }));
|
|
329
|
-
}
|
|
330
353
|
function stateOf(conversation) {
|
|
331
354
|
const facts = liveOf(conversation);
|
|
332
355
|
if (facts.questions.length > 0)
|
|
@@ -336,7 +359,7 @@ export function createConversationStore(deps) {
|
|
|
336
359
|
function entries() {
|
|
337
360
|
return [...listing.values()].map((entry) => ({
|
|
338
361
|
conversation: entry.conversation,
|
|
339
|
-
agent: { identity: entry.agent, name:
|
|
362
|
+
agent: { identity: entry.agent, name: entry.agentName },
|
|
340
363
|
name: entry.name,
|
|
341
364
|
created: entry.created,
|
|
342
365
|
finished: entry.finished,
|
|
@@ -346,25 +369,103 @@ export function createConversationStore(deps) {
|
|
|
346
369
|
started: lives.get(entry.conversation)?.turn?.started ?? null,
|
|
347
370
|
}));
|
|
348
371
|
}
|
|
372
|
+
function keepList() {
|
|
373
|
+
if (!listKnown || listKept)
|
|
374
|
+
return;
|
|
375
|
+
listKept = true;
|
|
376
|
+
queueMicrotask(() => {
|
|
377
|
+
listKept = false;
|
|
378
|
+
if (deps.closed())
|
|
379
|
+
return;
|
|
380
|
+
const entries = [...listing.values()];
|
|
381
|
+
const cursor = listCursor;
|
|
382
|
+
void deps
|
|
383
|
+
.durably(async (local) => {
|
|
384
|
+
await local.fact('conversationList', entries);
|
|
385
|
+
await local.fact('conversationCursor', cursor);
|
|
386
|
+
})
|
|
387
|
+
.catch(() => { });
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
function listed(entry) {
|
|
391
|
+
const ended = listing.get(entry.conversation)?.processEnded ?? null;
|
|
392
|
+
listing.set(entry.conversation, { ...entry });
|
|
393
|
+
creations.delete(entry.conversation);
|
|
394
|
+
if (entry.processEnded !== ended)
|
|
395
|
+
emit(entry.conversation);
|
|
396
|
+
}
|
|
349
397
|
function emitList() {
|
|
350
|
-
if (deps.closed()
|
|
398
|
+
if (deps.closed())
|
|
351
399
|
return;
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
watcher
|
|
400
|
+
if (listWatchers.size > 0) {
|
|
401
|
+
const value = entries();
|
|
402
|
+
for (const watcher of listWatchers)
|
|
403
|
+
watcher(value);
|
|
404
|
+
}
|
|
405
|
+
emitAgents();
|
|
406
|
+
learned();
|
|
407
|
+
}
|
|
408
|
+
function learned() {
|
|
409
|
+
if (deps.closed())
|
|
410
|
+
return;
|
|
411
|
+
if (!listKnown && !listHeld && deps.stream() !== undefined && deps.online())
|
|
412
|
+
return;
|
|
413
|
+
if (unlisted.size > 0) {
|
|
414
|
+
const value = entries();
|
|
415
|
+
for (const watcher of [...unlisted]) {
|
|
416
|
+
unlisted.delete(watcher);
|
|
417
|
+
listWatchers.add(watcher);
|
|
418
|
+
watcher(value);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
if (unnamed.size > 0) {
|
|
422
|
+
const value = agents();
|
|
423
|
+
for (const watcher of [...unnamed]) {
|
|
424
|
+
unnamed.delete(watcher);
|
|
425
|
+
agentWatchers.add(watcher);
|
|
426
|
+
watcher(value);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
355
429
|
}
|
|
356
430
|
function agents() {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
.
|
|
431
|
+
const named = new Map();
|
|
432
|
+
for (const agent of listedAgents ?? [])
|
|
433
|
+
named.set(agent.agent, agent);
|
|
434
|
+
for (const entry of listing.values()) {
|
|
435
|
+
named.set(entry.agent, { name: entry.agentName, retired: entry.agentRetired });
|
|
436
|
+
}
|
|
437
|
+
return [...named]
|
|
438
|
+
.filter(([, agent]) => !agent.retired)
|
|
439
|
+
.map(([identity, agent]) => ({ identity, name: agent.name }))
|
|
360
440
|
.sort((left, right) => left.name === right.name
|
|
361
441
|
? left.identity.localeCompare(right.identity)
|
|
362
442
|
: left.name.localeCompare(right.name));
|
|
363
443
|
}
|
|
444
|
+
function readAgents() {
|
|
445
|
+
const stream = deps.stream();
|
|
446
|
+
if (stream?.agents === undefined || !deps.online() || agentsReading)
|
|
447
|
+
return;
|
|
448
|
+
agentsReading = true;
|
|
449
|
+
void stream
|
|
450
|
+
.agents()
|
|
451
|
+
.then((read) => {
|
|
452
|
+
if (read === null)
|
|
453
|
+
return;
|
|
454
|
+
listedAgents = read;
|
|
455
|
+
emitAgents();
|
|
456
|
+
}, () => { })
|
|
457
|
+
.finally(() => {
|
|
458
|
+
agentsReading = false;
|
|
459
|
+
});
|
|
460
|
+
}
|
|
364
461
|
function emitAgents() {
|
|
365
462
|
if (deps.closed() || agentWatchers.size === 0)
|
|
366
463
|
return;
|
|
367
464
|
const value = agents();
|
|
465
|
+
const shown = JSON.stringify(value);
|
|
466
|
+
if (shown === agentsShown)
|
|
467
|
+
return;
|
|
468
|
+
agentsShown = shown;
|
|
368
469
|
for (const watcher of agentWatchers)
|
|
369
470
|
watcher(value);
|
|
370
471
|
}
|
|
@@ -380,55 +481,11 @@ export function createConversationStore(deps) {
|
|
|
380
481
|
if (stateOf(conversation) !== before || next?.turn?.started !== began)
|
|
381
482
|
emitList();
|
|
382
483
|
}
|
|
383
|
-
async function readAgents() {
|
|
384
|
-
const declaration = deps.agents();
|
|
385
|
-
if (declaration === undefined)
|
|
386
|
-
return;
|
|
387
|
-
const names = new Map();
|
|
388
|
-
const retired = new Set();
|
|
389
|
-
let covered = null;
|
|
390
|
-
for (let after;;) {
|
|
391
|
-
const read = await deps.documents(declaration, after);
|
|
392
|
-
if ('pending' in read)
|
|
393
|
-
return;
|
|
394
|
-
const coverage = JSON.stringify(read.coverage);
|
|
395
|
-
if (covered !== null && coverage !== covered)
|
|
396
|
-
return readAgents();
|
|
397
|
-
covered = coverage;
|
|
398
|
-
for (const document of read.documents) {
|
|
399
|
-
const identity = document.fields?.[declaration.identity];
|
|
400
|
-
const name = document.fields?.[declaration.name];
|
|
401
|
-
if (typeof identity !== 'string' || typeof name !== 'string')
|
|
402
|
-
continue;
|
|
403
|
-
names.set(identity, name);
|
|
404
|
-
const ended = declaration.retired === undefined ? null : document.fields?.[declaration.retired];
|
|
405
|
-
if (ended !== undefined && ended !== null)
|
|
406
|
-
retired.add(identity);
|
|
407
|
-
}
|
|
408
|
-
if (read.next === undefined)
|
|
409
|
-
break;
|
|
410
|
-
after = read.next;
|
|
411
|
-
}
|
|
412
|
-
const named = JSON.stringify([...names]) !== JSON.stringify([...agentNames]);
|
|
413
|
-
if (!named && JSON.stringify([...retired]) === JSON.stringify([...retiredAgents]))
|
|
414
|
-
return;
|
|
415
|
-
agentNames = names;
|
|
416
|
-
retiredAgents = retired;
|
|
417
|
-
if (named)
|
|
418
|
-
emitList();
|
|
419
|
-
emitAgents();
|
|
420
|
-
const ended = [...drafts.keys()].filter(retiredChat);
|
|
421
|
-
if (ended.length > 0)
|
|
422
|
-
await remove(ended);
|
|
423
|
-
}
|
|
424
484
|
function retiredChat(conversation) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
agentsRead = null;
|
|
430
|
-
});
|
|
431
|
-
return agentsRead;
|
|
485
|
+
if (!conversation.startsWith(NEW_CHAT))
|
|
486
|
+
return false;
|
|
487
|
+
const agent = conversation.slice(NEW_CHAT.length);
|
|
488
|
+
return [...listing.values()].some((entry) => entry.agent === agent && entry.agentRetired);
|
|
432
489
|
}
|
|
433
490
|
function live(conversation, change) {
|
|
434
491
|
const owed = unsent.get(conversation);
|
|
@@ -451,6 +508,7 @@ export function createConversationStore(deps) {
|
|
|
451
508
|
commands: facts.has('commands') ? QUIET.commands : held.commands,
|
|
452
509
|
options: facts.has('options') ? QUIET.options : held.options,
|
|
453
510
|
starting: facts.has('starting') ? QUIET.starting : held.starting,
|
|
511
|
+
subagents: facts.has('subagents') ? QUIET.subagents : held.subagents,
|
|
454
512
|
link: facts.has('link') ? QUIET.link : held.link,
|
|
455
513
|
deliveryUnknown: facts.has('deliveryUnknown')
|
|
456
514
|
? QUIET.deliveryUnknown
|
|
@@ -485,12 +543,6 @@ export function createConversationStore(deps) {
|
|
|
485
543
|
}
|
|
486
544
|
async function remove(leaving) {
|
|
487
545
|
await deps.durably(async (local) => {
|
|
488
|
-
const removed = [];
|
|
489
|
-
for (const conversation of leaving) {
|
|
490
|
-
for (const identity of await local.messageIdentities(conversation)) {
|
|
491
|
-
removed.push({ conversation, identity, text: null });
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
546
|
await local.dropConversations(leaving);
|
|
495
547
|
const changed = [];
|
|
496
548
|
for (const conversation of leaving) {
|
|
@@ -507,9 +559,23 @@ export function createConversationStore(deps) {
|
|
|
507
559
|
await slide(local, conversation, null);
|
|
508
560
|
}
|
|
509
561
|
if (changed.length > 0)
|
|
510
|
-
deps.publish(conversationChangeSet(
|
|
562
|
+
deps.publish(conversationChangeSet(changed));
|
|
511
563
|
});
|
|
512
564
|
}
|
|
565
|
+
function missed(conversation) {
|
|
566
|
+
const read = reads.get(conversation);
|
|
567
|
+
const newest = listing.get(conversation)?.newest;
|
|
568
|
+
return (read === undefined ||
|
|
569
|
+
newest === undefined ||
|
|
570
|
+
partials.has(conversation) ||
|
|
571
|
+
(newest !== null && (read === null || newest > read)));
|
|
572
|
+
}
|
|
573
|
+
function noted(conversation, message) {
|
|
574
|
+
const entry = listing.get(conversation);
|
|
575
|
+
if (entry === undefined || (entry.newest !== null && entry.newest >= message.position))
|
|
576
|
+
return;
|
|
577
|
+
listing.set(conversation, { ...entry, newest: message.position });
|
|
578
|
+
}
|
|
513
579
|
function gap(conversation) {
|
|
514
580
|
gaps.set(conversation, (gaps.get(conversation) ?? 0) + 1);
|
|
515
581
|
behind.add(conversation);
|
|
@@ -533,17 +599,18 @@ export function createConversationStore(deps) {
|
|
|
533
599
|
reads.set(conversation, message.position);
|
|
534
600
|
sealTurns(conversation, new Set([message.turn]));
|
|
535
601
|
await slide(local, conversation, [message]);
|
|
536
|
-
deps.publish(conversationChangeSet(
|
|
602
|
+
deps.publish(conversationChangeSet([conversation]));
|
|
537
603
|
});
|
|
538
604
|
}
|
|
539
605
|
async function readHistories(conversations, ended) {
|
|
540
606
|
const generations = new Map(conversations.map((one) => [one, gaps.get(one) ?? 0]));
|
|
541
|
-
let
|
|
607
|
+
let waiting = conversations.map((conversation) => ({
|
|
542
608
|
conversation,
|
|
543
609
|
after: reads.get(conversation) ?? undefined,
|
|
544
610
|
}));
|
|
545
|
-
while (
|
|
546
|
-
const
|
|
611
|
+
while (waiting.length > 0) {
|
|
612
|
+
const asking = waiting.slice(0, HISTORY_CONVERSATIONS);
|
|
613
|
+
const result = await deps.history({
|
|
547
614
|
conversations: asking.map(({ conversation, after }) => ({
|
|
548
615
|
conversation,
|
|
549
616
|
...(after === undefined ? {} : { after }),
|
|
@@ -566,7 +633,7 @@ export function createConversationStore(deps) {
|
|
|
566
633
|
if (!following.some((next) => next.conversation === conversation))
|
|
567
634
|
ended(conversation);
|
|
568
635
|
}
|
|
569
|
-
|
|
636
|
+
waiting = [...waiting.slice(HISTORY_CONVERSATIONS), ...following];
|
|
570
637
|
}
|
|
571
638
|
return null;
|
|
572
639
|
}
|
|
@@ -609,7 +676,7 @@ export function createConversationStore(deps) {
|
|
|
609
676
|
behind.delete(conversation);
|
|
610
677
|
await slide(local, conversation, arriving);
|
|
611
678
|
if (arriving.length > 0 || sealing || whole) {
|
|
612
|
-
deps.publish(conversationChangeSet(
|
|
679
|
+
deps.publish(conversationChangeSet([conversation]));
|
|
613
680
|
}
|
|
614
681
|
});
|
|
615
682
|
}
|
|
@@ -646,6 +713,10 @@ export function createConversationStore(deps) {
|
|
|
646
713
|
live(conversation, { starting: event.step });
|
|
647
714
|
return;
|
|
648
715
|
}
|
|
716
|
+
if (event.kind === 'subagents') {
|
|
717
|
+
live(conversation, { subagents: structuredClone(event.subagents) });
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
649
720
|
if (event.kind === 'link') {
|
|
650
721
|
live(conversation, { link: { connected: event.connected } });
|
|
651
722
|
return;
|
|
@@ -657,8 +728,16 @@ export function createConversationStore(deps) {
|
|
|
657
728
|
const arriving = acceptedMessage(event.message);
|
|
658
729
|
if (arriving === null)
|
|
659
730
|
return;
|
|
731
|
+
noted(conversation, arriving);
|
|
660
732
|
if (replicated.has(conversation)) {
|
|
661
|
-
|
|
733
|
+
if (deps.full()) {
|
|
734
|
+
gap(conversation);
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
void keep(conversation, arriving).catch((error) => {
|
|
738
|
+
if (refusedForSpace(error))
|
|
739
|
+
gap(conversation);
|
|
740
|
+
});
|
|
662
741
|
return;
|
|
663
742
|
}
|
|
664
743
|
if (sealTurns(conversation, new Set([arriving.turn])))
|
|
@@ -687,7 +766,7 @@ export function createConversationStore(deps) {
|
|
|
687
766
|
const from = newChat(agent);
|
|
688
767
|
return deps.durably(async (local) => {
|
|
689
768
|
const held = drafts.get(from);
|
|
690
|
-
const earlier =
|
|
769
|
+
const earlier = held?.moves ?? [];
|
|
691
770
|
if (earlier.includes(operation))
|
|
692
771
|
return;
|
|
693
772
|
const blank = {
|
|
@@ -702,7 +781,7 @@ export function createConversationStore(deps) {
|
|
|
702
781
|
drafts.set(from, left);
|
|
703
782
|
for (const one of taken)
|
|
704
783
|
drafts.set(to, one);
|
|
705
|
-
deps.publish(conversationChangeSet([
|
|
784
|
+
deps.publish(conversationChangeSet([from, to]));
|
|
706
785
|
});
|
|
707
786
|
}
|
|
708
787
|
function withDraft(conversation, next) {
|
|
@@ -711,15 +790,13 @@ export function createConversationStore(deps) {
|
|
|
711
790
|
if (following === undefined)
|
|
712
791
|
return;
|
|
713
792
|
await kept(local, conversation, following);
|
|
714
|
-
deps.publish(conversationChangeSet([
|
|
793
|
+
deps.publish(conversationChangeSet([conversation]));
|
|
715
794
|
});
|
|
716
795
|
}
|
|
717
796
|
async function submitted(conversation, operation, draft) {
|
|
718
797
|
let submission;
|
|
719
|
-
let earlier = false;
|
|
720
798
|
await withDraft(conversation, (current) => {
|
|
721
799
|
submission = current?.submitted?.find((one) => one.operation === operation);
|
|
722
|
-
earlier = submission !== undefined;
|
|
723
800
|
if (submission !== undefined)
|
|
724
801
|
return undefined;
|
|
725
802
|
const said = draft ?? current;
|
|
@@ -732,31 +809,24 @@ export function createConversationStore(deps) {
|
|
|
732
809
|
submitted: [...(current?.submitted ?? []), submission],
|
|
733
810
|
};
|
|
734
811
|
});
|
|
735
|
-
return
|
|
736
|
-
}
|
|
737
|
-
function forgotten(conversation, submission) {
|
|
738
|
-
return withDraft(conversation, (current) => {
|
|
739
|
-
const held = current?.submitted ?? [];
|
|
740
|
-
if (current === undefined || !held.includes(submission))
|
|
741
|
-
return undefined;
|
|
742
|
-
return withSubmitted(current, held.filter((one) => one !== submission));
|
|
743
|
-
});
|
|
812
|
+
return submission;
|
|
744
813
|
}
|
|
745
814
|
async function dispatched(conversation, submission) {
|
|
746
|
-
const dispatch = {};
|
|
815
|
+
const dispatch = { answered: false };
|
|
747
816
|
sending.set(submission.operation, dispatch);
|
|
748
817
|
try {
|
|
749
|
-
const result = await invoke('
|
|
750
|
-
text: submission.text,
|
|
818
|
+
const result = await invoke('conversations/send', conversation, {
|
|
751
819
|
operation_id: submission.operation,
|
|
820
|
+
text: submission.text,
|
|
752
821
|
});
|
|
822
|
+
dispatch.answered = result.kind !== 'transport-uncertainty';
|
|
753
823
|
if (result.kind === 'revoked-authorization')
|
|
754
824
|
return result;
|
|
755
825
|
if (result.kind !== 'action' && result.retryable) {
|
|
756
826
|
deps.unanswered();
|
|
757
827
|
return result;
|
|
758
828
|
}
|
|
759
|
-
const turn = answered(result, '
|
|
829
|
+
const turn = answered(result, 'message_id');
|
|
760
830
|
await withDraft(conversation, async (current, local) => {
|
|
761
831
|
const held = current?.submitted?.find((one) => one.operation === submission.operation);
|
|
762
832
|
if (current === undefined || held === undefined || held.turn !== null)
|
|
@@ -776,25 +846,34 @@ export function createConversationStore(deps) {
|
|
|
776
846
|
sending.delete(submission.operation);
|
|
777
847
|
}
|
|
778
848
|
}
|
|
779
|
-
function invoke(name, conversation, extra = {}) {
|
|
780
|
-
return deps.call(name, { conversation, ...extra });
|
|
849
|
+
function invoke(name, conversation, extra = { operation_id: changeBatchIdentity() }) {
|
|
850
|
+
return deps.call(name, { conversation_id: conversation, ...extra });
|
|
781
851
|
}
|
|
782
852
|
const surface = {
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
853
|
+
list() {
|
|
854
|
+
return new Promise((settle) => {
|
|
855
|
+
const answer = (listed) => {
|
|
856
|
+
unlisted.delete(answer);
|
|
857
|
+
listWatchers.delete(answer);
|
|
858
|
+
settle(listed);
|
|
859
|
+
};
|
|
860
|
+
unlisted.add(answer);
|
|
861
|
+
learned();
|
|
862
|
+
});
|
|
786
863
|
},
|
|
787
864
|
async read(conversation, options = {}) {
|
|
788
|
-
const
|
|
865
|
+
const { text, ...windowed } = options;
|
|
866
|
+
const asked = askedOf(windowed);
|
|
867
|
+
const phrase = phraseOf(text);
|
|
789
868
|
return deps.durably(async (local) => {
|
|
790
|
-
const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
|
|
791
|
-
const total = asked.total ? await local.messageCount(conversation) : null;
|
|
869
|
+
const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before, phrase);
|
|
870
|
+
const total = asked.total ? await local.messageCount(conversation, phrase) : null;
|
|
792
871
|
return structuredClone(viewOf(conversation, messages, frameOf(asked, messages, more, total)));
|
|
793
872
|
});
|
|
794
873
|
},
|
|
795
874
|
async create(input) {
|
|
796
|
-
const result = await deps.call('
|
|
797
|
-
const conversation = answered(result, '
|
|
875
|
+
const result = await deps.call('conversations/create', input);
|
|
876
|
+
const conversation = answered(result, 'conversation_id');
|
|
798
877
|
if (conversation === null)
|
|
799
878
|
return result;
|
|
800
879
|
if (!listing.has(conversation))
|
|
@@ -805,12 +884,17 @@ export function createConversationStore(deps) {
|
|
|
805
884
|
return result;
|
|
806
885
|
},
|
|
807
886
|
async send(conversation, operation = changeBatchIdentity(), draft) {
|
|
887
|
+
if (deps.full())
|
|
888
|
+
return DURABLE_WRITE;
|
|
808
889
|
if (deps.online()) {
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
890
|
+
const held = await submitted(conversation, operation, draft).catch((error) => {
|
|
891
|
+
if (refusedForSpace(error))
|
|
892
|
+
return null;
|
|
893
|
+
throw error;
|
|
894
|
+
});
|
|
895
|
+
if (held === null)
|
|
896
|
+
return DURABLE_WRITE;
|
|
897
|
+
return dispatched(conversation, held);
|
|
814
898
|
}
|
|
815
899
|
if (draft !== undefined) {
|
|
816
900
|
await withDraft(conversation, (current) => current?.submitted?.some((one) => one.operation === operation) === true
|
|
@@ -819,38 +903,20 @@ export function createConversationStore(deps) {
|
|
|
819
903
|
}
|
|
820
904
|
return OFFLINE;
|
|
821
905
|
},
|
|
822
|
-
async attach(room, file) {
|
|
823
|
-
if (!deps.online())
|
|
824
|
-
return OFFLINE;
|
|
825
|
-
return deps.call('conversation.attach', {
|
|
826
|
-
room,
|
|
827
|
-
...(await declaredFile(file)),
|
|
828
|
-
blob: file.blob,
|
|
829
|
-
});
|
|
830
|
-
},
|
|
831
906
|
answer(conversation, answer) {
|
|
832
|
-
return invoke('
|
|
907
|
+
return invoke('conversations/interaction/answer', conversation, {
|
|
908
|
+
operation_id: changeBatchIdentity(),
|
|
909
|
+
...answer,
|
|
910
|
+
});
|
|
833
911
|
},
|
|
834
912
|
interrupt(conversation) {
|
|
835
|
-
return invoke('
|
|
913
|
+
return invoke('conversations/interrupt', conversation);
|
|
836
914
|
},
|
|
837
915
|
kill(conversation) {
|
|
838
|
-
return invoke('
|
|
839
|
-
},
|
|
840
|
-
async cancel(conversation, turn) {
|
|
841
|
-
const result = await invoke('conversation.cancel', conversation, { turn });
|
|
842
|
-
if (result.kind !== 'action')
|
|
843
|
-
return result;
|
|
844
|
-
await withDraft(conversation, (current) => {
|
|
845
|
-
const held = current?.submitted?.find((one) => one.turn === turn);
|
|
846
|
-
if (current === undefined || held === undefined)
|
|
847
|
-
return undefined;
|
|
848
|
-
return returned(current, held, current.submitted.filter((one) => one !== held));
|
|
849
|
-
});
|
|
850
|
-
return result;
|
|
916
|
+
return invoke('conversations/kill', conversation);
|
|
851
917
|
},
|
|
852
918
|
delete(conversation) {
|
|
853
|
-
return invoke('
|
|
919
|
+
return invoke('conversations/delete', conversation);
|
|
854
920
|
},
|
|
855
921
|
};
|
|
856
922
|
const chatDraft = {
|
|
@@ -879,7 +945,15 @@ export function createConversationStore(deps) {
|
|
|
879
945
|
return {
|
|
880
946
|
surface,
|
|
881
947
|
chatDraft,
|
|
882
|
-
hydrate(held, kept) {
|
|
948
|
+
hydrate(held, kept, list, cursor) {
|
|
949
|
+
if (list !== null && !listKnown) {
|
|
950
|
+
listing.clear();
|
|
951
|
+
for (const entry of list)
|
|
952
|
+
listing.set(entry.conversation, { ...entry });
|
|
953
|
+
listHeld = true;
|
|
954
|
+
listCursor = cursor;
|
|
955
|
+
deps.stream()?.hold(cursor);
|
|
956
|
+
}
|
|
883
957
|
stored.clear();
|
|
884
958
|
reads.clear();
|
|
885
959
|
partials.clear();
|
|
@@ -893,6 +967,8 @@ export function createConversationStore(deps) {
|
|
|
893
967
|
drafts.clear();
|
|
894
968
|
for (const record of kept)
|
|
895
969
|
drafts.set(record.conversation, record);
|
|
970
|
+
if (listHeld)
|
|
971
|
+
learned();
|
|
896
972
|
},
|
|
897
973
|
async reconcile() {
|
|
898
974
|
if (!listKnown)
|
|
@@ -904,7 +980,7 @@ export function createConversationStore(deps) {
|
|
|
904
980
|
!creations.has(conversation) &&
|
|
905
981
|
(!conversation.startsWith(NEW_CHAT) || retiredChat(conversation)));
|
|
906
982
|
for (const conversation of named) {
|
|
907
|
-
if (!replicated.has(conversation))
|
|
983
|
+
if (!replicated.has(conversation) && missed(conversation))
|
|
908
984
|
behind.add(conversation);
|
|
909
985
|
}
|
|
910
986
|
replicated = named;
|
|
@@ -913,6 +989,11 @@ export function createConversationStore(deps) {
|
|
|
913
989
|
await remove(leaving);
|
|
914
990
|
},
|
|
915
991
|
async catchUp(progress) {
|
|
992
|
+
if (deps.full()) {
|
|
993
|
+
if (behind.size > 0)
|
|
994
|
+
progress.complete = false;
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
916
997
|
const owed = (conversation) => behind.has(conversation) && replicated.has(conversation);
|
|
917
998
|
const read = async (conversations) => {
|
|
918
999
|
if (conversations.length === 0 || deps.closed())
|
|
@@ -937,10 +1018,6 @@ export function createConversationStore(deps) {
|
|
|
937
1018
|
continue;
|
|
938
1019
|
if (deps.closed())
|
|
939
1020
|
return;
|
|
940
|
-
if (deps.expired(submission.operation)) {
|
|
941
|
-
await forgotten(conversation, submission);
|
|
942
|
-
continue;
|
|
943
|
-
}
|
|
944
1021
|
const result = await dispatched(conversation, submission);
|
|
945
1022
|
if (result.kind === 'revoked-authorization')
|
|
946
1023
|
return;
|
|
@@ -961,12 +1038,11 @@ export function createConversationStore(deps) {
|
|
|
961
1038
|
known() {
|
|
962
1039
|
return listKnown;
|
|
963
1040
|
},
|
|
964
|
-
reconnected() {
|
|
965
|
-
for (const conversation of replicated)
|
|
966
|
-
gap(conversation);
|
|
967
|
-
},
|
|
968
1041
|
reopened() {
|
|
969
|
-
|
|
1042
|
+
relisting = null;
|
|
1043
|
+
for (const [operation, dispatch] of sending)
|
|
1044
|
+
if (!dispatch.answered)
|
|
1045
|
+
sending.delete(operation);
|
|
970
1046
|
},
|
|
971
1047
|
lost() {
|
|
972
1048
|
catching.clear();
|
|
@@ -985,15 +1061,15 @@ export function createConversationStore(deps) {
|
|
|
985
1061
|
views.set(key, view);
|
|
986
1062
|
const watcher = { notify: deliver, ready: false };
|
|
987
1063
|
view.watchers.add(watcher);
|
|
988
|
-
|
|
989
|
-
|
|
1064
|
+
const reading = new AbortController();
|
|
1065
|
+
void untilAnswered(() => deps.durably(async (local) => {
|
|
990
1066
|
if (view.window !== null)
|
|
991
1067
|
return;
|
|
992
1068
|
const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
|
|
993
1069
|
view.window = messages;
|
|
994
1070
|
view.more = more;
|
|
995
1071
|
view.total = asked.total ? await local.messageCount(conversation) : null;
|
|
996
|
-
})
|
|
1072
|
+
}), reading.signal)
|
|
997
1073
|
.then(() => {
|
|
998
1074
|
if (deps.closed() || !view.watchers.has(watcher))
|
|
999
1075
|
return;
|
|
@@ -1003,6 +1079,7 @@ export function createConversationStore(deps) {
|
|
|
1003
1079
|
})
|
|
1004
1080
|
.catch(() => { });
|
|
1005
1081
|
return () => {
|
|
1082
|
+
reading.abort();
|
|
1006
1083
|
if (!view.watchers.delete(watcher))
|
|
1007
1084
|
return;
|
|
1008
1085
|
if (view.watchers.size === 0)
|
|
@@ -1010,77 +1087,88 @@ export function createConversationStore(deps) {
|
|
|
1010
1087
|
};
|
|
1011
1088
|
},
|
|
1012
1089
|
watchList(deliver) {
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
if (!deps.closed() && listWatchers.has(deliver))
|
|
1016
|
-
deliver(entries());
|
|
1017
|
-
});
|
|
1090
|
+
unlisted.add(deliver);
|
|
1091
|
+
learned();
|
|
1018
1092
|
return () => {
|
|
1093
|
+
unlisted.delete(deliver);
|
|
1019
1094
|
listWatchers.delete(deliver);
|
|
1020
1095
|
};
|
|
1021
1096
|
},
|
|
1022
1097
|
watchAgents(deliver) {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
deliver(agents());
|
|
1027
|
-
});
|
|
1098
|
+
unnamed.add(deliver);
|
|
1099
|
+
learned();
|
|
1100
|
+
readAgents();
|
|
1028
1101
|
return () => {
|
|
1102
|
+
unnamed.delete(deliver);
|
|
1029
1103
|
agentWatchers.delete(deliver);
|
|
1030
1104
|
};
|
|
1031
1105
|
},
|
|
1106
|
+
learned,
|
|
1032
1107
|
changed(set) {
|
|
1033
1108
|
for (const conversation of set.conversations)
|
|
1034
1109
|
emit(conversation);
|
|
1035
|
-
const declaration = deps.agents();
|
|
1036
|
-
if (declaration !== undefined &&
|
|
1037
|
-
set.documents.some((change) => change.locator === declaration.locator)) {
|
|
1038
|
-
agentsRead = readAgents().catch(() => {
|
|
1039
|
-
agentsRead = null;
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1042
1110
|
},
|
|
1043
1111
|
receive(event) {
|
|
1044
1112
|
if (deps.closed())
|
|
1045
1113
|
return false;
|
|
1046
1114
|
if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
|
|
1047
1115
|
if (event.kind === 'list') {
|
|
1048
|
-
|
|
1116
|
+
if (event.whole)
|
|
1117
|
+
relisting ??= new Map();
|
|
1049
1118
|
for (const entry of event.entries) {
|
|
1050
|
-
|
|
1051
|
-
|
|
1119
|
+
if (relisting === null)
|
|
1120
|
+
listed(entry);
|
|
1121
|
+
else
|
|
1122
|
+
relisting.set(entry.conversation, { ...entry });
|
|
1123
|
+
}
|
|
1124
|
+
if (event.more)
|
|
1125
|
+
return false;
|
|
1126
|
+
if (relisting !== null) {
|
|
1127
|
+
listing.clear();
|
|
1128
|
+
for (const entry of relisting.values())
|
|
1129
|
+
listed(entry);
|
|
1130
|
+
relisting = null;
|
|
1052
1131
|
}
|
|
1132
|
+
listCursor = event.cursor;
|
|
1133
|
+
deps.stream()?.hold(event.cursor);
|
|
1053
1134
|
listKnown = true;
|
|
1135
|
+
for (const conversation of replicated) {
|
|
1136
|
+
if (!listing.has(conversation))
|
|
1137
|
+
continue;
|
|
1138
|
+
if (!missed(conversation))
|
|
1139
|
+
behind.delete(conversation);
|
|
1140
|
+
else if (!behind.has(conversation))
|
|
1141
|
+
gap(conversation);
|
|
1142
|
+
}
|
|
1054
1143
|
openingEnded();
|
|
1055
1144
|
}
|
|
1056
1145
|
else if (event.kind === 'listed') {
|
|
1057
|
-
|
|
1058
|
-
|
|
1146
|
+
listed(event.entry);
|
|
1147
|
+
relisting?.set(event.entry.conversation, { ...event.entry });
|
|
1059
1148
|
}
|
|
1060
1149
|
else {
|
|
1061
1150
|
listing.delete(event.conversation);
|
|
1151
|
+
relisting?.delete(event.conversation);
|
|
1062
1152
|
}
|
|
1153
|
+
keepList();
|
|
1063
1154
|
emitList();
|
|
1064
|
-
return (event.kind !== 'list' &&
|
|
1155
|
+
return ((event.kind !== 'list' &&
|
|
1065
1156
|
listKnown &&
|
|
1066
1157
|
(listing.size !== replicated.size ||
|
|
1067
|
-
[...listing.keys()].some((conversation) => !replicated.has(conversation))))
|
|
1158
|
+
[...listing.keys()].some((conversation) => !replicated.has(conversation)))) ||
|
|
1159
|
+
(listKnown && [...drafts.keys()].some(retiredChat)));
|
|
1068
1160
|
}
|
|
1069
1161
|
heard(event);
|
|
1070
1162
|
return false;
|
|
1071
1163
|
},
|
|
1072
|
-
searchable() {
|
|
1073
|
-
return [...(listKnown ? listing.keys() : stored)].sort();
|
|
1074
|
-
},
|
|
1075
|
-
acquired(conversation) {
|
|
1076
|
-
return reads.has(conversation) && !partials.has(conversation);
|
|
1077
|
-
},
|
|
1078
1164
|
close() {
|
|
1079
1165
|
views.clear();
|
|
1080
1166
|
lives.clear();
|
|
1081
1167
|
unsent.clear();
|
|
1082
1168
|
listWatchers.clear();
|
|
1169
|
+
unlisted.clear();
|
|
1083
1170
|
agentWatchers.clear();
|
|
1171
|
+
unnamed.clear();
|
|
1084
1172
|
},
|
|
1085
1173
|
};
|
|
1086
1174
|
}
|