@agentshouse/mdruntime 0.1.0-cb9c79aee537a → 0.1.0-cba6f2439bb25
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 +70 -32
- 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 +26 -8
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +174 -102
- 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 +9 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +80 -6
- package/dist/collection.d.ts +11 -20
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +53 -354
- package/dist/compile.d.ts +16 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +771 -0
- package/dist/connection.d.ts +18 -10
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +2631 -986
- package/dist/conversation.d.ts +14 -6
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +237 -90
- 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 +3 -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 +4 -4
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +45 -15
- 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 +12 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/live.d.ts +22 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +124 -0
- package/dist/media.d.ts +8 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +208 -0
- package/dist/memory.d.ts +3 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +66 -23
- 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 -0
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +7 -1
- 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 -5
- 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 +201 -72
- package/dist/readiness.d.ts +19 -9
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +6 -6
- package/dist/reads.d.ts.map +1 -1
- package/dist/reads.js +10 -17
- package/dist/recovery.d.ts +2 -2
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +8 -7
- package/dist/refresh.d.ts +15 -14
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +113 -56
- package/dist/replica.d.ts +56 -38
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +279 -195
- 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 +5 -3
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +72 -35
- package/dist/status.d.ts +5 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +3 -1
- package/dist/store.d.ts +85 -93
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +323 -687
- package/dist/stored.d.ts +135 -0
- package/dist/stored.d.ts.map +1 -0
- package/dist/stored.js +568 -0
- package/dist/tables.d.ts +352 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +621 -0
- 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 +30 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +162 -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 -1
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +5 -1
- 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 -21
- package/dist/chat/markdown.d.ts.map +0 -1
- package/dist/chat/markdown.js +0 -246
- 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/pieces.d.ts +0 -51
- package/dist/chat/pieces.d.ts.map +0 -1
- package/dist/chat/pieces.js +0 -797
- 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/conversation.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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
6
|
import { capped, cursorOf, decodedCursor, FROM_START, messageOrder, precedes } from './windows.js';
|
|
@@ -10,8 +10,19 @@ const QUIET = {
|
|
|
10
10
|
process: null,
|
|
11
11
|
commands: [],
|
|
12
12
|
options: [],
|
|
13
|
+
starting: null,
|
|
14
|
+
link: null,
|
|
15
|
+
deliveryUnknown: [],
|
|
13
16
|
};
|
|
14
|
-
const FACTS = [
|
|
17
|
+
const FACTS = [
|
|
18
|
+
'questions',
|
|
19
|
+
'process',
|
|
20
|
+
'commands',
|
|
21
|
+
'options',
|
|
22
|
+
'starting',
|
|
23
|
+
'link',
|
|
24
|
+
'deliveryUnknown',
|
|
25
|
+
];
|
|
15
26
|
export function unheldView(conversation) {
|
|
16
27
|
return {
|
|
17
28
|
conversation,
|
|
@@ -21,19 +32,25 @@ export function unheldView(conversation) {
|
|
|
21
32
|
process: null,
|
|
22
33
|
commands: [],
|
|
23
34
|
options: [],
|
|
35
|
+
starting: null,
|
|
36
|
+
link: null,
|
|
37
|
+
deliveryUnknown: [],
|
|
24
38
|
chatDraft: null,
|
|
25
39
|
};
|
|
26
40
|
}
|
|
27
41
|
export const SESSION_STARTED = 'Session started';
|
|
28
42
|
const NEW_CHAT = 'new:';
|
|
43
|
+
export const HISTORY_CONVERSATIONS = 64;
|
|
29
44
|
export function newChat(agent) {
|
|
30
45
|
return `${NEW_CHAT}${agent}`;
|
|
31
46
|
}
|
|
32
47
|
function creationOf(input) {
|
|
33
48
|
if (typeof input !== 'object' || input === null)
|
|
34
49
|
return null;
|
|
35
|
-
const { agent_id: agent, operation_id: operation } = input;
|
|
36
|
-
return typeof agent === 'string' && typeof operation === 'string'
|
|
50
|
+
const { agent_id: agent, operation_id: operation, replaces, } = input;
|
|
51
|
+
return typeof agent === 'string' && typeof operation === 'string' && replaces === undefined
|
|
52
|
+
? { agent, operation }
|
|
53
|
+
: null;
|
|
37
54
|
}
|
|
38
55
|
function startedTurn(turn, operation) {
|
|
39
56
|
if (operation.op === 'begin')
|
|
@@ -193,8 +210,14 @@ function askedOf(options) {
|
|
|
193
210
|
return { limit: capped(limit), after, before: beforeOf(after), total: total === true };
|
|
194
211
|
}
|
|
195
212
|
const EXPIRED = { kind: 'rejected', code: 'expired', fields: {}, retryable: false };
|
|
213
|
+
const DURABLE_WRITE = {
|
|
214
|
+
kind: 'rejected',
|
|
215
|
+
code: 'durable-write',
|
|
216
|
+
fields: {},
|
|
217
|
+
retryable: true,
|
|
218
|
+
};
|
|
196
219
|
function unwritten(draft) {
|
|
197
|
-
return draft.text === ''
|
|
220
|
+
return draft.text === '';
|
|
198
221
|
}
|
|
199
222
|
function pending(draft) {
|
|
200
223
|
return {
|
|
@@ -210,10 +233,7 @@ function withSubmitted(draft, submitted) {
|
|
|
210
233
|
return submitted.length === 0 ? unsent : { ...unsent, submitted };
|
|
211
234
|
}
|
|
212
235
|
function prepended(draft, said) {
|
|
213
|
-
return {
|
|
214
|
-
text: [said.text, draft.text].filter((one) => one !== '').join('\n'),
|
|
215
|
-
files: [...said.files, ...draft.files],
|
|
216
|
-
};
|
|
236
|
+
return { text: [said.text, draft.text].filter((one) => one !== '').join('\n') };
|
|
217
237
|
}
|
|
218
238
|
function returned(draft, submission, others) {
|
|
219
239
|
return withSubmitted({
|
|
@@ -237,11 +257,17 @@ export function createConversationStore(deps) {
|
|
|
237
257
|
const listing = new Map();
|
|
238
258
|
const creations = new Set();
|
|
239
259
|
const listWatchers = new Set();
|
|
260
|
+
const unlisted = new Set();
|
|
240
261
|
let listKnown = false;
|
|
262
|
+
let listHeld = false;
|
|
263
|
+
let listKept = false;
|
|
241
264
|
const agentWatchers = new Set();
|
|
265
|
+
const unnamed = new Set();
|
|
266
|
+
let agentsKnown = false;
|
|
242
267
|
let agentNames = new Map();
|
|
243
268
|
let retiredAgents = new Set();
|
|
244
269
|
let agentsRead = null;
|
|
270
|
+
let agentsFrom;
|
|
245
271
|
let replicated = new Set();
|
|
246
272
|
let handedReplicated;
|
|
247
273
|
function liveOf(conversation) {
|
|
@@ -264,9 +290,12 @@ export function createConversationStore(deps) {
|
|
|
264
290
|
process: facts.process === null ? null : { ...facts.process },
|
|
265
291
|
commands: structuredClone(facts.commands),
|
|
266
292
|
options: structuredClone(facts.options),
|
|
293
|
+
starting: facts.starting,
|
|
294
|
+
link: facts.link === null ? null : { ...facts.link },
|
|
295
|
+
deliveryUnknown: [...facts.deliveryUnknown],
|
|
267
296
|
chatDraft: draft === undefined || unwritten(draft)
|
|
268
297
|
? null
|
|
269
|
-
: { text: draft.text,
|
|
298
|
+
: { text: draft.text, revision: draft.revision },
|
|
270
299
|
};
|
|
271
300
|
}
|
|
272
301
|
function emit(conversation) {
|
|
@@ -308,9 +337,6 @@ export function createConversationStore(deps) {
|
|
|
308
337
|
}
|
|
309
338
|
}
|
|
310
339
|
}
|
|
311
|
-
function changesOf(conversation, arriving) {
|
|
312
|
-
return arriving.map(({ identity, text }) => ({ conversation, identity, text }));
|
|
313
|
-
}
|
|
314
340
|
function stateOf(conversation) {
|
|
315
341
|
const facts = liveOf(conversation);
|
|
316
342
|
if (facts.questions.length > 0)
|
|
@@ -325,16 +351,58 @@ export function createConversationStore(deps) {
|
|
|
325
351
|
created: entry.created,
|
|
326
352
|
finished: entry.finished,
|
|
327
353
|
outcome: entry.outcome,
|
|
354
|
+
waiting: entry.waiting,
|
|
328
355
|
state: stateOf(entry.conversation),
|
|
329
356
|
started: lives.get(entry.conversation)?.turn?.started ?? null,
|
|
330
357
|
}));
|
|
331
358
|
}
|
|
359
|
+
function keepList() {
|
|
360
|
+
if (!listKnown || listKept)
|
|
361
|
+
return;
|
|
362
|
+
listKept = true;
|
|
363
|
+
queueMicrotask(() => {
|
|
364
|
+
listKept = false;
|
|
365
|
+
if (deps.closed())
|
|
366
|
+
return;
|
|
367
|
+
const entries = [...listing.values()];
|
|
368
|
+
void deps.durably((local) => local.fact('conversationList', entries)).catch(() => { });
|
|
369
|
+
});
|
|
370
|
+
}
|
|
332
371
|
function emitList() {
|
|
333
|
-
if (deps.closed()
|
|
372
|
+
if (deps.closed())
|
|
334
373
|
return;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
watcher
|
|
374
|
+
if (listWatchers.size > 0) {
|
|
375
|
+
const value = entries();
|
|
376
|
+
for (const watcher of listWatchers)
|
|
377
|
+
watcher(value);
|
|
378
|
+
}
|
|
379
|
+
learned();
|
|
380
|
+
}
|
|
381
|
+
function unlearnable() {
|
|
382
|
+
return !deps.online() || (deps.listed() && deps.agents() === undefined);
|
|
383
|
+
}
|
|
384
|
+
function learned() {
|
|
385
|
+
if (deps.closed())
|
|
386
|
+
return;
|
|
387
|
+
const named = agentsKnown || unlearnable();
|
|
388
|
+
if (unlisted.size > 0 &&
|
|
389
|
+
named &&
|
|
390
|
+
(listKnown || listHeld || deps.stream() === undefined || unlearnable())) {
|
|
391
|
+
const value = entries();
|
|
392
|
+
for (const watcher of [...unlisted]) {
|
|
393
|
+
unlisted.delete(watcher);
|
|
394
|
+
listWatchers.add(watcher);
|
|
395
|
+
watcher(value);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (unnamed.size > 0 && named) {
|
|
399
|
+
const value = agents();
|
|
400
|
+
for (const watcher of [...unnamed]) {
|
|
401
|
+
unnamed.delete(watcher);
|
|
402
|
+
agentWatchers.add(watcher);
|
|
403
|
+
watcher(value);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
338
406
|
}
|
|
339
407
|
function agents() {
|
|
340
408
|
return [...agentNames]
|
|
@@ -365,34 +433,46 @@ export function createConversationStore(deps) {
|
|
|
365
433
|
}
|
|
366
434
|
async function readAgents() {
|
|
367
435
|
const declaration = deps.agents();
|
|
436
|
+
agentsFrom = JSON.stringify(declaration);
|
|
368
437
|
if (declaration === undefined)
|
|
369
438
|
return;
|
|
370
|
-
const held = await deps.documents(declaration);
|
|
371
|
-
if ('pending' in held)
|
|
372
|
-
return;
|
|
373
|
-
const { documents } = held;
|
|
374
439
|
const names = new Map();
|
|
375
440
|
const retired = new Set();
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
441
|
+
let covered = null;
|
|
442
|
+
for (let after;;) {
|
|
443
|
+
const read = await deps.documents(declaration, after);
|
|
444
|
+
if ('pending' in read)
|
|
445
|
+
return;
|
|
446
|
+
const coverage = JSON.stringify(read.coverage);
|
|
447
|
+
if (covered !== null && coverage !== covered)
|
|
448
|
+
return readAgents();
|
|
449
|
+
covered = coverage;
|
|
450
|
+
for (const document of read.documents) {
|
|
451
|
+
const identity = document.fields?.[declaration.identity];
|
|
452
|
+
const name = document.fields?.[declaration.name];
|
|
453
|
+
if (typeof identity !== 'string' || typeof name !== 'string')
|
|
454
|
+
continue;
|
|
455
|
+
names.set(identity, name);
|
|
456
|
+
const ended = declaration.retired === undefined ? null : document.fields?.[declaration.retired];
|
|
457
|
+
if (ended !== undefined && ended !== null)
|
|
458
|
+
retired.add(identity);
|
|
459
|
+
}
|
|
460
|
+
if (read.next === undefined)
|
|
461
|
+
break;
|
|
462
|
+
after = read.next;
|
|
387
463
|
}
|
|
464
|
+
agentsKnown = true;
|
|
388
465
|
const named = JSON.stringify([...names]) !== JSON.stringify([...agentNames]);
|
|
389
|
-
if (!named && JSON.stringify([...retired]) === JSON.stringify([...retiredAgents]))
|
|
466
|
+
if (!named && JSON.stringify([...retired]) === JSON.stringify([...retiredAgents])) {
|
|
467
|
+
learned();
|
|
390
468
|
return;
|
|
469
|
+
}
|
|
391
470
|
agentNames = names;
|
|
392
471
|
retiredAgents = retired;
|
|
472
|
+
emitAgents();
|
|
393
473
|
if (named)
|
|
394
474
|
emitList();
|
|
395
|
-
|
|
475
|
+
learned();
|
|
396
476
|
const ended = [...drafts.keys()].filter(retiredChat);
|
|
397
477
|
if (ended.length > 0)
|
|
398
478
|
await remove(ended);
|
|
@@ -426,6 +506,11 @@ export function createConversationStore(deps) {
|
|
|
426
506
|
process: facts.has('process') ? QUIET.process : held.process,
|
|
427
507
|
commands: facts.has('commands') ? QUIET.commands : held.commands,
|
|
428
508
|
options: facts.has('options') ? QUIET.options : held.options,
|
|
509
|
+
starting: facts.has('starting') ? QUIET.starting : held.starting,
|
|
510
|
+
link: facts.has('link') ? QUIET.link : held.link,
|
|
511
|
+
deliveryUnknown: facts.has('deliveryUnknown')
|
|
512
|
+
? QUIET.deliveryUnknown
|
|
513
|
+
: held.deliveryUnknown,
|
|
429
514
|
});
|
|
430
515
|
emit(conversation);
|
|
431
516
|
}
|
|
@@ -456,12 +541,6 @@ export function createConversationStore(deps) {
|
|
|
456
541
|
}
|
|
457
542
|
async function remove(leaving) {
|
|
458
543
|
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
544
|
await local.dropConversations(leaving);
|
|
466
545
|
const changed = [];
|
|
467
546
|
for (const conversation of leaving) {
|
|
@@ -478,9 +557,23 @@ export function createConversationStore(deps) {
|
|
|
478
557
|
await slide(local, conversation, null);
|
|
479
558
|
}
|
|
480
559
|
if (changed.length > 0)
|
|
481
|
-
deps.publish(conversationChangeSet(
|
|
560
|
+
deps.publish(conversationChangeSet(changed));
|
|
482
561
|
});
|
|
483
562
|
}
|
|
563
|
+
function missed(conversation) {
|
|
564
|
+
const read = reads.get(conversation);
|
|
565
|
+
const newest = listing.get(conversation)?.newest;
|
|
566
|
+
return (read === undefined ||
|
|
567
|
+
newest === undefined ||
|
|
568
|
+
partials.has(conversation) ||
|
|
569
|
+
(newest !== null && (read === null || newest > read)));
|
|
570
|
+
}
|
|
571
|
+
function noted(conversation, message) {
|
|
572
|
+
const entry = listing.get(conversation);
|
|
573
|
+
if (entry === undefined || (entry.newest !== null && entry.newest >= message.position))
|
|
574
|
+
return;
|
|
575
|
+
listing.set(conversation, { ...entry, newest: message.position });
|
|
576
|
+
}
|
|
484
577
|
function gap(conversation) {
|
|
485
578
|
gaps.set(conversation, (gaps.get(conversation) ?? 0) + 1);
|
|
486
579
|
behind.add(conversation);
|
|
@@ -504,16 +597,17 @@ export function createConversationStore(deps) {
|
|
|
504
597
|
reads.set(conversation, message.position);
|
|
505
598
|
sealTurns(conversation, new Set([message.turn]));
|
|
506
599
|
await slide(local, conversation, [message]);
|
|
507
|
-
deps.publish(conversationChangeSet(
|
|
600
|
+
deps.publish(conversationChangeSet([conversation]));
|
|
508
601
|
});
|
|
509
602
|
}
|
|
510
603
|
async function readHistories(conversations, ended) {
|
|
511
604
|
const generations = new Map(conversations.map((one) => [one, gaps.get(one) ?? 0]));
|
|
512
|
-
let
|
|
605
|
+
let waiting = conversations.map((conversation) => ({
|
|
513
606
|
conversation,
|
|
514
607
|
after: reads.get(conversation) ?? undefined,
|
|
515
608
|
}));
|
|
516
|
-
while (
|
|
609
|
+
while (waiting.length > 0) {
|
|
610
|
+
const asking = waiting.slice(0, HISTORY_CONVERSATIONS);
|
|
517
611
|
const result = await deps.call('conversation.history', {
|
|
518
612
|
conversations: asking.map(({ conversation, after }) => ({
|
|
519
613
|
conversation,
|
|
@@ -537,7 +631,7 @@ export function createConversationStore(deps) {
|
|
|
537
631
|
if (!following.some((next) => next.conversation === conversation))
|
|
538
632
|
ended(conversation);
|
|
539
633
|
}
|
|
540
|
-
|
|
634
|
+
waiting = [...waiting.slice(HISTORY_CONVERSATIONS), ...following];
|
|
541
635
|
}
|
|
542
636
|
return null;
|
|
543
637
|
}
|
|
@@ -580,7 +674,7 @@ export function createConversationStore(deps) {
|
|
|
580
674
|
behind.delete(conversation);
|
|
581
675
|
await slide(local, conversation, arriving);
|
|
582
676
|
if (arriving.length > 0 || sealing || whole) {
|
|
583
|
-
deps.publish(conversationChangeSet(
|
|
677
|
+
deps.publish(conversationChangeSet([conversation]));
|
|
584
678
|
}
|
|
585
679
|
});
|
|
586
680
|
}
|
|
@@ -613,11 +707,31 @@ export function createConversationStore(deps) {
|
|
|
613
707
|
live(conversation, { options: structuredClone(event.options) });
|
|
614
708
|
return;
|
|
615
709
|
}
|
|
710
|
+
if (event.kind === 'starting') {
|
|
711
|
+
live(conversation, { starting: event.step });
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
if (event.kind === 'link') {
|
|
715
|
+
live(conversation, { link: { connected: event.connected } });
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
if (event.kind === 'deliveries') {
|
|
719
|
+
live(conversation, { deliveryUnknown: [...event.unknown] });
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
616
722
|
const arriving = acceptedMessage(event.message);
|
|
617
723
|
if (arriving === null)
|
|
618
724
|
return;
|
|
725
|
+
noted(conversation, arriving);
|
|
619
726
|
if (replicated.has(conversation)) {
|
|
620
|
-
|
|
727
|
+
if (deps.full()) {
|
|
728
|
+
gap(conversation);
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
void keep(conversation, arriving).catch((error) => {
|
|
732
|
+
if (refusedForSpace(error))
|
|
733
|
+
gap(conversation);
|
|
734
|
+
});
|
|
621
735
|
return;
|
|
622
736
|
}
|
|
623
737
|
if (sealTurns(conversation, new Set([arriving.turn])))
|
|
@@ -652,7 +766,6 @@ export function createConversationStore(deps) {
|
|
|
652
766
|
const blank = {
|
|
653
767
|
conversation: from,
|
|
654
768
|
text: '',
|
|
655
|
-
files: [],
|
|
656
769
|
revision: chatDraftRevision(),
|
|
657
770
|
};
|
|
658
771
|
const { moves: _answered, ...unsent } = held ?? blank;
|
|
@@ -662,7 +775,7 @@ export function createConversationStore(deps) {
|
|
|
662
775
|
drafts.set(from, left);
|
|
663
776
|
for (const one of taken)
|
|
664
777
|
drafts.set(to, one);
|
|
665
|
-
deps.publish(conversationChangeSet([
|
|
778
|
+
deps.publish(conversationChangeSet([from, to]));
|
|
666
779
|
});
|
|
667
780
|
}
|
|
668
781
|
function withDraft(conversation, next) {
|
|
@@ -671,7 +784,7 @@ export function createConversationStore(deps) {
|
|
|
671
784
|
if (following === undefined)
|
|
672
785
|
return;
|
|
673
786
|
await kept(local, conversation, following);
|
|
674
|
-
deps.publish(conversationChangeSet([
|
|
787
|
+
deps.publish(conversationChangeSet([conversation]));
|
|
675
788
|
});
|
|
676
789
|
}
|
|
677
790
|
async function submitted(conversation, operation, draft) {
|
|
@@ -683,17 +796,12 @@ export function createConversationStore(deps) {
|
|
|
683
796
|
if (submission !== undefined)
|
|
684
797
|
return undefined;
|
|
685
798
|
const said = draft ?? current;
|
|
686
|
-
submission = {
|
|
687
|
-
operation,
|
|
688
|
-
text: said?.text ?? '',
|
|
689
|
-
files: [...(said?.files ?? [])],
|
|
690
|
-
turn: null,
|
|
691
|
-
};
|
|
799
|
+
submission = { operation, text: said?.text ?? '', turn: null };
|
|
692
800
|
return {
|
|
693
801
|
conversation,
|
|
694
802
|
...(draft === undefined || current === undefined
|
|
695
|
-
? { text: '',
|
|
696
|
-
: { text: current.text,
|
|
803
|
+
? { text: '', revision: chatDraftRevision() }
|
|
804
|
+
: { text: current.text, revision: current.revision }),
|
|
697
805
|
submitted: [...(current?.submitted ?? []), submission],
|
|
698
806
|
};
|
|
699
807
|
});
|
|
@@ -708,15 +816,14 @@ export function createConversationStore(deps) {
|
|
|
708
816
|
});
|
|
709
817
|
}
|
|
710
818
|
async function dispatched(conversation, submission) {
|
|
711
|
-
const dispatch = {};
|
|
819
|
+
const dispatch = { answered: false };
|
|
712
820
|
sending.set(submission.operation, dispatch);
|
|
713
821
|
try {
|
|
714
|
-
const files = await Promise.all(submission.files.map(async (file) => ({ ...(await declaredFile(file)), blob: file.blob })));
|
|
715
822
|
const result = await invoke('conversation.send', conversation, {
|
|
716
823
|
text: submission.text,
|
|
717
|
-
files,
|
|
718
824
|
operation_id: submission.operation,
|
|
719
825
|
});
|
|
826
|
+
dispatch.answered = result.kind !== 'transport-uncertainty';
|
|
720
827
|
if (result.kind === 'revoked-authorization')
|
|
721
828
|
return result;
|
|
722
829
|
if (result.kind !== 'action' && result.retryable) {
|
|
@@ -749,7 +856,15 @@ export function createConversationStore(deps) {
|
|
|
749
856
|
const surface = {
|
|
750
857
|
async list() {
|
|
751
858
|
await agentsReady();
|
|
752
|
-
return
|
|
859
|
+
return new Promise((settle) => {
|
|
860
|
+
const answer = (listed) => {
|
|
861
|
+
unlisted.delete(answer);
|
|
862
|
+
listWatchers.delete(answer);
|
|
863
|
+
settle(listed);
|
|
864
|
+
};
|
|
865
|
+
unlisted.add(answer);
|
|
866
|
+
learned();
|
|
867
|
+
});
|
|
753
868
|
},
|
|
754
869
|
async read(conversation, options = {}) {
|
|
755
870
|
const asked = askedOf(options);
|
|
@@ -772,8 +887,17 @@ export function createConversationStore(deps) {
|
|
|
772
887
|
return result;
|
|
773
888
|
},
|
|
774
889
|
async send(conversation, operation = changeBatchIdentity(), draft) {
|
|
890
|
+
if (deps.full())
|
|
891
|
+
return DURABLE_WRITE;
|
|
775
892
|
if (deps.online()) {
|
|
776
|
-
const
|
|
893
|
+
const held = await submitted(conversation, operation, draft).catch((error) => {
|
|
894
|
+
if (refusedForSpace(error))
|
|
895
|
+
return null;
|
|
896
|
+
throw error;
|
|
897
|
+
});
|
|
898
|
+
if (held === null)
|
|
899
|
+
return DURABLE_WRITE;
|
|
900
|
+
const { submission, earlier } = held;
|
|
777
901
|
if (!earlier || !deps.expired(operation))
|
|
778
902
|
return dispatched(conversation, submission);
|
|
779
903
|
await forgotten(conversation, submission);
|
|
@@ -782,7 +906,7 @@ export function createConversationStore(deps) {
|
|
|
782
906
|
if (draft !== undefined) {
|
|
783
907
|
await withDraft(conversation, (current) => current?.submitted?.some((one) => one.operation === operation) === true
|
|
784
908
|
? undefined
|
|
785
|
-
: returned(current ?? { conversation, text: '',
|
|
909
|
+
: returned(current ?? { conversation, text: '', revision: '' }, { operation, ...draft, turn: null }, current?.submitted ?? []));
|
|
786
910
|
}
|
|
787
911
|
return OFFLINE;
|
|
788
912
|
},
|
|
@@ -816,7 +940,6 @@ export function createConversationStore(deps) {
|
|
|
816
940
|
return withDraft(conversation, (current) => ({
|
|
817
941
|
conversation,
|
|
818
942
|
text: draft.text,
|
|
819
|
-
files: [...draft.files],
|
|
820
943
|
revision,
|
|
821
944
|
...(current === undefined ? {} : pending(current)),
|
|
822
945
|
}));
|
|
@@ -824,9 +947,7 @@ export function createConversationStore(deps) {
|
|
|
824
947
|
prepend(conversation, draft) {
|
|
825
948
|
return withDraft(conversation, (current) => ({
|
|
826
949
|
conversation,
|
|
827
|
-
...(current === undefined
|
|
828
|
-
? { text: draft.text, files: [...draft.files] }
|
|
829
|
-
: prepended(current, draft)),
|
|
950
|
+
...(current === undefined ? { text: draft.text } : prepended(current, draft)),
|
|
830
951
|
revision: chatDraftRevision(),
|
|
831
952
|
...(current === undefined ? {} : pending(current)),
|
|
832
953
|
}));
|
|
@@ -834,19 +955,19 @@ export function createConversationStore(deps) {
|
|
|
834
955
|
discard(conversation) {
|
|
835
956
|
return withDraft(conversation, (current) => current === undefined
|
|
836
957
|
? undefined
|
|
837
|
-
: {
|
|
838
|
-
conversation,
|
|
839
|
-
text: '',
|
|
840
|
-
files: [],
|
|
841
|
-
revision: chatDraftRevision(),
|
|
842
|
-
...pending(current),
|
|
843
|
-
});
|
|
958
|
+
: { conversation, text: '', revision: chatDraftRevision(), ...pending(current) });
|
|
844
959
|
},
|
|
845
960
|
};
|
|
846
961
|
return {
|
|
847
962
|
surface,
|
|
848
963
|
chatDraft,
|
|
849
|
-
hydrate(held, kept) {
|
|
964
|
+
hydrate(held, kept, list) {
|
|
965
|
+
if (list !== null && !listKnown) {
|
|
966
|
+
listing.clear();
|
|
967
|
+
for (const entry of list)
|
|
968
|
+
listing.set(entry.conversation, { ...entry });
|
|
969
|
+
listHeld = true;
|
|
970
|
+
}
|
|
850
971
|
stored.clear();
|
|
851
972
|
reads.clear();
|
|
852
973
|
partials.clear();
|
|
@@ -860,6 +981,8 @@ export function createConversationStore(deps) {
|
|
|
860
981
|
drafts.clear();
|
|
861
982
|
for (const record of kept)
|
|
862
983
|
drafts.set(record.conversation, record);
|
|
984
|
+
if (listHeld)
|
|
985
|
+
learned();
|
|
863
986
|
},
|
|
864
987
|
async reconcile() {
|
|
865
988
|
if (!listKnown)
|
|
@@ -871,7 +994,7 @@ export function createConversationStore(deps) {
|
|
|
871
994
|
!creations.has(conversation) &&
|
|
872
995
|
(!conversation.startsWith(NEW_CHAT) || retiredChat(conversation)));
|
|
873
996
|
for (const conversation of named) {
|
|
874
|
-
if (!replicated.has(conversation))
|
|
997
|
+
if (!replicated.has(conversation) && missed(conversation))
|
|
875
998
|
behind.add(conversation);
|
|
876
999
|
}
|
|
877
1000
|
replicated = named;
|
|
@@ -880,6 +1003,11 @@ export function createConversationStore(deps) {
|
|
|
880
1003
|
await remove(leaving);
|
|
881
1004
|
},
|
|
882
1005
|
async catchUp(progress) {
|
|
1006
|
+
if (deps.full()) {
|
|
1007
|
+
if (behind.size > 0)
|
|
1008
|
+
progress.complete = false;
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
883
1011
|
const owed = (conversation) => behind.has(conversation) && replicated.has(conversation);
|
|
884
1012
|
const read = async (conversations) => {
|
|
885
1013
|
if (conversations.length === 0 || deps.closed())
|
|
@@ -928,12 +1056,10 @@ export function createConversationStore(deps) {
|
|
|
928
1056
|
known() {
|
|
929
1057
|
return listKnown;
|
|
930
1058
|
},
|
|
931
|
-
reconnected() {
|
|
932
|
-
for (const conversation of replicated)
|
|
933
|
-
gap(conversation);
|
|
934
|
-
},
|
|
935
1059
|
reopened() {
|
|
936
|
-
sending
|
|
1060
|
+
for (const [operation, dispatch] of sending)
|
|
1061
|
+
if (!dispatch.answered)
|
|
1062
|
+
sending.delete(operation);
|
|
937
1063
|
},
|
|
938
1064
|
lost() {
|
|
939
1065
|
catching.clear();
|
|
@@ -977,25 +1103,35 @@ export function createConversationStore(deps) {
|
|
|
977
1103
|
};
|
|
978
1104
|
},
|
|
979
1105
|
watchList(deliver) {
|
|
980
|
-
|
|
1106
|
+
let ended = false;
|
|
981
1107
|
void agentsReady().then(() => {
|
|
982
|
-
if (
|
|
983
|
-
|
|
1108
|
+
if (ended)
|
|
1109
|
+
return;
|
|
1110
|
+
unlisted.add(deliver);
|
|
1111
|
+
learned();
|
|
984
1112
|
});
|
|
985
1113
|
return () => {
|
|
1114
|
+
ended = true;
|
|
1115
|
+
unlisted.delete(deliver);
|
|
986
1116
|
listWatchers.delete(deliver);
|
|
987
1117
|
};
|
|
988
1118
|
},
|
|
989
1119
|
watchAgents(deliver) {
|
|
990
|
-
|
|
991
|
-
void agentsReady().then(
|
|
992
|
-
if (!deps.closed() && agentWatchers.has(deliver))
|
|
993
|
-
deliver(agents());
|
|
994
|
-
});
|
|
1120
|
+
unnamed.add(deliver);
|
|
1121
|
+
void agentsReady().then(learned);
|
|
995
1122
|
return () => {
|
|
1123
|
+
unnamed.delete(deliver);
|
|
996
1124
|
agentWatchers.delete(deliver);
|
|
997
1125
|
};
|
|
998
1126
|
},
|
|
1127
|
+
learned,
|
|
1128
|
+
declared() {
|
|
1129
|
+
if (JSON.stringify(deps.agents()) === agentsFrom)
|
|
1130
|
+
return;
|
|
1131
|
+
agentsRead = readAgents().catch(() => {
|
|
1132
|
+
agentsRead = null;
|
|
1133
|
+
});
|
|
1134
|
+
},
|
|
999
1135
|
changed(set) {
|
|
1000
1136
|
for (const conversation of set.conversations)
|
|
1001
1137
|
emit(conversation);
|
|
@@ -1018,6 +1154,14 @@ export function createConversationStore(deps) {
|
|
|
1018
1154
|
creations.delete(entry.conversation);
|
|
1019
1155
|
}
|
|
1020
1156
|
listKnown = true;
|
|
1157
|
+
for (const conversation of replicated) {
|
|
1158
|
+
if (!listing.has(conversation))
|
|
1159
|
+
continue;
|
|
1160
|
+
if (!missed(conversation))
|
|
1161
|
+
behind.delete(conversation);
|
|
1162
|
+
else if (!behind.has(conversation))
|
|
1163
|
+
gap(conversation);
|
|
1164
|
+
}
|
|
1021
1165
|
openingEnded();
|
|
1022
1166
|
}
|
|
1023
1167
|
else if (event.kind === 'listed') {
|
|
@@ -1027,6 +1171,7 @@ export function createConversationStore(deps) {
|
|
|
1027
1171
|
else {
|
|
1028
1172
|
listing.delete(event.conversation);
|
|
1029
1173
|
}
|
|
1174
|
+
keepList();
|
|
1030
1175
|
emitList();
|
|
1031
1176
|
return (event.kind !== 'list' &&
|
|
1032
1177
|
listKnown &&
|
|
@@ -1047,7 +1192,9 @@ export function createConversationStore(deps) {
|
|
|
1047
1192
|
lives.clear();
|
|
1048
1193
|
unsent.clear();
|
|
1049
1194
|
listWatchers.clear();
|
|
1195
|
+
unlisted.clear();
|
|
1050
1196
|
agentWatchers.clear();
|
|
1197
|
+
unnamed.clear();
|
|
1051
1198
|
},
|
|
1052
1199
|
};
|
|
1053
1200
|
}
|
package/dist/digest.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"AA0EA,MAAM,MAAM,MAAM,GAAG;IACnB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,GAAG,IAAI,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,MAAM,IAAI,MAAM,CAoC/B;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAMxD"}
|