@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.
Files changed (229) hide show
  1. package/README.md +18 -15
  2. package/dist/adapter.d.ts +70 -32
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +5 -1
  5. package/dist/attached-model.d.ts.map +1 -1
  6. package/dist/attached-model.js +38 -4
  7. package/dist/binary.d.ts +0 -5
  8. package/dist/binary.d.ts.map +1 -1
  9. package/dist/binary.js +1 -1
  10. package/dist/bootstrap.d.ts +26 -8
  11. package/dist/bootstrap.d.ts.map +1 -1
  12. package/dist/bootstrap.js +174 -102
  13. package/dist/chain.d.ts +11 -0
  14. package/dist/chain.d.ts.map +1 -0
  15. package/dist/chain.js +64 -0
  16. package/dist/change-set.d.ts +9 -16
  17. package/dist/change-set.d.ts.map +1 -1
  18. package/dist/change-set.js +11 -89
  19. package/dist/change.d.ts +31 -1
  20. package/dist/change.d.ts.map +1 -1
  21. package/dist/change.js +10 -1
  22. package/dist/client.d.ts +9 -5
  23. package/dist/client.d.ts.map +1 -1
  24. package/dist/client.js +80 -6
  25. package/dist/collection.d.ts +11 -20
  26. package/dist/collection.d.ts.map +1 -1
  27. package/dist/collection.js +53 -354
  28. package/dist/compile.d.ts +16 -0
  29. package/dist/compile.d.ts.map +1 -0
  30. package/dist/compile.js +771 -0
  31. package/dist/connection.d.ts +18 -10
  32. package/dist/connection.d.ts.map +1 -1
  33. package/dist/connection.js +2631 -986
  34. package/dist/conversation.d.ts +14 -6
  35. package/dist/conversation.d.ts.map +1 -1
  36. package/dist/conversation.js +237 -90
  37. package/dist/digest.d.ts +7 -0
  38. package/dist/digest.d.ts.map +1 -0
  39. package/dist/digest.js +113 -0
  40. package/dist/durability.d.ts +3 -5
  41. package/dist/durability.d.ts.map +1 -1
  42. package/dist/durability.js +5 -0
  43. package/dist/entry.d.ts +4 -1
  44. package/dist/entry.d.ts.map +1 -1
  45. package/dist/entry.js +18 -24
  46. package/dist/file.d.ts +2 -19
  47. package/dist/file.d.ts.map +1 -1
  48. package/dist/file.js +7 -122
  49. package/dist/fulltext.d.ts +27 -0
  50. package/dist/fulltext.d.ts.map +1 -0
  51. package/dist/fulltext.js +370 -0
  52. package/dist/host.d.ts +4 -4
  53. package/dist/host.d.ts.map +1 -1
  54. package/dist/host.js +45 -15
  55. package/dist/identity.d.ts +0 -1
  56. package/dist/identity.d.ts.map +1 -1
  57. package/dist/identity.js +0 -3
  58. package/dist/index.d.ts +12 -10
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +5 -2
  61. package/dist/live.d.ts +22 -0
  62. package/dist/live.d.ts.map +1 -0
  63. package/dist/live.js +124 -0
  64. package/dist/media.d.ts +8 -0
  65. package/dist/media.d.ts.map +1 -0
  66. package/dist/media.js +208 -0
  67. package/dist/memory.d.ts +3 -2
  68. package/dist/memory.d.ts.map +1 -1
  69. package/dist/memory.js +66 -23
  70. package/dist/messages.d.ts +28 -0
  71. package/dist/messages.d.ts.map +1 -0
  72. package/dist/messages.js +90 -0
  73. package/dist/model.d.ts +6 -0
  74. package/dist/model.d.ts.map +1 -1
  75. package/dist/model.js +7 -1
  76. package/dist/name.d.ts +4 -0
  77. package/dist/name.d.ts.map +1 -0
  78. package/dist/name.js +122 -0
  79. package/dist/observation.d.ts +13 -0
  80. package/dist/observation.d.ts.map +1 -1
  81. package/dist/observation.js +84 -0
  82. package/dist/opened.d.ts +22 -0
  83. package/dist/opened.d.ts.map +1 -0
  84. package/dist/opened.js +107 -0
  85. package/dist/outcome.d.ts +40 -5
  86. package/dist/outcome.d.ts.map +1 -1
  87. package/dist/outcome.js +38 -2
  88. package/dist/overlay.d.ts +2 -6
  89. package/dist/overlay.d.ts.map +1 -1
  90. package/dist/overlay.js +87 -176
  91. package/dist/paths.d.ts +1 -0
  92. package/dist/paths.d.ts.map +1 -1
  93. package/dist/paths.js +4 -0
  94. package/dist/query.d.ts +11 -1
  95. package/dist/query.d.ts.map +1 -1
  96. package/dist/query.js +13 -1
  97. package/dist/reach.d.ts +13 -4
  98. package/dist/reach.d.ts.map +1 -1
  99. package/dist/reach.js +201 -72
  100. package/dist/readiness.d.ts +19 -9
  101. package/dist/readiness.d.ts.map +1 -1
  102. package/dist/readiness.js +6 -6
  103. package/dist/reads.d.ts.map +1 -1
  104. package/dist/reads.js +10 -17
  105. package/dist/recovery.d.ts +2 -2
  106. package/dist/recovery.d.ts.map +1 -1
  107. package/dist/recovery.js +8 -7
  108. package/dist/refresh.d.ts +15 -14
  109. package/dist/refresh.d.ts.map +1 -1
  110. package/dist/refresh.js +113 -56
  111. package/dist/replica.d.ts +56 -38
  112. package/dist/replica.d.ts.map +1 -1
  113. package/dist/replica.js +279 -195
  114. package/dist/room-draft.d.ts +21 -3
  115. package/dist/room-draft.d.ts.map +1 -1
  116. package/dist/room-draft.js +102 -28
  117. package/dist/rows.d.ts +38 -31
  118. package/dist/rows.d.ts.map +1 -1
  119. package/dist/rows.js +173 -101
  120. package/dist/save.d.ts +52 -15
  121. package/dist/save.d.ts.map +1 -1
  122. package/dist/save.js +504 -182
  123. package/dist/search.d.ts +11 -43
  124. package/dist/search.d.ts.map +1 -1
  125. package/dist/search.js +0 -213
  126. package/dist/shared.d.ts +5 -3
  127. package/dist/shared.d.ts.map +1 -1
  128. package/dist/shared.js +72 -35
  129. package/dist/status.d.ts +5 -0
  130. package/dist/status.d.ts.map +1 -1
  131. package/dist/status.js +3 -1
  132. package/dist/store.d.ts +85 -93
  133. package/dist/store.d.ts.map +1 -1
  134. package/dist/store.js +323 -687
  135. package/dist/stored.d.ts +135 -0
  136. package/dist/stored.d.ts.map +1 -0
  137. package/dist/stored.js +568 -0
  138. package/dist/tables.d.ts +352 -0
  139. package/dist/tables.d.ts.map +1 -0
  140. package/dist/tables.js +621 -0
  141. package/dist/turn.d.ts +2 -2
  142. package/dist/turn.d.ts.map +1 -1
  143. package/dist/turn.js +34 -23
  144. package/dist/validation.d.ts +30 -0
  145. package/dist/validation.d.ts.map +1 -0
  146. package/dist/validation.js +162 -0
  147. package/dist/windows.d.ts +2 -6
  148. package/dist/windows.d.ts.map +1 -1
  149. package/dist/windows.js +30 -34
  150. package/dist/wire.d.ts +17 -1
  151. package/dist/wire.d.ts.map +1 -1
  152. package/dist/wire.js +5 -1
  153. package/dist/words.d.ts +19 -0
  154. package/dist/words.d.ts.map +1 -0
  155. package/dist/words.js +156 -0
  156. package/package.json +18 -19
  157. package/AGENTS.md +0 -299
  158. package/dist/chat/acts.d.ts +0 -33
  159. package/dist/chat/acts.d.ts.map +0 -1
  160. package/dist/chat/acts.js +0 -36
  161. package/dist/chat/context.d.ts +0 -3
  162. package/dist/chat/context.d.ts.map +0 -1
  163. package/dist/chat/context.js +0 -10
  164. package/dist/chat/earlier.d.ts +0 -10
  165. package/dist/chat/earlier.d.ts.map +0 -1
  166. package/dist/chat/earlier.js +0 -54
  167. package/dist/chat/input.d.ts +0 -9
  168. package/dist/chat/input.d.ts.map +0 -1
  169. package/dist/chat/input.js +0 -99
  170. package/dist/chat/kit.d.ts +0 -61
  171. package/dist/chat/kit.d.ts.map +0 -1
  172. package/dist/chat/kit.js +0 -123
  173. package/dist/chat/lasting.d.ts +0 -6
  174. package/dist/chat/lasting.d.ts.map +0 -1
  175. package/dist/chat/lasting.js +0 -19
  176. package/dist/chat/list.d.ts +0 -27
  177. package/dist/chat/list.d.ts.map +0 -1
  178. package/dist/chat/list.js +0 -99
  179. package/dist/chat/markdown.d.ts +0 -21
  180. package/dist/chat/markdown.d.ts.map +0 -1
  181. package/dist/chat/markdown.js +0 -246
  182. package/dist/chat/message.d.ts +0 -6
  183. package/dist/chat/message.d.ts.map +0 -1
  184. package/dist/chat/message.js +0 -192
  185. package/dist/chat/messages.d.ts +0 -22
  186. package/dist/chat/messages.d.ts.map +0 -1
  187. package/dist/chat/messages.js +0 -155
  188. package/dist/chat/name.d.ts +0 -6
  189. package/dist/chat/name.d.ts.map +0 -1
  190. package/dist/chat/name.js +0 -37
  191. package/dist/chat/opened.d.ts +0 -11
  192. package/dist/chat/opened.d.ts.map +0 -1
  193. package/dist/chat/opened.js +0 -17
  194. package/dist/chat/overlay.d.ts +0 -31
  195. package/dist/chat/overlay.d.ts.map +0 -1
  196. package/dist/chat/overlay.js +0 -97
  197. package/dist/chat/parts.d.ts +0 -57
  198. package/dist/chat/parts.d.ts.map +0 -1
  199. package/dist/chat/parts.js +0 -119
  200. package/dist/chat/pieces.d.ts +0 -51
  201. package/dist/chat/pieces.d.ts.map +0 -1
  202. package/dist/chat/pieces.js +0 -797
  203. package/dist/chat/process.d.ts +0 -20
  204. package/dist/chat/process.d.ts.map +0 -1
  205. package/dist/chat/process.js +0 -32
  206. package/dist/chat/provider.d.ts +0 -63
  207. package/dist/chat/provider.d.ts.map +0 -1
  208. package/dist/chat/provider.js +0 -628
  209. package/dist/chat/question.d.ts +0 -9
  210. package/dist/chat/question.d.ts.map +0 -1
  211. package/dist/chat/question.js +0 -69
  212. package/dist/chat/questions.d.ts +0 -31
  213. package/dist/chat/questions.d.ts.map +0 -1
  214. package/dist/chat/questions.js +0 -111
  215. package/dist/chat/read.d.ts +0 -5
  216. package/dist/chat/read.d.ts.map +0 -1
  217. package/dist/chat/read.js +0 -13
  218. package/dist/chat/ready.d.ts +0 -34
  219. package/dist/chat/ready.d.ts.map +0 -1
  220. package/dist/chat/ready.js +0 -91
  221. package/dist/chat/style.d.ts +0 -4
  222. package/dist/chat/style.d.ts.map +0 -1
  223. package/dist/chat/style.js +0 -302
  224. package/dist/chat.d.ts +0 -14
  225. package/dist/chat.d.ts.map +0 -1
  226. package/dist/chat.js +0 -8
  227. package/dist/read-side.d.ts +0 -27
  228. package/dist/read-side.d.ts.map +0 -1
  229. package/dist/read-side.js +0 -824
@@ -1,6 +1,6 @@
1
1
  import { conversationChangeSet } from './change-set.js';
2
2
  import { runtimeError } from './failure.js';
3
- import { declaredFile } from './file.js';
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 = ['questions', 'process', 'commands', 'options'];
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' ? { agent, operation } : null;
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 === '' && draft.files.length === 0;
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, files: [...draft.files], revision: draft.revision },
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() || listWatchers.size === 0)
372
+ if (deps.closed())
334
373
  return;
335
- const value = entries();
336
- for (const watcher of listWatchers)
337
- watcher(value);
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
- 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);
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
- emitAgents();
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(removed, changed));
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(changesOf(conversation, [message]), [conversation]));
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 asking = conversations.map((conversation) => ({
605
+ let waiting = conversations.map((conversation) => ({
513
606
  conversation,
514
607
  after: reads.get(conversation) ?? undefined,
515
608
  }));
516
- while (asking.length > 0) {
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
- asking = following;
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(changesOf(conversation, arriving), [conversation]));
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
- void keep(conversation, arriving).catch(() => { });
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([], [from, to]));
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([], [conversation]));
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: '', files: [], revision: chatDraftRevision() }
696
- : { text: current.text, files: current.files, revision: current.revision }),
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 entries();
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 { submission, earlier } = await submitted(conversation, operation, draft);
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: '', files: [], revision: '' }, { operation, ...draft, turn: null }, current?.submitted ?? []));
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.clear();
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
- listWatchers.add(deliver);
1106
+ let ended = false;
981
1107
  void agentsReady().then(() => {
982
- if (!deps.closed() && listWatchers.has(deliver))
983
- deliver(entries());
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
- agentWatchers.add(deliver);
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
  }
@@ -0,0 +1,7 @@
1
+ export type Digest = {
2
+ update(bytes: Uint8Array): void;
3
+ hex(): string;
4
+ };
5
+ export declare function digest(): Digest;
6
+ export declare function sha256(blob: Blob): Promise<string>;
7
+ //# sourceMappingURL=digest.d.ts.map
@@ -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"}