@agentshouse/mdruntime 0.1.0-ce131cb435f8b → 0.1.0-ce41fec66d91b
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 +18 -15
- package/dist/adapter.d.ts +110 -72
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +5 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +38 -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 +25 -10
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +180 -103
- package/dist/chain.d.ts +11 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +64 -0
- package/dist/change-set.d.ts +9 -16
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +11 -89
- package/dist/change.d.ts +31 -1
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +10 -1
- package/dist/client.d.ts +11 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +80 -7
- package/dist/collection.d.ts +10 -22
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +39 -356
- package/dist/compile.d.ts +16 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +786 -0
- package/dist/connection.d.ts +17 -11
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +2779 -1329
- package/dist/conversation.d.ts +19 -11
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +298 -166
- package/dist/digest.d.ts +7 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +113 -0
- package/dist/durability.d.ts +2 -5
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +5 -0
- package/dist/entry.d.ts +4 -1
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +18 -24
- package/dist/file.d.ts +2 -19
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +7 -122
- package/dist/fulltext.d.ts +27 -0
- package/dist/fulltext.d.ts.map +1 -0
- package/dist/fulltext.js +370 -0
- package/dist/host.d.ts +3 -5
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +48 -21
- 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 +14 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/live.d.ts +22 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +123 -0
- 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 +10 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +195 -102
- package/dist/messages.d.ts +28 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +90 -0
- package/dist/model.d.ts +6 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +7 -10
- package/dist/name.d.ts +4 -0
- package/dist/name.d.ts.map +1 -0
- package/dist/name.js +122 -0
- package/dist/observation.d.ts +13 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +84 -0
- package/dist/opened.d.ts +22 -0
- package/dist/opened.d.ts.map +1 -0
- package/dist/opened.js +107 -0
- package/dist/outcome.d.ts +40 -8
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +38 -2
- package/dist/overlay.d.ts +2 -6
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +87 -176
- 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 +11 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +13 -1
- package/dist/reach.d.ts +13 -4
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +200 -78
- package/dist/readiness.d.ts +14 -15
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +2 -8
- package/dist/recovery.d.ts +3 -2
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +34 -7
- package/dist/refresh.d.ts +18 -15
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +136 -58
- package/dist/replica.d.ts +55 -38
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +278 -198
- package/dist/room-draft.d.ts +21 -3
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +102 -28
- package/dist/rows.d.ts +38 -31
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +173 -101
- package/dist/save.d.ts +52 -15
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +504 -182
- package/dist/search.d.ts +11 -43
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +0 -213
- package/dist/shared.d.ts +4 -3
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +62 -35
- 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 +81 -101
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +300 -693
- package/dist/stored.d.ts +130 -0
- package/dist/stored.d.ts.map +1 -0
- package/dist/stored.js +560 -0
- package/dist/tables.d.ts +325 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +578 -0
- package/dist/transfer.d.ts +0 -5
- package/dist/transfer.d.ts.map +1 -1
- package/dist/turn.d.ts +2 -2
- package/dist/turn.d.ts.map +1 -1
- package/dist/turn.js +34 -23
- package/dist/validation.d.ts +29 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +101 -0
- package/dist/windows.d.ts +2 -6
- package/dist/windows.d.ts.map +1 -1
- package/dist/windows.js +30 -34
- package/dist/wire.d.ts +17 -5
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +5 -2
- package/dist/words.d.ts +19 -0
- package/dist/words.d.ts.map +1 -0
- package/dist/words.js +156 -0
- package/package.json +18 -19
- package/AGENTS.md +0 -299
- 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/context.js +0 -10
- 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/input.d.ts +0 -9
- package/dist/chat/input.d.ts.map +0 -1
- package/dist/chat/input.js +0 -99
- 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 -27
- package/dist/chat/list.d.ts.map +0 -1
- package/dist/chat/list.js +0 -99
- package/dist/chat/markdown.d.ts +0 -20
- package/dist/chat/markdown.d.ts.map +0 -1
- package/dist/chat/markdown.js +0 -188
- package/dist/chat/message.d.ts +0 -6
- package/dist/chat/message.d.ts.map +0 -1
- package/dist/chat/message.js +0 -192
- package/dist/chat/messages.d.ts +0 -22
- package/dist/chat/messages.d.ts.map +0 -1
- package/dist/chat/messages.js +0 -155
- package/dist/chat/name.d.ts +0 -6
- package/dist/chat/name.d.ts.map +0 -1
- package/dist/chat/name.js +0 -37
- package/dist/chat/opened.d.ts +0 -11
- package/dist/chat/opened.d.ts.map +0 -1
- package/dist/chat/opened.js +0 -17
- package/dist/chat/overlay.d.ts +0 -31
- package/dist/chat/overlay.d.ts.map +0 -1
- package/dist/chat/overlay.js +0 -97
- package/dist/chat/parts.d.ts +0 -57
- package/dist/chat/parts.d.ts.map +0 -1
- package/dist/chat/parts.js +0 -119
- 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 -63
- package/dist/chat/provider.d.ts.map +0 -1
- package/dist/chat/provider.js +0 -628
- 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 -34
- package/dist/chat/ready.d.ts.map +0 -1
- package/dist/chat/ready.js +0 -91
- package/dist/chat/style.d.ts +0 -4
- package/dist/chat/style.d.ts.map +0 -1
- package/dist/chat/style.js +0 -302
- package/dist/chat.d.ts +0 -14
- package/dist/chat.d.ts.map +0 -1
- package/dist/chat.js +0 -8
- package/dist/read-side.d.ts +0 -27
- package/dist/read-side.d.ts.map +0 -1
- package/dist/read-side.js +0 -824
- 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,8 +1,9 @@
|
|
|
1
1
|
import { conversationChangeSet } from './change-set.js';
|
|
2
2
|
import { runtimeError } from './failure.js';
|
|
3
|
-
import {
|
|
3
|
+
import { refusedForSpace } from './durability.js';
|
|
4
4
|
import { changeBatchIdentity, chatDraftRevision } from './identity.js';
|
|
5
5
|
import { OFFLINE } from './outcome.js';
|
|
6
|
+
import { untilAnswered } from './recovery.js';
|
|
6
7
|
import { capped, cursorOf, decodedCursor, FROM_START, messageOrder, precedes } from './windows.js';
|
|
7
8
|
const QUIET = {
|
|
8
9
|
turn: null,
|
|
@@ -10,8 +11,21 @@ const QUIET = {
|
|
|
10
11
|
process: null,
|
|
11
12
|
commands: [],
|
|
12
13
|
options: [],
|
|
14
|
+
starting: null,
|
|
15
|
+
subagents: [],
|
|
16
|
+
link: null,
|
|
17
|
+
deliveryUnknown: [],
|
|
13
18
|
};
|
|
14
|
-
const FACTS = [
|
|
19
|
+
const FACTS = [
|
|
20
|
+
'questions',
|
|
21
|
+
'process',
|
|
22
|
+
'commands',
|
|
23
|
+
'options',
|
|
24
|
+
'starting',
|
|
25
|
+
'subagents',
|
|
26
|
+
'link',
|
|
27
|
+
'deliveryUnknown',
|
|
28
|
+
];
|
|
15
29
|
export function unheldView(conversation) {
|
|
16
30
|
return {
|
|
17
31
|
conversation,
|
|
@@ -21,19 +35,26 @@ export function unheldView(conversation) {
|
|
|
21
35
|
process: null,
|
|
22
36
|
commands: [],
|
|
23
37
|
options: [],
|
|
38
|
+
starting: null,
|
|
39
|
+
subagents: [],
|
|
40
|
+
link: null,
|
|
41
|
+
deliveryUnknown: [],
|
|
24
42
|
chatDraft: null,
|
|
25
43
|
};
|
|
26
44
|
}
|
|
27
45
|
export const SESSION_STARTED = 'Session started';
|
|
28
46
|
const NEW_CHAT = 'new:';
|
|
47
|
+
export const HISTORY_CONVERSATIONS = 64;
|
|
29
48
|
export function newChat(agent) {
|
|
30
49
|
return `${NEW_CHAT}${agent}`;
|
|
31
50
|
}
|
|
32
51
|
function creationOf(input) {
|
|
33
52
|
if (typeof input !== 'object' || input === null)
|
|
34
53
|
return null;
|
|
35
|
-
const { agent_id: agent, operation_id: operation } = input;
|
|
36
|
-
return typeof agent === 'string' && typeof operation === 'string'
|
|
54
|
+
const { agent_id: agent, operation_id: operation, replaces, } = input;
|
|
55
|
+
return typeof agent === 'string' && typeof operation === 'string' && replaces === undefined
|
|
56
|
+
? { agent, operation }
|
|
57
|
+
: null;
|
|
37
58
|
}
|
|
38
59
|
function startedTurn(turn, operation) {
|
|
39
60
|
if (operation.op === 'begin')
|
|
@@ -193,8 +214,14 @@ function askedOf(options) {
|
|
|
193
214
|
return { limit: capped(limit), after, before: beforeOf(after), total: total === true };
|
|
194
215
|
}
|
|
195
216
|
const EXPIRED = { kind: 'rejected', code: 'expired', fields: {}, retryable: false };
|
|
217
|
+
const DURABLE_WRITE = {
|
|
218
|
+
kind: 'rejected',
|
|
219
|
+
code: 'durable-write',
|
|
220
|
+
fields: {},
|
|
221
|
+
retryable: true,
|
|
222
|
+
};
|
|
196
223
|
function unwritten(draft) {
|
|
197
|
-
return draft.text === ''
|
|
224
|
+
return draft.text === '';
|
|
198
225
|
}
|
|
199
226
|
function pending(draft) {
|
|
200
227
|
return {
|
|
@@ -210,10 +237,7 @@ function withSubmitted(draft, submitted) {
|
|
|
210
237
|
return submitted.length === 0 ? unsent : { ...unsent, submitted };
|
|
211
238
|
}
|
|
212
239
|
function prepended(draft, said) {
|
|
213
|
-
return {
|
|
214
|
-
text: [said.text, draft.text].filter((one) => one !== '').join('\n'),
|
|
215
|
-
files: [...said.files, ...draft.files],
|
|
216
|
-
};
|
|
240
|
+
return { text: [said.text, draft.text].filter((one) => one !== '').join('\n') };
|
|
217
241
|
}
|
|
218
242
|
function returned(draft, submission, others) {
|
|
219
243
|
return withSubmitted({
|
|
@@ -235,13 +259,19 @@ export function createConversationStore(deps) {
|
|
|
235
259
|
const unsent = new Map();
|
|
236
260
|
const views = new Map();
|
|
237
261
|
const listing = new Map();
|
|
262
|
+
let relisting = null;
|
|
263
|
+
let listCursor = null;
|
|
238
264
|
const creations = new Set();
|
|
239
265
|
const listWatchers = new Set();
|
|
266
|
+
const unlisted = new Set();
|
|
240
267
|
let listKnown = false;
|
|
268
|
+
let listHeld = false;
|
|
269
|
+
let listKept = false;
|
|
241
270
|
const agentWatchers = new Set();
|
|
242
|
-
|
|
243
|
-
let
|
|
244
|
-
let
|
|
271
|
+
const unnamed = new Set();
|
|
272
|
+
let agentsShown = null;
|
|
273
|
+
let listedAgents = null;
|
|
274
|
+
let agentsReading = false;
|
|
245
275
|
let replicated = new Set();
|
|
246
276
|
let handedReplicated;
|
|
247
277
|
function liveOf(conversation) {
|
|
@@ -264,9 +294,13 @@ export function createConversationStore(deps) {
|
|
|
264
294
|
process: facts.process === null ? null : { ...facts.process },
|
|
265
295
|
commands: structuredClone(facts.commands),
|
|
266
296
|
options: structuredClone(facts.options),
|
|
297
|
+
starting: facts.starting,
|
|
298
|
+
subagents: structuredClone(facts.subagents),
|
|
299
|
+
link: facts.link === null ? null : { ...facts.link },
|
|
300
|
+
deliveryUnknown: [...facts.deliveryUnknown],
|
|
267
301
|
chatDraft: draft === undefined || unwritten(draft)
|
|
268
302
|
? null
|
|
269
|
-
: { text: draft.text,
|
|
303
|
+
: { text: draft.text, revision: draft.revision },
|
|
270
304
|
};
|
|
271
305
|
}
|
|
272
306
|
function emit(conversation) {
|
|
@@ -308,9 +342,6 @@ export function createConversationStore(deps) {
|
|
|
308
342
|
}
|
|
309
343
|
}
|
|
310
344
|
}
|
|
311
|
-
function changesOf(conversation, arriving) {
|
|
312
|
-
return arriving.map(({ identity, text }) => ({ conversation, identity, text }));
|
|
313
|
-
}
|
|
314
345
|
function stateOf(conversation) {
|
|
315
346
|
const facts = liveOf(conversation);
|
|
316
347
|
if (facts.questions.length > 0)
|
|
@@ -320,34 +351,110 @@ export function createConversationStore(deps) {
|
|
|
320
351
|
function entries() {
|
|
321
352
|
return [...listing.values()].map((entry) => ({
|
|
322
353
|
conversation: entry.conversation,
|
|
323
|
-
agent: { identity: entry.agent, name:
|
|
354
|
+
agent: { identity: entry.agent, name: entry.agentName },
|
|
324
355
|
name: entry.name,
|
|
325
356
|
created: entry.created,
|
|
326
357
|
finished: entry.finished,
|
|
327
358
|
outcome: entry.outcome,
|
|
359
|
+
waiting: entry.waiting,
|
|
328
360
|
state: stateOf(entry.conversation),
|
|
329
361
|
started: lives.get(entry.conversation)?.turn?.started ?? null,
|
|
330
362
|
}));
|
|
331
363
|
}
|
|
364
|
+
function keepList() {
|
|
365
|
+
if (!listKnown || listKept)
|
|
366
|
+
return;
|
|
367
|
+
listKept = true;
|
|
368
|
+
queueMicrotask(() => {
|
|
369
|
+
listKept = false;
|
|
370
|
+
if (deps.closed())
|
|
371
|
+
return;
|
|
372
|
+
const entries = [...listing.values()];
|
|
373
|
+
const cursor = listCursor;
|
|
374
|
+
void deps
|
|
375
|
+
.durably(async (local) => {
|
|
376
|
+
await local.fact('conversationList', entries);
|
|
377
|
+
await local.fact('conversationCursor', cursor);
|
|
378
|
+
})
|
|
379
|
+
.catch(() => { });
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
function listed(entry) {
|
|
383
|
+
listing.set(entry.conversation, { ...entry });
|
|
384
|
+
creations.delete(entry.conversation);
|
|
385
|
+
}
|
|
332
386
|
function emitList() {
|
|
333
|
-
if (deps.closed()
|
|
387
|
+
if (deps.closed())
|
|
334
388
|
return;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
watcher
|
|
389
|
+
if (listWatchers.size > 0) {
|
|
390
|
+
const value = entries();
|
|
391
|
+
for (const watcher of listWatchers)
|
|
392
|
+
watcher(value);
|
|
393
|
+
}
|
|
394
|
+
emitAgents();
|
|
395
|
+
learned();
|
|
396
|
+
}
|
|
397
|
+
function learned() {
|
|
398
|
+
if (deps.closed())
|
|
399
|
+
return;
|
|
400
|
+
if (!listKnown && !listHeld && deps.stream() !== undefined && deps.online())
|
|
401
|
+
return;
|
|
402
|
+
if (unlisted.size > 0) {
|
|
403
|
+
const value = entries();
|
|
404
|
+
for (const watcher of [...unlisted]) {
|
|
405
|
+
unlisted.delete(watcher);
|
|
406
|
+
listWatchers.add(watcher);
|
|
407
|
+
watcher(value);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (unnamed.size > 0) {
|
|
411
|
+
const value = agents();
|
|
412
|
+
for (const watcher of [...unnamed]) {
|
|
413
|
+
unnamed.delete(watcher);
|
|
414
|
+
agentWatchers.add(watcher);
|
|
415
|
+
watcher(value);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
338
418
|
}
|
|
339
419
|
function agents() {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
.
|
|
420
|
+
const named = new Map();
|
|
421
|
+
for (const agent of listedAgents ?? [])
|
|
422
|
+
named.set(agent.agent, agent);
|
|
423
|
+
for (const entry of listing.values()) {
|
|
424
|
+
named.set(entry.agent, { name: entry.agentName, retired: entry.agentRetired });
|
|
425
|
+
}
|
|
426
|
+
return [...named]
|
|
427
|
+
.filter(([, agent]) => !agent.retired)
|
|
428
|
+
.map(([identity, agent]) => ({ identity, name: agent.name }))
|
|
343
429
|
.sort((left, right) => left.name === right.name
|
|
344
430
|
? left.identity.localeCompare(right.identity)
|
|
345
431
|
: left.name.localeCompare(right.name));
|
|
346
432
|
}
|
|
433
|
+
function readAgents() {
|
|
434
|
+
const stream = deps.stream();
|
|
435
|
+
if (stream?.agents === undefined || !deps.online() || agentsReading)
|
|
436
|
+
return;
|
|
437
|
+
agentsReading = true;
|
|
438
|
+
void stream
|
|
439
|
+
.agents()
|
|
440
|
+
.then((read) => {
|
|
441
|
+
if (read === null)
|
|
442
|
+
return;
|
|
443
|
+
listedAgents = read;
|
|
444
|
+
emitAgents();
|
|
445
|
+
}, () => { })
|
|
446
|
+
.finally(() => {
|
|
447
|
+
agentsReading = false;
|
|
448
|
+
});
|
|
449
|
+
}
|
|
347
450
|
function emitAgents() {
|
|
348
451
|
if (deps.closed() || agentWatchers.size === 0)
|
|
349
452
|
return;
|
|
350
453
|
const value = agents();
|
|
454
|
+
const shown = JSON.stringify(value);
|
|
455
|
+
if (shown === agentsShown)
|
|
456
|
+
return;
|
|
457
|
+
agentsShown = shown;
|
|
351
458
|
for (const watcher of agentWatchers)
|
|
352
459
|
watcher(value);
|
|
353
460
|
}
|
|
@@ -363,48 +470,11 @@ export function createConversationStore(deps) {
|
|
|
363
470
|
if (stateOf(conversation) !== before || next?.turn?.started !== began)
|
|
364
471
|
emitList();
|
|
365
472
|
}
|
|
366
|
-
async function readAgents() {
|
|
367
|
-
const declaration = deps.agents();
|
|
368
|
-
if (declaration === undefined)
|
|
369
|
-
return;
|
|
370
|
-
const held = await deps.documents(declaration);
|
|
371
|
-
if ('pending' in held)
|
|
372
|
-
return;
|
|
373
|
-
const { documents } = held;
|
|
374
|
-
const names = new Map();
|
|
375
|
-
const retired = new Set();
|
|
376
|
-
for (const document of documents) {
|
|
377
|
-
if (document.type !== declaration.type)
|
|
378
|
-
continue;
|
|
379
|
-
const identity = document.fields?.[declaration.identity];
|
|
380
|
-
const name = document.fields?.[declaration.name];
|
|
381
|
-
if (typeof identity !== 'string' || typeof name !== 'string')
|
|
382
|
-
continue;
|
|
383
|
-
names.set(identity, name);
|
|
384
|
-
const ended = declaration.retired === undefined ? null : document.fields?.[declaration.retired];
|
|
385
|
-
if (ended !== undefined && ended !== null)
|
|
386
|
-
retired.add(identity);
|
|
387
|
-
}
|
|
388
|
-
const named = JSON.stringify([...names]) !== JSON.stringify([...agentNames]);
|
|
389
|
-
if (!named && JSON.stringify([...retired]) === JSON.stringify([...retiredAgents]))
|
|
390
|
-
return;
|
|
391
|
-
agentNames = names;
|
|
392
|
-
retiredAgents = retired;
|
|
393
|
-
if (named)
|
|
394
|
-
emitList();
|
|
395
|
-
emitAgents();
|
|
396
|
-
const ended = [...drafts.keys()].filter(retiredChat);
|
|
397
|
-
if (ended.length > 0)
|
|
398
|
-
await remove(ended);
|
|
399
|
-
}
|
|
400
473
|
function retiredChat(conversation) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
agentsRead = null;
|
|
406
|
-
});
|
|
407
|
-
return agentsRead;
|
|
474
|
+
if (!conversation.startsWith(NEW_CHAT))
|
|
475
|
+
return false;
|
|
476
|
+
const agent = conversation.slice(NEW_CHAT.length);
|
|
477
|
+
return [...listing.values()].some((entry) => entry.agent === agent && entry.agentRetired);
|
|
408
478
|
}
|
|
409
479
|
function live(conversation, change) {
|
|
410
480
|
const owed = unsent.get(conversation);
|
|
@@ -426,6 +496,12 @@ export function createConversationStore(deps) {
|
|
|
426
496
|
process: facts.has('process') ? QUIET.process : held.process,
|
|
427
497
|
commands: facts.has('commands') ? QUIET.commands : held.commands,
|
|
428
498
|
options: facts.has('options') ? QUIET.options : held.options,
|
|
499
|
+
starting: facts.has('starting') ? QUIET.starting : held.starting,
|
|
500
|
+
subagents: facts.has('subagents') ? QUIET.subagents : held.subagents,
|
|
501
|
+
link: facts.has('link') ? QUIET.link : held.link,
|
|
502
|
+
deliveryUnknown: facts.has('deliveryUnknown')
|
|
503
|
+
? QUIET.deliveryUnknown
|
|
504
|
+
: held.deliveryUnknown,
|
|
429
505
|
});
|
|
430
506
|
emit(conversation);
|
|
431
507
|
}
|
|
@@ -456,12 +532,6 @@ export function createConversationStore(deps) {
|
|
|
456
532
|
}
|
|
457
533
|
async function remove(leaving) {
|
|
458
534
|
await deps.durably(async (local) => {
|
|
459
|
-
const removed = [];
|
|
460
|
-
for (const conversation of leaving) {
|
|
461
|
-
for (const identity of await local.messageIdentities(conversation)) {
|
|
462
|
-
removed.push({ conversation, identity, text: null });
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
535
|
await local.dropConversations(leaving);
|
|
466
536
|
const changed = [];
|
|
467
537
|
for (const conversation of leaving) {
|
|
@@ -478,9 +548,23 @@ export function createConversationStore(deps) {
|
|
|
478
548
|
await slide(local, conversation, null);
|
|
479
549
|
}
|
|
480
550
|
if (changed.length > 0)
|
|
481
|
-
deps.publish(conversationChangeSet(
|
|
551
|
+
deps.publish(conversationChangeSet(changed));
|
|
482
552
|
});
|
|
483
553
|
}
|
|
554
|
+
function missed(conversation) {
|
|
555
|
+
const read = reads.get(conversation);
|
|
556
|
+
const newest = listing.get(conversation)?.newest;
|
|
557
|
+
return (read === undefined ||
|
|
558
|
+
newest === undefined ||
|
|
559
|
+
partials.has(conversation) ||
|
|
560
|
+
(newest !== null && (read === null || newest > read)));
|
|
561
|
+
}
|
|
562
|
+
function noted(conversation, message) {
|
|
563
|
+
const entry = listing.get(conversation);
|
|
564
|
+
if (entry === undefined || (entry.newest !== null && entry.newest >= message.position))
|
|
565
|
+
return;
|
|
566
|
+
listing.set(conversation, { ...entry, newest: message.position });
|
|
567
|
+
}
|
|
484
568
|
function gap(conversation) {
|
|
485
569
|
gaps.set(conversation, (gaps.get(conversation) ?? 0) + 1);
|
|
486
570
|
behind.add(conversation);
|
|
@@ -504,17 +588,18 @@ export function createConversationStore(deps) {
|
|
|
504
588
|
reads.set(conversation, message.position);
|
|
505
589
|
sealTurns(conversation, new Set([message.turn]));
|
|
506
590
|
await slide(local, conversation, [message]);
|
|
507
|
-
deps.publish(conversationChangeSet(
|
|
591
|
+
deps.publish(conversationChangeSet([conversation]));
|
|
508
592
|
});
|
|
509
593
|
}
|
|
510
594
|
async function readHistories(conversations, ended) {
|
|
511
595
|
const generations = new Map(conversations.map((one) => [one, gaps.get(one) ?? 0]));
|
|
512
|
-
let
|
|
596
|
+
let waiting = conversations.map((conversation) => ({
|
|
513
597
|
conversation,
|
|
514
598
|
after: reads.get(conversation) ?? undefined,
|
|
515
599
|
}));
|
|
516
|
-
while (
|
|
517
|
-
const
|
|
600
|
+
while (waiting.length > 0) {
|
|
601
|
+
const asking = waiting.slice(0, HISTORY_CONVERSATIONS);
|
|
602
|
+
const result = await deps.history({
|
|
518
603
|
conversations: asking.map(({ conversation, after }) => ({
|
|
519
604
|
conversation,
|
|
520
605
|
...(after === undefined ? {} : { after }),
|
|
@@ -537,7 +622,7 @@ export function createConversationStore(deps) {
|
|
|
537
622
|
if (!following.some((next) => next.conversation === conversation))
|
|
538
623
|
ended(conversation);
|
|
539
624
|
}
|
|
540
|
-
|
|
625
|
+
waiting = [...waiting.slice(HISTORY_CONVERSATIONS), ...following];
|
|
541
626
|
}
|
|
542
627
|
return null;
|
|
543
628
|
}
|
|
@@ -580,7 +665,7 @@ export function createConversationStore(deps) {
|
|
|
580
665
|
behind.delete(conversation);
|
|
581
666
|
await slide(local, conversation, arriving);
|
|
582
667
|
if (arriving.length > 0 || sealing || whole) {
|
|
583
|
-
deps.publish(conversationChangeSet(
|
|
668
|
+
deps.publish(conversationChangeSet([conversation]));
|
|
584
669
|
}
|
|
585
670
|
});
|
|
586
671
|
}
|
|
@@ -613,11 +698,35 @@ export function createConversationStore(deps) {
|
|
|
613
698
|
live(conversation, { options: structuredClone(event.options) });
|
|
614
699
|
return;
|
|
615
700
|
}
|
|
701
|
+
if (event.kind === 'starting') {
|
|
702
|
+
live(conversation, { starting: event.step });
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
if (event.kind === 'subagents') {
|
|
706
|
+
live(conversation, { subagents: structuredClone(event.subagents) });
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
if (event.kind === 'link') {
|
|
710
|
+
live(conversation, { link: { connected: event.connected } });
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
if (event.kind === 'deliveries') {
|
|
714
|
+
live(conversation, { deliveryUnknown: [...event.unknown] });
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
616
717
|
const arriving = acceptedMessage(event.message);
|
|
617
718
|
if (arriving === null)
|
|
618
719
|
return;
|
|
720
|
+
noted(conversation, arriving);
|
|
619
721
|
if (replicated.has(conversation)) {
|
|
620
|
-
|
|
722
|
+
if (deps.full()) {
|
|
723
|
+
gap(conversation);
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
void keep(conversation, arriving).catch((error) => {
|
|
727
|
+
if (refusedForSpace(error))
|
|
728
|
+
gap(conversation);
|
|
729
|
+
});
|
|
621
730
|
return;
|
|
622
731
|
}
|
|
623
732
|
if (sealTurns(conversation, new Set([arriving.turn])))
|
|
@@ -652,7 +761,6 @@ export function createConversationStore(deps) {
|
|
|
652
761
|
const blank = {
|
|
653
762
|
conversation: from,
|
|
654
763
|
text: '',
|
|
655
|
-
files: [],
|
|
656
764
|
revision: chatDraftRevision(),
|
|
657
765
|
};
|
|
658
766
|
const { moves: _answered, ...unsent } = held ?? blank;
|
|
@@ -662,7 +770,7 @@ export function createConversationStore(deps) {
|
|
|
662
770
|
drafts.set(from, left);
|
|
663
771
|
for (const one of taken)
|
|
664
772
|
drafts.set(to, one);
|
|
665
|
-
deps.publish(conversationChangeSet([
|
|
773
|
+
deps.publish(conversationChangeSet([from, to]));
|
|
666
774
|
});
|
|
667
775
|
}
|
|
668
776
|
function withDraft(conversation, next) {
|
|
@@ -671,7 +779,7 @@ export function createConversationStore(deps) {
|
|
|
671
779
|
if (following === undefined)
|
|
672
780
|
return;
|
|
673
781
|
await kept(local, conversation, following);
|
|
674
|
-
deps.publish(conversationChangeSet([
|
|
782
|
+
deps.publish(conversationChangeSet([conversation]));
|
|
675
783
|
});
|
|
676
784
|
}
|
|
677
785
|
async function submitted(conversation, operation, draft) {
|
|
@@ -683,17 +791,12 @@ export function createConversationStore(deps) {
|
|
|
683
791
|
if (submission !== undefined)
|
|
684
792
|
return undefined;
|
|
685
793
|
const said = draft ?? current;
|
|
686
|
-
submission = {
|
|
687
|
-
operation,
|
|
688
|
-
text: said?.text ?? '',
|
|
689
|
-
files: [...(said?.files ?? [])],
|
|
690
|
-
turn: null,
|
|
691
|
-
};
|
|
794
|
+
submission = { operation, text: said?.text ?? '', turn: null };
|
|
692
795
|
return {
|
|
693
796
|
conversation,
|
|
694
797
|
...(draft === undefined || current === undefined
|
|
695
|
-
? { text: '',
|
|
696
|
-
: { text: current.text,
|
|
798
|
+
? { text: '', revision: chatDraftRevision() }
|
|
799
|
+
: { text: current.text, revision: current.revision }),
|
|
697
800
|
submitted: [...(current?.submitted ?? []), submission],
|
|
698
801
|
};
|
|
699
802
|
});
|
|
@@ -708,22 +811,21 @@ export function createConversationStore(deps) {
|
|
|
708
811
|
});
|
|
709
812
|
}
|
|
710
813
|
async function dispatched(conversation, submission) {
|
|
711
|
-
const dispatch = {};
|
|
814
|
+
const dispatch = { answered: false };
|
|
712
815
|
sending.set(submission.operation, dispatch);
|
|
713
816
|
try {
|
|
714
|
-
const
|
|
715
|
-
const result = await invoke('conversation.send', conversation, {
|
|
716
|
-
text: submission.text,
|
|
717
|
-
files,
|
|
817
|
+
const result = await invoke('conversations/send', conversation, {
|
|
718
818
|
operation_id: submission.operation,
|
|
819
|
+
text: submission.text,
|
|
719
820
|
});
|
|
821
|
+
dispatch.answered = result.kind !== 'transport-uncertainty';
|
|
720
822
|
if (result.kind === 'revoked-authorization')
|
|
721
823
|
return result;
|
|
722
824
|
if (result.kind !== 'action' && result.retryable) {
|
|
723
825
|
deps.unanswered();
|
|
724
826
|
return result;
|
|
725
827
|
}
|
|
726
|
-
const turn = answered(result, '
|
|
828
|
+
const turn = answered(result, 'message_id');
|
|
727
829
|
await withDraft(conversation, async (current, local) => {
|
|
728
830
|
const held = current?.submitted?.find((one) => one.operation === submission.operation);
|
|
729
831
|
if (current === undefined || held === undefined || held.turn !== null)
|
|
@@ -743,13 +845,20 @@ export function createConversationStore(deps) {
|
|
|
743
845
|
sending.delete(submission.operation);
|
|
744
846
|
}
|
|
745
847
|
}
|
|
746
|
-
function invoke(name, conversation, extra = {}) {
|
|
747
|
-
return deps.call(name, { conversation, ...extra });
|
|
848
|
+
function invoke(name, conversation, extra = { operation_id: changeBatchIdentity() }) {
|
|
849
|
+
return deps.call(name, { conversation_id: conversation, ...extra });
|
|
748
850
|
}
|
|
749
851
|
const surface = {
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
852
|
+
list() {
|
|
853
|
+
return new Promise((settle) => {
|
|
854
|
+
const answer = (listed) => {
|
|
855
|
+
unlisted.delete(answer);
|
|
856
|
+
listWatchers.delete(answer);
|
|
857
|
+
settle(listed);
|
|
858
|
+
};
|
|
859
|
+
unlisted.add(answer);
|
|
860
|
+
learned();
|
|
861
|
+
});
|
|
753
862
|
},
|
|
754
863
|
async read(conversation, options = {}) {
|
|
755
864
|
const asked = askedOf(options);
|
|
@@ -760,8 +869,8 @@ export function createConversationStore(deps) {
|
|
|
760
869
|
});
|
|
761
870
|
},
|
|
762
871
|
async create(input) {
|
|
763
|
-
const result = await deps.call('
|
|
764
|
-
const conversation = answered(result, '
|
|
872
|
+
const result = await deps.call('conversations/create', input);
|
|
873
|
+
const conversation = answered(result, 'conversation_id');
|
|
765
874
|
if (conversation === null)
|
|
766
875
|
return result;
|
|
767
876
|
if (!listing.has(conversation))
|
|
@@ -772,8 +881,17 @@ export function createConversationStore(deps) {
|
|
|
772
881
|
return result;
|
|
773
882
|
},
|
|
774
883
|
async send(conversation, operation = changeBatchIdentity(), draft) {
|
|
884
|
+
if (deps.full())
|
|
885
|
+
return DURABLE_WRITE;
|
|
775
886
|
if (deps.online()) {
|
|
776
|
-
const
|
|
887
|
+
const held = await submitted(conversation, operation, draft).catch((error) => {
|
|
888
|
+
if (refusedForSpace(error))
|
|
889
|
+
return null;
|
|
890
|
+
throw error;
|
|
891
|
+
});
|
|
892
|
+
if (held === null)
|
|
893
|
+
return DURABLE_WRITE;
|
|
894
|
+
const { submission, earlier } = held;
|
|
777
895
|
if (!earlier || !deps.expired(operation))
|
|
778
896
|
return dispatched(conversation, submission);
|
|
779
897
|
await forgotten(conversation, submission);
|
|
@@ -782,33 +900,24 @@ export function createConversationStore(deps) {
|
|
|
782
900
|
if (draft !== undefined) {
|
|
783
901
|
await withDraft(conversation, (current) => current?.submitted?.some((one) => one.operation === operation) === true
|
|
784
902
|
? undefined
|
|
785
|
-
: returned(current ?? { conversation, text: '',
|
|
903
|
+
: returned(current ?? { conversation, text: '', revision: '' }, { operation, ...draft, turn: null }, current?.submitted ?? []));
|
|
786
904
|
}
|
|
787
905
|
return OFFLINE;
|
|
788
906
|
},
|
|
789
907
|
answer(conversation, answer) {
|
|
790
|
-
return invoke('
|
|
908
|
+
return invoke('conversations/interaction/answer', conversation, {
|
|
909
|
+
operation_id: changeBatchIdentity(),
|
|
910
|
+
...answer,
|
|
911
|
+
});
|
|
791
912
|
},
|
|
792
913
|
interrupt(conversation) {
|
|
793
|
-
return invoke('
|
|
914
|
+
return invoke('conversations/interrupt', conversation);
|
|
794
915
|
},
|
|
795
916
|
kill(conversation) {
|
|
796
|
-
return invoke('
|
|
797
|
-
},
|
|
798
|
-
async cancel(conversation, turn) {
|
|
799
|
-
const result = await invoke('conversation.cancel', conversation, { turn });
|
|
800
|
-
if (result.kind !== 'action')
|
|
801
|
-
return result;
|
|
802
|
-
await withDraft(conversation, (current) => {
|
|
803
|
-
const held = current?.submitted?.find((one) => one.turn === turn);
|
|
804
|
-
if (current === undefined || held === undefined)
|
|
805
|
-
return undefined;
|
|
806
|
-
return returned(current, held, current.submitted.filter((one) => one !== held));
|
|
807
|
-
});
|
|
808
|
-
return result;
|
|
917
|
+
return invoke('conversations/kill', conversation);
|
|
809
918
|
},
|
|
810
919
|
delete(conversation) {
|
|
811
|
-
return invoke('
|
|
920
|
+
return invoke('conversations/delete', conversation);
|
|
812
921
|
},
|
|
813
922
|
};
|
|
814
923
|
const chatDraft = {
|
|
@@ -816,7 +925,6 @@ export function createConversationStore(deps) {
|
|
|
816
925
|
return withDraft(conversation, (current) => ({
|
|
817
926
|
conversation,
|
|
818
927
|
text: draft.text,
|
|
819
|
-
files: [...draft.files],
|
|
820
928
|
revision,
|
|
821
929
|
...(current === undefined ? {} : pending(current)),
|
|
822
930
|
}));
|
|
@@ -824,9 +932,7 @@ export function createConversationStore(deps) {
|
|
|
824
932
|
prepend(conversation, draft) {
|
|
825
933
|
return withDraft(conversation, (current) => ({
|
|
826
934
|
conversation,
|
|
827
|
-
...(current === undefined
|
|
828
|
-
? { text: draft.text, files: [...draft.files] }
|
|
829
|
-
: prepended(current, draft)),
|
|
935
|
+
...(current === undefined ? { text: draft.text } : prepended(current, draft)),
|
|
830
936
|
revision: chatDraftRevision(),
|
|
831
937
|
...(current === undefined ? {} : pending(current)),
|
|
832
938
|
}));
|
|
@@ -834,19 +940,21 @@ export function createConversationStore(deps) {
|
|
|
834
940
|
discard(conversation) {
|
|
835
941
|
return withDraft(conversation, (current) => current === undefined
|
|
836
942
|
? undefined
|
|
837
|
-
: {
|
|
838
|
-
conversation,
|
|
839
|
-
text: '',
|
|
840
|
-
files: [],
|
|
841
|
-
revision: chatDraftRevision(),
|
|
842
|
-
...pending(current),
|
|
843
|
-
});
|
|
943
|
+
: { conversation, text: '', revision: chatDraftRevision(), ...pending(current) });
|
|
844
944
|
},
|
|
845
945
|
};
|
|
846
946
|
return {
|
|
847
947
|
surface,
|
|
848
948
|
chatDraft,
|
|
849
|
-
hydrate(held, kept) {
|
|
949
|
+
hydrate(held, kept, list, cursor) {
|
|
950
|
+
if (list !== null && !listKnown) {
|
|
951
|
+
listing.clear();
|
|
952
|
+
for (const entry of list)
|
|
953
|
+
listing.set(entry.conversation, { ...entry });
|
|
954
|
+
listHeld = true;
|
|
955
|
+
listCursor = cursor;
|
|
956
|
+
deps.stream()?.hold(cursor);
|
|
957
|
+
}
|
|
850
958
|
stored.clear();
|
|
851
959
|
reads.clear();
|
|
852
960
|
partials.clear();
|
|
@@ -860,6 +968,8 @@ export function createConversationStore(deps) {
|
|
|
860
968
|
drafts.clear();
|
|
861
969
|
for (const record of kept)
|
|
862
970
|
drafts.set(record.conversation, record);
|
|
971
|
+
if (listHeld)
|
|
972
|
+
learned();
|
|
863
973
|
},
|
|
864
974
|
async reconcile() {
|
|
865
975
|
if (!listKnown)
|
|
@@ -871,7 +981,7 @@ export function createConversationStore(deps) {
|
|
|
871
981
|
!creations.has(conversation) &&
|
|
872
982
|
(!conversation.startsWith(NEW_CHAT) || retiredChat(conversation)));
|
|
873
983
|
for (const conversation of named) {
|
|
874
|
-
if (!replicated.has(conversation))
|
|
984
|
+
if (!replicated.has(conversation) && missed(conversation))
|
|
875
985
|
behind.add(conversation);
|
|
876
986
|
}
|
|
877
987
|
replicated = named;
|
|
@@ -880,6 +990,11 @@ export function createConversationStore(deps) {
|
|
|
880
990
|
await remove(leaving);
|
|
881
991
|
},
|
|
882
992
|
async catchUp(progress) {
|
|
993
|
+
if (deps.full()) {
|
|
994
|
+
if (behind.size > 0)
|
|
995
|
+
progress.complete = false;
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
883
998
|
const owed = (conversation) => behind.has(conversation) && replicated.has(conversation);
|
|
884
999
|
const read = async (conversations) => {
|
|
885
1000
|
if (conversations.length === 0 || deps.closed())
|
|
@@ -928,12 +1043,11 @@ export function createConversationStore(deps) {
|
|
|
928
1043
|
known() {
|
|
929
1044
|
return listKnown;
|
|
930
1045
|
},
|
|
931
|
-
reconnected() {
|
|
932
|
-
for (const conversation of replicated)
|
|
933
|
-
gap(conversation);
|
|
934
|
-
},
|
|
935
1046
|
reopened() {
|
|
936
|
-
|
|
1047
|
+
relisting = null;
|
|
1048
|
+
for (const [operation, dispatch] of sending)
|
|
1049
|
+
if (!dispatch.answered)
|
|
1050
|
+
sending.delete(operation);
|
|
937
1051
|
},
|
|
938
1052
|
lost() {
|
|
939
1053
|
catching.clear();
|
|
@@ -952,15 +1066,15 @@ export function createConversationStore(deps) {
|
|
|
952
1066
|
views.set(key, view);
|
|
953
1067
|
const watcher = { notify: deliver, ready: false };
|
|
954
1068
|
view.watchers.add(watcher);
|
|
955
|
-
|
|
956
|
-
|
|
1069
|
+
const reading = new AbortController();
|
|
1070
|
+
void untilAnswered(() => deps.durably(async (local) => {
|
|
957
1071
|
if (view.window !== null)
|
|
958
1072
|
return;
|
|
959
1073
|
const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
|
|
960
1074
|
view.window = messages;
|
|
961
1075
|
view.more = more;
|
|
962
1076
|
view.total = asked.total ? await local.messageCount(conversation) : null;
|
|
963
|
-
})
|
|
1077
|
+
}), reading.signal)
|
|
964
1078
|
.then(() => {
|
|
965
1079
|
if (deps.closed() || !view.watchers.has(watcher))
|
|
966
1080
|
return;
|
|
@@ -970,6 +1084,7 @@ export function createConversationStore(deps) {
|
|
|
970
1084
|
})
|
|
971
1085
|
.catch(() => { });
|
|
972
1086
|
return () => {
|
|
1087
|
+
reading.abort();
|
|
973
1088
|
if (!view.watchers.delete(watcher))
|
|
974
1089
|
return;
|
|
975
1090
|
if (view.watchers.size === 0)
|
|
@@ -977,61 +1092,76 @@ export function createConversationStore(deps) {
|
|
|
977
1092
|
};
|
|
978
1093
|
},
|
|
979
1094
|
watchList(deliver) {
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
if (!deps.closed() && listWatchers.has(deliver))
|
|
983
|
-
deliver(entries());
|
|
984
|
-
});
|
|
1095
|
+
unlisted.add(deliver);
|
|
1096
|
+
learned();
|
|
985
1097
|
return () => {
|
|
1098
|
+
unlisted.delete(deliver);
|
|
986
1099
|
listWatchers.delete(deliver);
|
|
987
1100
|
};
|
|
988
1101
|
},
|
|
989
1102
|
watchAgents(deliver) {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
deliver(agents());
|
|
994
|
-
});
|
|
1103
|
+
unnamed.add(deliver);
|
|
1104
|
+
learned();
|
|
1105
|
+
readAgents();
|
|
995
1106
|
return () => {
|
|
1107
|
+
unnamed.delete(deliver);
|
|
996
1108
|
agentWatchers.delete(deliver);
|
|
997
1109
|
};
|
|
998
1110
|
},
|
|
1111
|
+
learned,
|
|
999
1112
|
changed(set) {
|
|
1000
1113
|
for (const conversation of set.conversations)
|
|
1001
1114
|
emit(conversation);
|
|
1002
|
-
const declaration = deps.agents();
|
|
1003
|
-
if (declaration !== undefined &&
|
|
1004
|
-
set.documents.some((change) => change.locator === declaration.locator)) {
|
|
1005
|
-
agentsRead = readAgents().catch(() => {
|
|
1006
|
-
agentsRead = null;
|
|
1007
|
-
});
|
|
1008
|
-
}
|
|
1009
1115
|
},
|
|
1010
1116
|
receive(event) {
|
|
1011
1117
|
if (deps.closed())
|
|
1012
1118
|
return false;
|
|
1013
1119
|
if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
|
|
1014
1120
|
if (event.kind === 'list') {
|
|
1015
|
-
|
|
1121
|
+
if (event.whole)
|
|
1122
|
+
relisting ??= new Map();
|
|
1016
1123
|
for (const entry of event.entries) {
|
|
1017
|
-
|
|
1018
|
-
|
|
1124
|
+
if (relisting === null)
|
|
1125
|
+
listed(entry);
|
|
1126
|
+
else
|
|
1127
|
+
relisting.set(entry.conversation, { ...entry });
|
|
1019
1128
|
}
|
|
1129
|
+
if (event.more)
|
|
1130
|
+
return false;
|
|
1131
|
+
if (relisting !== null) {
|
|
1132
|
+
listing.clear();
|
|
1133
|
+
for (const entry of relisting.values())
|
|
1134
|
+
listed(entry);
|
|
1135
|
+
relisting = null;
|
|
1136
|
+
}
|
|
1137
|
+
listCursor = event.cursor;
|
|
1138
|
+
deps.stream()?.hold(event.cursor);
|
|
1020
1139
|
listKnown = true;
|
|
1140
|
+
for (const conversation of replicated) {
|
|
1141
|
+
if (!listing.has(conversation))
|
|
1142
|
+
continue;
|
|
1143
|
+
if (!missed(conversation))
|
|
1144
|
+
behind.delete(conversation);
|
|
1145
|
+
else if (!behind.has(conversation))
|
|
1146
|
+
gap(conversation);
|
|
1147
|
+
}
|
|
1021
1148
|
openingEnded();
|
|
1022
1149
|
}
|
|
1023
1150
|
else if (event.kind === 'listed') {
|
|
1024
|
-
|
|
1025
|
-
|
|
1151
|
+
listed(event.entry);
|
|
1152
|
+
relisting?.set(event.entry.conversation, { ...event.entry });
|
|
1026
1153
|
}
|
|
1027
1154
|
else {
|
|
1028
1155
|
listing.delete(event.conversation);
|
|
1156
|
+
relisting?.delete(event.conversation);
|
|
1029
1157
|
}
|
|
1158
|
+
keepList();
|
|
1030
1159
|
emitList();
|
|
1031
|
-
return (event.kind !== 'list' &&
|
|
1160
|
+
return ((event.kind !== 'list' &&
|
|
1032
1161
|
listKnown &&
|
|
1033
1162
|
(listing.size !== replicated.size ||
|
|
1034
|
-
[...listing.keys()].some((conversation) => !replicated.has(conversation))))
|
|
1163
|
+
[...listing.keys()].some((conversation) => !replicated.has(conversation)))) ||
|
|
1164
|
+
(listKnown && [...drafts.keys()].some(retiredChat)));
|
|
1035
1165
|
}
|
|
1036
1166
|
heard(event);
|
|
1037
1167
|
return false;
|
|
@@ -1047,7 +1177,9 @@ export function createConversationStore(deps) {
|
|
|
1047
1177
|
lives.clear();
|
|
1048
1178
|
unsent.clear();
|
|
1049
1179
|
listWatchers.clear();
|
|
1180
|
+
unlisted.clear();
|
|
1050
1181
|
agentWatchers.clear();
|
|
1182
|
+
unnamed.clear();
|
|
1051
1183
|
},
|
|
1052
1184
|
};
|
|
1053
1185
|
}
|