@agentshouse/mdruntime 0.1.0-cee9c8aa4cd86 → 0.1.0-cef5833f6c689
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 +96 -67
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +2 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +28 -4
- 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/client.d.ts +12 -12
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +54 -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 +1 -6
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +118 -247
- package/dist/connection.d.ts +11 -11
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1598 -1248
- 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 +268 -171
- package/dist/durability.d.ts +1 -5
- 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 +15 -6
- 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 -6
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +49 -35
- package/dist/identity.d.ts +0 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +0 -3
- 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 +11 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +178 -101
- package/dist/messages.d.ts +2 -2
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +15 -16
- package/dist/model.d.ts +7 -3
- 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 -205
- 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 +81 -71
- package/dist/react.d.ts +3 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/readiness.d.ts +13 -16
- 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 +104 -30
- package/dist/replica.d.ts +6 -5
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +8 -7
- 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 +8 -15
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +51 -151
- 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 -63
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +9 -52
- 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 +32 -31
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +67 -63
- package/dist/stored.d.ts +42 -18
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +193 -194
- package/dist/tables.d.ts +60 -40
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +78 -62
- 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 +6 -9
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +3 -3
- package/package.json +11 -18
- package/AGENTS.md +0 -320
- 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 -254
- package/dist/chat/messages.d.ts +0 -35
- package/dist/chat/messages.d.ts.map +0 -1
- package/dist/chat/messages.js +0 -210
- 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 -307
- package/dist/chat.d.ts +0 -15
- package/dist/chat.d.ts.map +0 -1
- package/dist/chat.js +0 -8
- package/dist/fulltext.d.ts +0 -27
- package/dist/fulltext.d.ts.map +0 -1
- package/dist/fulltext.js +0 -368
- package/dist/reads.d.ts +0 -11
- package/dist/reads.d.ts.map +0 -1
- package/dist/reads.js +0 -98
- package/dist/words.d.ts +0 -19
- package/dist/words.d.ts.map +0 -1
- package/dist/words.js +0 -150
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)
|
|
@@ -333,7 +359,7 @@ export function createConversationStore(deps) {
|
|
|
333
359
|
function entries() {
|
|
334
360
|
return [...listing.values()].map((entry) => ({
|
|
335
361
|
conversation: entry.conversation,
|
|
336
|
-
agent: { identity: entry.agent, name:
|
|
362
|
+
agent: { identity: entry.agent, name: entry.agentName },
|
|
337
363
|
name: entry.name,
|
|
338
364
|
created: entry.created,
|
|
339
365
|
finished: entry.finished,
|
|
@@ -343,25 +369,103 @@ export function createConversationStore(deps) {
|
|
|
343
369
|
started: lives.get(entry.conversation)?.turn?.started ?? null,
|
|
344
370
|
}));
|
|
345
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
|
+
}
|
|
346
397
|
function emitList() {
|
|
347
|
-
if (deps.closed()
|
|
398
|
+
if (deps.closed())
|
|
348
399
|
return;
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
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
|
+
}
|
|
352
429
|
}
|
|
353
430
|
function agents() {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
.
|
|
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 }))
|
|
357
440
|
.sort((left, right) => left.name === right.name
|
|
358
441
|
? left.identity.localeCompare(right.identity)
|
|
359
442
|
: left.name.localeCompare(right.name));
|
|
360
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
|
+
}
|
|
361
461
|
function emitAgents() {
|
|
362
462
|
if (deps.closed() || agentWatchers.size === 0)
|
|
363
463
|
return;
|
|
364
464
|
const value = agents();
|
|
465
|
+
const shown = JSON.stringify(value);
|
|
466
|
+
if (shown === agentsShown)
|
|
467
|
+
return;
|
|
468
|
+
agentsShown = shown;
|
|
365
469
|
for (const watcher of agentWatchers)
|
|
366
470
|
watcher(value);
|
|
367
471
|
}
|
|
@@ -377,55 +481,11 @@ export function createConversationStore(deps) {
|
|
|
377
481
|
if (stateOf(conversation) !== before || next?.turn?.started !== began)
|
|
378
482
|
emitList();
|
|
379
483
|
}
|
|
380
|
-
async function readAgents() {
|
|
381
|
-
const declaration = deps.agents();
|
|
382
|
-
if (declaration === undefined)
|
|
383
|
-
return;
|
|
384
|
-
const names = new Map();
|
|
385
|
-
const retired = new Set();
|
|
386
|
-
let covered = null;
|
|
387
|
-
for (let after;;) {
|
|
388
|
-
const read = await deps.documents(declaration, after);
|
|
389
|
-
if ('pending' in read)
|
|
390
|
-
return;
|
|
391
|
-
const coverage = JSON.stringify(read.coverage);
|
|
392
|
-
if (covered !== null && coverage !== covered)
|
|
393
|
-
return readAgents();
|
|
394
|
-
covered = coverage;
|
|
395
|
-
for (const document of read.documents) {
|
|
396
|
-
const identity = document.fields?.[declaration.identity];
|
|
397
|
-
const name = document.fields?.[declaration.name];
|
|
398
|
-
if (typeof identity !== 'string' || typeof name !== 'string')
|
|
399
|
-
continue;
|
|
400
|
-
names.set(identity, name);
|
|
401
|
-
const ended = declaration.retired === undefined ? null : document.fields?.[declaration.retired];
|
|
402
|
-
if (ended !== undefined && ended !== null)
|
|
403
|
-
retired.add(identity);
|
|
404
|
-
}
|
|
405
|
-
if (read.next === undefined)
|
|
406
|
-
break;
|
|
407
|
-
after = read.next;
|
|
408
|
-
}
|
|
409
|
-
const named = JSON.stringify([...names]) !== JSON.stringify([...agentNames]);
|
|
410
|
-
if (!named && JSON.stringify([...retired]) === JSON.stringify([...retiredAgents]))
|
|
411
|
-
return;
|
|
412
|
-
agentNames = names;
|
|
413
|
-
retiredAgents = retired;
|
|
414
|
-
if (named)
|
|
415
|
-
emitList();
|
|
416
|
-
emitAgents();
|
|
417
|
-
const ended = [...drafts.keys()].filter(retiredChat);
|
|
418
|
-
if (ended.length > 0)
|
|
419
|
-
await remove(ended);
|
|
420
|
-
}
|
|
421
484
|
function retiredChat(conversation) {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
agentsRead = null;
|
|
427
|
-
});
|
|
428
|
-
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);
|
|
429
489
|
}
|
|
430
490
|
function live(conversation, change) {
|
|
431
491
|
const owed = unsent.get(conversation);
|
|
@@ -448,6 +508,7 @@ export function createConversationStore(deps) {
|
|
|
448
508
|
commands: facts.has('commands') ? QUIET.commands : held.commands,
|
|
449
509
|
options: facts.has('options') ? QUIET.options : held.options,
|
|
450
510
|
starting: facts.has('starting') ? QUIET.starting : held.starting,
|
|
511
|
+
subagents: facts.has('subagents') ? QUIET.subagents : held.subagents,
|
|
451
512
|
link: facts.has('link') ? QUIET.link : held.link,
|
|
452
513
|
deliveryUnknown: facts.has('deliveryUnknown')
|
|
453
514
|
? QUIET.deliveryUnknown
|
|
@@ -501,6 +562,20 @@ export function createConversationStore(deps) {
|
|
|
501
562
|
deps.publish(conversationChangeSet(changed));
|
|
502
563
|
});
|
|
503
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
|
+
}
|
|
504
579
|
function gap(conversation) {
|
|
505
580
|
gaps.set(conversation, (gaps.get(conversation) ?? 0) + 1);
|
|
506
581
|
behind.add(conversation);
|
|
@@ -529,12 +604,13 @@ export function createConversationStore(deps) {
|
|
|
529
604
|
}
|
|
530
605
|
async function readHistories(conversations, ended) {
|
|
531
606
|
const generations = new Map(conversations.map((one) => [one, gaps.get(one) ?? 0]));
|
|
532
|
-
let
|
|
607
|
+
let waiting = conversations.map((conversation) => ({
|
|
533
608
|
conversation,
|
|
534
609
|
after: reads.get(conversation) ?? undefined,
|
|
535
610
|
}));
|
|
536
|
-
while (
|
|
537
|
-
const
|
|
611
|
+
while (waiting.length > 0) {
|
|
612
|
+
const asking = waiting.slice(0, HISTORY_CONVERSATIONS);
|
|
613
|
+
const result = await deps.history({
|
|
538
614
|
conversations: asking.map(({ conversation, after }) => ({
|
|
539
615
|
conversation,
|
|
540
616
|
...(after === undefined ? {} : { after }),
|
|
@@ -557,7 +633,7 @@ export function createConversationStore(deps) {
|
|
|
557
633
|
if (!following.some((next) => next.conversation === conversation))
|
|
558
634
|
ended(conversation);
|
|
559
635
|
}
|
|
560
|
-
|
|
636
|
+
waiting = [...waiting.slice(HISTORY_CONVERSATIONS), ...following];
|
|
561
637
|
}
|
|
562
638
|
return null;
|
|
563
639
|
}
|
|
@@ -637,6 +713,10 @@ export function createConversationStore(deps) {
|
|
|
637
713
|
live(conversation, { starting: event.step });
|
|
638
714
|
return;
|
|
639
715
|
}
|
|
716
|
+
if (event.kind === 'subagents') {
|
|
717
|
+
live(conversation, { subagents: structuredClone(event.subagents) });
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
640
720
|
if (event.kind === 'link') {
|
|
641
721
|
live(conversation, { link: { connected: event.connected } });
|
|
642
722
|
return;
|
|
@@ -648,8 +728,16 @@ export function createConversationStore(deps) {
|
|
|
648
728
|
const arriving = acceptedMessage(event.message);
|
|
649
729
|
if (arriving === null)
|
|
650
730
|
return;
|
|
731
|
+
noted(conversation, arriving);
|
|
651
732
|
if (replicated.has(conversation)) {
|
|
652
|
-
|
|
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
|
+
});
|
|
653
741
|
return;
|
|
654
742
|
}
|
|
655
743
|
if (sealTurns(conversation, new Set([arriving.turn])))
|
|
@@ -678,7 +766,7 @@ export function createConversationStore(deps) {
|
|
|
678
766
|
const from = newChat(agent);
|
|
679
767
|
return deps.durably(async (local) => {
|
|
680
768
|
const held = drafts.get(from);
|
|
681
|
-
const earlier =
|
|
769
|
+
const earlier = held?.moves ?? [];
|
|
682
770
|
if (earlier.includes(operation))
|
|
683
771
|
return;
|
|
684
772
|
const blank = {
|
|
@@ -707,10 +795,8 @@ export function createConversationStore(deps) {
|
|
|
707
795
|
}
|
|
708
796
|
async function submitted(conversation, operation, draft) {
|
|
709
797
|
let submission;
|
|
710
|
-
let earlier = false;
|
|
711
798
|
await withDraft(conversation, (current) => {
|
|
712
799
|
submission = current?.submitted?.find((one) => one.operation === operation);
|
|
713
|
-
earlier = submission !== undefined;
|
|
714
800
|
if (submission !== undefined)
|
|
715
801
|
return undefined;
|
|
716
802
|
const said = draft ?? current;
|
|
@@ -723,31 +809,24 @@ export function createConversationStore(deps) {
|
|
|
723
809
|
submitted: [...(current?.submitted ?? []), submission],
|
|
724
810
|
};
|
|
725
811
|
});
|
|
726
|
-
return
|
|
727
|
-
}
|
|
728
|
-
function forgotten(conversation, submission) {
|
|
729
|
-
return withDraft(conversation, (current) => {
|
|
730
|
-
const held = current?.submitted ?? [];
|
|
731
|
-
if (current === undefined || !held.includes(submission))
|
|
732
|
-
return undefined;
|
|
733
|
-
return withSubmitted(current, held.filter((one) => one !== submission));
|
|
734
|
-
});
|
|
812
|
+
return submission;
|
|
735
813
|
}
|
|
736
814
|
async function dispatched(conversation, submission) {
|
|
737
|
-
const dispatch = {};
|
|
815
|
+
const dispatch = { answered: false };
|
|
738
816
|
sending.set(submission.operation, dispatch);
|
|
739
817
|
try {
|
|
740
|
-
const result = await invoke('
|
|
741
|
-
text: submission.text,
|
|
818
|
+
const result = await invoke('conversations/send', conversation, {
|
|
742
819
|
operation_id: submission.operation,
|
|
820
|
+
text: submission.text,
|
|
743
821
|
});
|
|
822
|
+
dispatch.answered = result.kind !== 'transport-uncertainty';
|
|
744
823
|
if (result.kind === 'revoked-authorization')
|
|
745
824
|
return result;
|
|
746
825
|
if (result.kind !== 'action' && result.retryable) {
|
|
747
826
|
deps.unanswered();
|
|
748
827
|
return result;
|
|
749
828
|
}
|
|
750
|
-
const turn = answered(result, '
|
|
829
|
+
const turn = answered(result, 'message_id');
|
|
751
830
|
await withDraft(conversation, async (current, local) => {
|
|
752
831
|
const held = current?.submitted?.find((one) => one.operation === submission.operation);
|
|
753
832
|
if (current === undefined || held === undefined || held.turn !== null)
|
|
@@ -767,25 +846,34 @@ export function createConversationStore(deps) {
|
|
|
767
846
|
sending.delete(submission.operation);
|
|
768
847
|
}
|
|
769
848
|
}
|
|
770
|
-
function invoke(name, conversation, extra = {}) {
|
|
771
|
-
return deps.call(name, { conversation, ...extra });
|
|
849
|
+
function invoke(name, conversation, extra = { operation_id: changeBatchIdentity() }) {
|
|
850
|
+
return deps.call(name, { conversation_id: conversation, ...extra });
|
|
772
851
|
}
|
|
773
852
|
const surface = {
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
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
|
+
});
|
|
777
863
|
},
|
|
778
864
|
async read(conversation, options = {}) {
|
|
779
|
-
const
|
|
865
|
+
const { text, ...windowed } = options;
|
|
866
|
+
const asked = askedOf(windowed);
|
|
867
|
+
const phrase = phraseOf(text);
|
|
780
868
|
return deps.durably(async (local) => {
|
|
781
|
-
const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
|
|
782
|
-
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;
|
|
783
871
|
return structuredClone(viewOf(conversation, messages, frameOf(asked, messages, more, total)));
|
|
784
872
|
});
|
|
785
873
|
},
|
|
786
874
|
async create(input) {
|
|
787
|
-
const result = await deps.call('
|
|
788
|
-
const conversation = answered(result, '
|
|
875
|
+
const result = await deps.call('conversations/create', input);
|
|
876
|
+
const conversation = answered(result, 'conversation_id');
|
|
789
877
|
if (conversation === null)
|
|
790
878
|
return result;
|
|
791
879
|
if (!listing.has(conversation))
|
|
@@ -796,12 +884,17 @@ export function createConversationStore(deps) {
|
|
|
796
884
|
return result;
|
|
797
885
|
},
|
|
798
886
|
async send(conversation, operation = changeBatchIdentity(), draft) {
|
|
887
|
+
if (deps.full())
|
|
888
|
+
return DURABLE_WRITE;
|
|
799
889
|
if (deps.online()) {
|
|
800
|
-
const
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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);
|
|
805
898
|
}
|
|
806
899
|
if (draft !== undefined) {
|
|
807
900
|
await withDraft(conversation, (current) => current?.submitted?.some((one) => one.operation === operation) === true
|
|
@@ -810,38 +903,20 @@ export function createConversationStore(deps) {
|
|
|
810
903
|
}
|
|
811
904
|
return OFFLINE;
|
|
812
905
|
},
|
|
813
|
-
async attach(room, file) {
|
|
814
|
-
if (!deps.online())
|
|
815
|
-
return OFFLINE;
|
|
816
|
-
return deps.call('conversation.attach', {
|
|
817
|
-
room,
|
|
818
|
-
...(await declaredFile(file)),
|
|
819
|
-
blob: file.blob,
|
|
820
|
-
});
|
|
821
|
-
},
|
|
822
906
|
answer(conversation, answer) {
|
|
823
|
-
return invoke('
|
|
907
|
+
return invoke('conversations/interaction/answer', conversation, {
|
|
908
|
+
operation_id: changeBatchIdentity(),
|
|
909
|
+
...answer,
|
|
910
|
+
});
|
|
824
911
|
},
|
|
825
912
|
interrupt(conversation) {
|
|
826
|
-
return invoke('
|
|
913
|
+
return invoke('conversations/interrupt', conversation);
|
|
827
914
|
},
|
|
828
915
|
kill(conversation) {
|
|
829
|
-
return invoke('
|
|
830
|
-
},
|
|
831
|
-
async cancel(conversation, turn) {
|
|
832
|
-
const result = await invoke('conversation.cancel', conversation, { turn });
|
|
833
|
-
if (result.kind !== 'action')
|
|
834
|
-
return result;
|
|
835
|
-
await withDraft(conversation, (current) => {
|
|
836
|
-
const held = current?.submitted?.find((one) => one.turn === turn);
|
|
837
|
-
if (current === undefined || held === undefined)
|
|
838
|
-
return undefined;
|
|
839
|
-
return returned(current, held, current.submitted.filter((one) => one !== held));
|
|
840
|
-
});
|
|
841
|
-
return result;
|
|
916
|
+
return invoke('conversations/kill', conversation);
|
|
842
917
|
},
|
|
843
918
|
delete(conversation) {
|
|
844
|
-
return invoke('
|
|
919
|
+
return invoke('conversations/delete', conversation);
|
|
845
920
|
},
|
|
846
921
|
};
|
|
847
922
|
const chatDraft = {
|
|
@@ -870,7 +945,15 @@ export function createConversationStore(deps) {
|
|
|
870
945
|
return {
|
|
871
946
|
surface,
|
|
872
947
|
chatDraft,
|
|
873
|
-
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
|
+
}
|
|
874
957
|
stored.clear();
|
|
875
958
|
reads.clear();
|
|
876
959
|
partials.clear();
|
|
@@ -884,6 +967,8 @@ export function createConversationStore(deps) {
|
|
|
884
967
|
drafts.clear();
|
|
885
968
|
for (const record of kept)
|
|
886
969
|
drafts.set(record.conversation, record);
|
|
970
|
+
if (listHeld)
|
|
971
|
+
learned();
|
|
887
972
|
},
|
|
888
973
|
async reconcile() {
|
|
889
974
|
if (!listKnown)
|
|
@@ -895,7 +980,7 @@ export function createConversationStore(deps) {
|
|
|
895
980
|
!creations.has(conversation) &&
|
|
896
981
|
(!conversation.startsWith(NEW_CHAT) || retiredChat(conversation)));
|
|
897
982
|
for (const conversation of named) {
|
|
898
|
-
if (!replicated.has(conversation))
|
|
983
|
+
if (!replicated.has(conversation) && missed(conversation))
|
|
899
984
|
behind.add(conversation);
|
|
900
985
|
}
|
|
901
986
|
replicated = named;
|
|
@@ -904,6 +989,11 @@ export function createConversationStore(deps) {
|
|
|
904
989
|
await remove(leaving);
|
|
905
990
|
},
|
|
906
991
|
async catchUp(progress) {
|
|
992
|
+
if (deps.full()) {
|
|
993
|
+
if (behind.size > 0)
|
|
994
|
+
progress.complete = false;
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
907
997
|
const owed = (conversation) => behind.has(conversation) && replicated.has(conversation);
|
|
908
998
|
const read = async (conversations) => {
|
|
909
999
|
if (conversations.length === 0 || deps.closed())
|
|
@@ -928,10 +1018,6 @@ export function createConversationStore(deps) {
|
|
|
928
1018
|
continue;
|
|
929
1019
|
if (deps.closed())
|
|
930
1020
|
return;
|
|
931
|
-
if (deps.expired(submission.operation)) {
|
|
932
|
-
await forgotten(conversation, submission);
|
|
933
|
-
continue;
|
|
934
|
-
}
|
|
935
1021
|
const result = await dispatched(conversation, submission);
|
|
936
1022
|
if (result.kind === 'revoked-authorization')
|
|
937
1023
|
return;
|
|
@@ -952,12 +1038,11 @@ export function createConversationStore(deps) {
|
|
|
952
1038
|
known() {
|
|
953
1039
|
return listKnown;
|
|
954
1040
|
},
|
|
955
|
-
reconnected() {
|
|
956
|
-
for (const conversation of replicated)
|
|
957
|
-
gap(conversation);
|
|
958
|
-
},
|
|
959
1041
|
reopened() {
|
|
960
|
-
|
|
1042
|
+
relisting = null;
|
|
1043
|
+
for (const [operation, dispatch] of sending)
|
|
1044
|
+
if (!dispatch.answered)
|
|
1045
|
+
sending.delete(operation);
|
|
961
1046
|
},
|
|
962
1047
|
lost() {
|
|
963
1048
|
catching.clear();
|
|
@@ -976,15 +1061,15 @@ export function createConversationStore(deps) {
|
|
|
976
1061
|
views.set(key, view);
|
|
977
1062
|
const watcher = { notify: deliver, ready: false };
|
|
978
1063
|
view.watchers.add(watcher);
|
|
979
|
-
|
|
980
|
-
|
|
1064
|
+
const reading = new AbortController();
|
|
1065
|
+
void untilAnswered(() => deps.durably(async (local) => {
|
|
981
1066
|
if (view.window !== null)
|
|
982
1067
|
return;
|
|
983
1068
|
const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
|
|
984
1069
|
view.window = messages;
|
|
985
1070
|
view.more = more;
|
|
986
1071
|
view.total = asked.total ? await local.messageCount(conversation) : null;
|
|
987
|
-
})
|
|
1072
|
+
}), reading.signal)
|
|
988
1073
|
.then(() => {
|
|
989
1074
|
if (deps.closed() || !view.watchers.has(watcher))
|
|
990
1075
|
return;
|
|
@@ -994,6 +1079,7 @@ export function createConversationStore(deps) {
|
|
|
994
1079
|
})
|
|
995
1080
|
.catch(() => { });
|
|
996
1081
|
return () => {
|
|
1082
|
+
reading.abort();
|
|
997
1083
|
if (!view.watchers.delete(watcher))
|
|
998
1084
|
return;
|
|
999
1085
|
if (view.watchers.size === 0)
|
|
@@ -1001,77 +1087,88 @@ export function createConversationStore(deps) {
|
|
|
1001
1087
|
};
|
|
1002
1088
|
},
|
|
1003
1089
|
watchList(deliver) {
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
if (!deps.closed() && listWatchers.has(deliver))
|
|
1007
|
-
deliver(entries());
|
|
1008
|
-
});
|
|
1090
|
+
unlisted.add(deliver);
|
|
1091
|
+
learned();
|
|
1009
1092
|
return () => {
|
|
1093
|
+
unlisted.delete(deliver);
|
|
1010
1094
|
listWatchers.delete(deliver);
|
|
1011
1095
|
};
|
|
1012
1096
|
},
|
|
1013
1097
|
watchAgents(deliver) {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
deliver(agents());
|
|
1018
|
-
});
|
|
1098
|
+
unnamed.add(deliver);
|
|
1099
|
+
learned();
|
|
1100
|
+
readAgents();
|
|
1019
1101
|
return () => {
|
|
1102
|
+
unnamed.delete(deliver);
|
|
1020
1103
|
agentWatchers.delete(deliver);
|
|
1021
1104
|
};
|
|
1022
1105
|
},
|
|
1106
|
+
learned,
|
|
1023
1107
|
changed(set) {
|
|
1024
1108
|
for (const conversation of set.conversations)
|
|
1025
1109
|
emit(conversation);
|
|
1026
|
-
const declaration = deps.agents();
|
|
1027
|
-
if (declaration !== undefined &&
|
|
1028
|
-
set.documents.some((change) => change.locator === declaration.locator)) {
|
|
1029
|
-
agentsRead = readAgents().catch(() => {
|
|
1030
|
-
agentsRead = null;
|
|
1031
|
-
});
|
|
1032
|
-
}
|
|
1033
1110
|
},
|
|
1034
1111
|
receive(event) {
|
|
1035
1112
|
if (deps.closed())
|
|
1036
1113
|
return false;
|
|
1037
1114
|
if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
|
|
1038
1115
|
if (event.kind === 'list') {
|
|
1039
|
-
|
|
1116
|
+
if (event.whole)
|
|
1117
|
+
relisting ??= new Map();
|
|
1040
1118
|
for (const entry of event.entries) {
|
|
1041
|
-
|
|
1042
|
-
|
|
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;
|
|
1043
1131
|
}
|
|
1132
|
+
listCursor = event.cursor;
|
|
1133
|
+
deps.stream()?.hold(event.cursor);
|
|
1044
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
|
+
}
|
|
1045
1143
|
openingEnded();
|
|
1046
1144
|
}
|
|
1047
1145
|
else if (event.kind === 'listed') {
|
|
1048
|
-
|
|
1049
|
-
|
|
1146
|
+
listed(event.entry);
|
|
1147
|
+
relisting?.set(event.entry.conversation, { ...event.entry });
|
|
1050
1148
|
}
|
|
1051
1149
|
else {
|
|
1052
1150
|
listing.delete(event.conversation);
|
|
1151
|
+
relisting?.delete(event.conversation);
|
|
1053
1152
|
}
|
|
1153
|
+
keepList();
|
|
1054
1154
|
emitList();
|
|
1055
|
-
return (event.kind !== 'list' &&
|
|
1155
|
+
return ((event.kind !== 'list' &&
|
|
1056
1156
|
listKnown &&
|
|
1057
1157
|
(listing.size !== replicated.size ||
|
|
1058
|
-
[...listing.keys()].some((conversation) => !replicated.has(conversation))))
|
|
1158
|
+
[...listing.keys()].some((conversation) => !replicated.has(conversation)))) ||
|
|
1159
|
+
(listKnown && [...drafts.keys()].some(retiredChat)));
|
|
1059
1160
|
}
|
|
1060
1161
|
heard(event);
|
|
1061
1162
|
return false;
|
|
1062
1163
|
},
|
|
1063
|
-
searchable() {
|
|
1064
|
-
return [...(listKnown ? listing.keys() : stored)].sort();
|
|
1065
|
-
},
|
|
1066
|
-
acquired(conversation) {
|
|
1067
|
-
return reads.has(conversation) && !partials.has(conversation);
|
|
1068
|
-
},
|
|
1069
1164
|
close() {
|
|
1070
1165
|
views.clear();
|
|
1071
1166
|
lives.clear();
|
|
1072
1167
|
unsent.clear();
|
|
1073
1168
|
listWatchers.clear();
|
|
1169
|
+
unlisted.clear();
|
|
1074
1170
|
agentWatchers.clear();
|
|
1171
|
+
unnamed.clear();
|
|
1075
1172
|
},
|
|
1076
1173
|
};
|
|
1077
1174
|
}
|