@agentshouse/mdruntime 0.1.0-c1ffd2bc60355 → 0.1.0-c20970f71a6a9

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 (206) hide show
  1. package/README.md +11 -9
  2. package/dist/adapter.d.ts +89 -53
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +2 -1
  5. package/dist/attached-model.d.ts.map +1 -1
  6. package/dist/attached-model.js +28 -4
  7. package/dist/bootstrap.d.ts +10 -13
  8. package/dist/bootstrap.d.ts.map +1 -1
  9. package/dist/bootstrap.js +100 -89
  10. package/dist/client.d.ts +8 -8
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +52 -6
  13. package/dist/collection.d.ts +5 -3
  14. package/dist/collection.d.ts.map +1 -1
  15. package/dist/collection.js +24 -19
  16. package/dist/compile.d.ts +1 -1
  17. package/dist/compile.d.ts.map +1 -1
  18. package/dist/compile.js +113 -45
  19. package/dist/connection.d.ts +8 -7
  20. package/dist/connection.d.ts.map +1 -1
  21. package/dist/connection.js +1311 -1067
  22. package/dist/conversation.d.ts +15 -14
  23. package/dist/conversation.d.ts.map +1 -1
  24. package/dist/conversation.js +222 -140
  25. package/dist/durability.d.ts +0 -1
  26. package/dist/durability.d.ts.map +1 -1
  27. package/dist/entry.d.ts +1 -0
  28. package/dist/entry.d.ts.map +1 -1
  29. package/dist/entry.js +2 -1
  30. package/dist/file.d.ts +2 -11
  31. package/dist/file.d.ts.map +1 -1
  32. package/dist/file.js +6 -4
  33. package/dist/host.d.ts +3 -6
  34. package/dist/host.d.ts.map +1 -1
  35. package/dist/host.js +12 -19
  36. package/dist/index.d.ts +7 -7
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +2 -1
  39. package/dist/media.d.ts +8 -0
  40. package/dist/media.d.ts.map +1 -0
  41. package/dist/media.js +218 -0
  42. package/dist/memory.d.ts +10 -6
  43. package/dist/memory.d.ts.map +1 -1
  44. package/dist/memory.js +178 -90
  45. package/dist/messages.d.ts +2 -2
  46. package/dist/messages.d.ts.map +1 -1
  47. package/dist/messages.js +15 -16
  48. package/dist/model.d.ts +6 -1
  49. package/dist/model.d.ts.map +1 -1
  50. package/dist/model.js +7 -10
  51. package/dist/observation.d.ts +1 -0
  52. package/dist/observation.d.ts.map +1 -1
  53. package/dist/observation.js +1 -1
  54. package/dist/outcome.d.ts +13 -5
  55. package/dist/outcome.d.ts.map +1 -1
  56. package/dist/outcome.js +16 -2
  57. package/dist/paths.d.ts +1 -0
  58. package/dist/paths.d.ts.map +1 -1
  59. package/dist/paths.js +4 -0
  60. package/dist/phrase.d.ts +3 -0
  61. package/dist/phrase.d.ts.map +1 -0
  62. package/dist/phrase.js +8 -0
  63. package/dist/query.d.ts +10 -0
  64. package/dist/query.d.ts.map +1 -1
  65. package/dist/query.js +20 -1
  66. package/dist/reach.d.ts +10 -3
  67. package/dist/reach.d.ts.map +1 -1
  68. package/dist/reach.js +53 -29
  69. package/dist/react.d.ts +1 -0
  70. package/dist/react.d.ts.map +1 -1
  71. package/dist/readiness.d.ts +3 -17
  72. package/dist/readiness.d.ts.map +1 -1
  73. package/dist/readiness.js +4 -10
  74. package/dist/recovery.d.ts +1 -0
  75. package/dist/recovery.d.ts.map +1 -1
  76. package/dist/recovery.js +26 -0
  77. package/dist/refresh.d.ts +7 -5
  78. package/dist/refresh.d.ts.map +1 -1
  79. package/dist/refresh.js +47 -11
  80. package/dist/replica.d.ts +3 -5
  81. package/dist/replica.d.ts.map +1 -1
  82. package/dist/replica.js +7 -7
  83. package/dist/room-draft.d.ts +18 -3
  84. package/dist/room-draft.d.ts.map +1 -1
  85. package/dist/room-draft.js +94 -47
  86. package/dist/rows.d.ts +17 -7
  87. package/dist/rows.d.ts.map +1 -1
  88. package/dist/rows.js +120 -87
  89. package/dist/save.d.ts +2 -0
  90. package/dist/save.d.ts.map +1 -1
  91. package/dist/save.js +11 -5
  92. package/dist/search.d.ts +12 -63
  93. package/dist/search.d.ts.map +1 -1
  94. package/dist/search.js +9 -52
  95. package/dist/shared.d.ts +0 -1
  96. package/dist/shared.d.ts.map +1 -1
  97. package/dist/shared.js +0 -10
  98. package/dist/status.d.ts +4 -3
  99. package/dist/status.d.ts.map +1 -1
  100. package/dist/status.js +3 -1
  101. package/dist/store.d.ts +30 -37
  102. package/dist/store.d.ts.map +1 -1
  103. package/dist/store.js +61 -66
  104. package/dist/stored.d.ts +41 -24
  105. package/dist/stored.d.ts.map +1 -1
  106. package/dist/stored.js +196 -214
  107. package/dist/tables.d.ts +48 -49
  108. package/dist/tables.d.ts.map +1 -1
  109. package/dist/tables.js +23 -62
  110. package/dist/transfer.d.ts +0 -5
  111. package/dist/transfer.d.ts.map +1 -1
  112. package/dist/validation.d.ts +3 -4
  113. package/dist/validation.d.ts.map +1 -1
  114. package/dist/validation.js +35 -96
  115. package/dist/wire.d.ts +9 -8
  116. package/dist/wire.d.ts.map +1 -1
  117. package/dist/wire.js +3 -2
  118. package/package.json +10 -17
  119. package/AGENTS.md +0 -317
  120. package/dist/chat/acts.d.ts +0 -33
  121. package/dist/chat/acts.d.ts.map +0 -1
  122. package/dist/chat/acts.js +0 -36
  123. package/dist/chat/context.d.ts +0 -3
  124. package/dist/chat/context.d.ts.map +0 -1
  125. package/dist/chat/context.js +0 -10
  126. package/dist/chat/earlier.d.ts +0 -10
  127. package/dist/chat/earlier.d.ts.map +0 -1
  128. package/dist/chat/earlier.js +0 -54
  129. package/dist/chat/house.d.ts +0 -25
  130. package/dist/chat/house.d.ts.map +0 -1
  131. package/dist/chat/house.js +0 -38
  132. package/dist/chat/input.d.ts +0 -11
  133. package/dist/chat/input.d.ts.map +0 -1
  134. package/dist/chat/input.js +0 -92
  135. package/dist/chat/kit.d.ts +0 -61
  136. package/dist/chat/kit.d.ts.map +0 -1
  137. package/dist/chat/kit.js +0 -123
  138. package/dist/chat/lasting.d.ts +0 -6
  139. package/dist/chat/lasting.d.ts.map +0 -1
  140. package/dist/chat/lasting.js +0 -19
  141. package/dist/chat/list.d.ts +0 -28
  142. package/dist/chat/list.d.ts.map +0 -1
  143. package/dist/chat/list.js +0 -103
  144. package/dist/chat/markdown.d.ts +0 -20
  145. package/dist/chat/markdown.d.ts.map +0 -1
  146. package/dist/chat/markdown.js +0 -229
  147. package/dist/chat/message.d.ts +0 -7
  148. package/dist/chat/message.d.ts.map +0 -1
  149. package/dist/chat/message.js +0 -254
  150. package/dist/chat/messages.d.ts +0 -35
  151. package/dist/chat/messages.d.ts.map +0 -1
  152. package/dist/chat/messages.js +0 -210
  153. package/dist/chat/name.d.ts +0 -7
  154. package/dist/chat/name.d.ts.map +0 -1
  155. package/dist/chat/name.js +0 -37
  156. package/dist/chat/opened.d.ts +0 -12
  157. package/dist/chat/opened.d.ts.map +0 -1
  158. package/dist/chat/opened.js +0 -19
  159. package/dist/chat/overlay.d.ts +0 -32
  160. package/dist/chat/overlay.d.ts.map +0 -1
  161. package/dist/chat/overlay.js +0 -103
  162. package/dist/chat/parts.d.ts +0 -58
  163. package/dist/chat/parts.d.ts.map +0 -1
  164. package/dist/chat/parts.js +0 -120
  165. package/dist/chat/pieces.d.ts +0 -62
  166. package/dist/chat/pieces.d.ts.map +0 -1
  167. package/dist/chat/pieces.js +0 -1110
  168. package/dist/chat/process.d.ts +0 -20
  169. package/dist/chat/process.d.ts.map +0 -1
  170. package/dist/chat/process.js +0 -32
  171. package/dist/chat/provider.d.ts +0 -70
  172. package/dist/chat/provider.d.ts.map +0 -1
  173. package/dist/chat/provider.js +0 -635
  174. package/dist/chat/question.d.ts +0 -9
  175. package/dist/chat/question.d.ts.map +0 -1
  176. package/dist/chat/question.js +0 -69
  177. package/dist/chat/questions.d.ts +0 -31
  178. package/dist/chat/questions.d.ts.map +0 -1
  179. package/dist/chat/questions.js +0 -111
  180. package/dist/chat/read.d.ts +0 -5
  181. package/dist/chat/read.d.ts.map +0 -1
  182. package/dist/chat/read.js +0 -13
  183. package/dist/chat/ready.d.ts +0 -37
  184. package/dist/chat/ready.d.ts.map +0 -1
  185. package/dist/chat/ready.js +0 -93
  186. package/dist/chat/room-file.d.ts +0 -8
  187. package/dist/chat/room-file.d.ts.map +0 -1
  188. package/dist/chat/room-file.js +0 -72
  189. package/dist/chat/steady.d.ts +0 -3
  190. package/dist/chat/steady.d.ts.map +0 -1
  191. package/dist/chat/steady.js +0 -26
  192. package/dist/chat/style.d.ts +0 -4
  193. package/dist/chat/style.d.ts.map +0 -1
  194. package/dist/chat/style.js +0 -307
  195. package/dist/chat.d.ts +0 -15
  196. package/dist/chat.d.ts.map +0 -1
  197. package/dist/chat.js +0 -8
  198. package/dist/fulltext.d.ts +0 -27
  199. package/dist/fulltext.d.ts.map +0 -1
  200. package/dist/fulltext.js +0 -368
  201. package/dist/reads.d.ts +0 -11
  202. package/dist/reads.d.ts.map +0 -1
  203. package/dist/reads.js +0 -100
  204. package/dist/words.d.ts +0 -19
  205. package/dist/words.d.ts.map +0 -1
  206. package/dist/words.js +0 -150
@@ -1,9 +1,9 @@
1
1
  import { conversationChangeSet } from './change-set.js';
2
2
  import { runtimeError } from './failure.js';
3
3
  import { refusedForSpace } from './durability.js';
4
- import { declaredFile } from './file.js';
5
4
  import { changeBatchIdentity, chatDraftRevision } from './identity.js';
6
5
  import { OFFLINE } from './outcome.js';
6
+ import { untilAnswered } from './recovery.js';
7
7
  import { capped, cursorOf, decodedCursor, FROM_START, messageOrder, precedes } from './windows.js';
8
8
  const QUIET = {
9
9
  turn: null,
@@ -12,6 +12,7 @@ const QUIET = {
12
12
  commands: [],
13
13
  options: [],
14
14
  starting: null,
15
+ subagents: [],
15
16
  link: null,
16
17
  deliveryUnknown: [],
17
18
  };
@@ -21,6 +22,7 @@ const FACTS = [
21
22
  'commands',
22
23
  'options',
23
24
  'starting',
25
+ 'subagents',
24
26
  'link',
25
27
  'deliveryUnknown',
26
28
  ];
@@ -34,6 +36,7 @@ export function unheldView(conversation) {
34
36
  commands: [],
35
37
  options: [],
36
38
  starting: null,
39
+ subagents: [],
37
40
  link: null,
38
41
  deliveryUnknown: [],
39
42
  chatDraft: null,
@@ -210,6 +213,14 @@ function askedOf(options) {
210
213
  }
211
214
  return { limit: capped(limit), after, before: beforeOf(after), total: total === true };
212
215
  }
216
+ function phraseOf(text) {
217
+ if (text === undefined)
218
+ return null;
219
+ if (typeof text !== 'string' || text === '') {
220
+ throw runtimeError('invalid-text', 'a conversation is found by a phrase');
221
+ }
222
+ return text;
223
+ }
213
224
  const EXPIRED = { kind: 'rejected', code: 'expired', fields: {}, retryable: false };
214
225
  const DURABLE_WRITE = {
215
226
  kind: 'rejected',
@@ -256,13 +267,19 @@ export function createConversationStore(deps) {
256
267
  const unsent = new Map();
257
268
  const views = new Map();
258
269
  const listing = new Map();
270
+ let relisting = null;
271
+ let listCursor = null;
259
272
  const creations = new Set();
260
273
  const listWatchers = new Set();
274
+ const unlisted = new Set();
261
275
  let listKnown = false;
276
+ let listHeld = false;
277
+ let listKept = false;
262
278
  const agentWatchers = new Set();
263
- let agentNames = new Map();
264
- let retiredAgents = new Set();
265
- let agentsRead = null;
279
+ const unnamed = new Set();
280
+ let agentsShown = null;
281
+ let listedAgents = null;
282
+ let agentsReading = false;
266
283
  let replicated = new Set();
267
284
  let handedReplicated;
268
285
  function liveOf(conversation) {
@@ -286,6 +303,7 @@ export function createConversationStore(deps) {
286
303
  commands: structuredClone(facts.commands),
287
304
  options: structuredClone(facts.options),
288
305
  starting: facts.starting,
306
+ subagents: structuredClone(facts.subagents),
289
307
  link: facts.link === null ? null : { ...facts.link },
290
308
  deliveryUnknown: [...facts.deliveryUnknown],
291
309
  chatDraft: draft === undefined || unwritten(draft)
@@ -341,7 +359,7 @@ export function createConversationStore(deps) {
341
359
  function entries() {
342
360
  return [...listing.values()].map((entry) => ({
343
361
  conversation: entry.conversation,
344
- agent: { identity: entry.agent, name: agentNames.get(entry.agent) ?? null },
362
+ agent: { identity: entry.agent, name: entry.agentName },
345
363
  name: entry.name,
346
364
  created: entry.created,
347
365
  finished: entry.finished,
@@ -351,25 +369,100 @@ export function createConversationStore(deps) {
351
369
  started: lives.get(entry.conversation)?.turn?.started ?? null,
352
370
  }));
353
371
  }
372
+ function keepList() {
373
+ if (!listKnown || listKept)
374
+ return;
375
+ listKept = true;
376
+ queueMicrotask(() => {
377
+ listKept = false;
378
+ if (deps.closed())
379
+ return;
380
+ const entries = [...listing.values()];
381
+ const cursor = listCursor;
382
+ void deps
383
+ .durably(async (local) => {
384
+ await local.fact('conversationList', entries);
385
+ await local.fact('conversationCursor', cursor);
386
+ })
387
+ .catch(() => { });
388
+ });
389
+ }
390
+ function listed(entry) {
391
+ listing.set(entry.conversation, { ...entry });
392
+ creations.delete(entry.conversation);
393
+ }
354
394
  function emitList() {
355
- if (deps.closed() || listWatchers.size === 0)
395
+ if (deps.closed())
356
396
  return;
357
- const value = entries();
358
- for (const watcher of listWatchers)
359
- watcher(value);
397
+ if (listWatchers.size > 0) {
398
+ const value = entries();
399
+ for (const watcher of listWatchers)
400
+ watcher(value);
401
+ }
402
+ emitAgents();
403
+ learned();
404
+ }
405
+ function learned() {
406
+ if (deps.closed())
407
+ return;
408
+ if (!listKnown && !listHeld && deps.stream() !== undefined && deps.online())
409
+ return;
410
+ if (unlisted.size > 0) {
411
+ const value = entries();
412
+ for (const watcher of [...unlisted]) {
413
+ unlisted.delete(watcher);
414
+ listWatchers.add(watcher);
415
+ watcher(value);
416
+ }
417
+ }
418
+ if (unnamed.size > 0) {
419
+ const value = agents();
420
+ for (const watcher of [...unnamed]) {
421
+ unnamed.delete(watcher);
422
+ agentWatchers.add(watcher);
423
+ watcher(value);
424
+ }
425
+ }
360
426
  }
361
427
  function agents() {
362
- return [...agentNames]
363
- .filter(([identity]) => !retiredAgents.has(identity))
364
- .map(([identity, name]) => ({ identity, name }))
428
+ const named = new Map();
429
+ for (const agent of listedAgents ?? [])
430
+ named.set(agent.agent, agent);
431
+ for (const entry of listing.values()) {
432
+ named.set(entry.agent, { name: entry.agentName, retired: entry.agentRetired });
433
+ }
434
+ return [...named]
435
+ .filter(([, agent]) => !agent.retired)
436
+ .map(([identity, agent]) => ({ identity, name: agent.name }))
365
437
  .sort((left, right) => left.name === right.name
366
438
  ? left.identity.localeCompare(right.identity)
367
439
  : left.name.localeCompare(right.name));
368
440
  }
441
+ function readAgents() {
442
+ const stream = deps.stream();
443
+ if (stream?.agents === undefined || !deps.online() || agentsReading)
444
+ return;
445
+ agentsReading = true;
446
+ void stream
447
+ .agents()
448
+ .then((read) => {
449
+ if (read === null)
450
+ return;
451
+ listedAgents = read;
452
+ emitAgents();
453
+ }, () => { })
454
+ .finally(() => {
455
+ agentsReading = false;
456
+ });
457
+ }
369
458
  function emitAgents() {
370
459
  if (deps.closed() || agentWatchers.size === 0)
371
460
  return;
372
461
  const value = agents();
462
+ const shown = JSON.stringify(value);
463
+ if (shown === agentsShown)
464
+ return;
465
+ agentsShown = shown;
373
466
  for (const watcher of agentWatchers)
374
467
  watcher(value);
375
468
  }
@@ -385,55 +478,11 @@ export function createConversationStore(deps) {
385
478
  if (stateOf(conversation) !== before || next?.turn?.started !== began)
386
479
  emitList();
387
480
  }
388
- async function readAgents() {
389
- const declaration = deps.agents();
390
- if (declaration === undefined)
391
- return;
392
- const names = new Map();
393
- const retired = new Set();
394
- let covered = null;
395
- for (let after;;) {
396
- const read = await deps.documents(declaration, after);
397
- if ('pending' in read)
398
- return;
399
- const coverage = JSON.stringify(read.coverage);
400
- if (covered !== null && coverage !== covered)
401
- return readAgents();
402
- covered = coverage;
403
- for (const document of read.documents) {
404
- const identity = document.fields?.[declaration.identity];
405
- const name = document.fields?.[declaration.name];
406
- if (typeof identity !== 'string' || typeof name !== 'string')
407
- continue;
408
- names.set(identity, name);
409
- const ended = declaration.retired === undefined ? null : document.fields?.[declaration.retired];
410
- if (ended !== undefined && ended !== null)
411
- retired.add(identity);
412
- }
413
- if (read.next === undefined)
414
- break;
415
- after = read.next;
416
- }
417
- const named = JSON.stringify([...names]) !== JSON.stringify([...agentNames]);
418
- if (!named && JSON.stringify([...retired]) === JSON.stringify([...retiredAgents]))
419
- return;
420
- agentNames = names;
421
- retiredAgents = retired;
422
- if (named)
423
- emitList();
424
- emitAgents();
425
- const ended = [...drafts.keys()].filter(retiredChat);
426
- if (ended.length > 0)
427
- await remove(ended);
428
- }
429
481
  function retiredChat(conversation) {
430
- return (conversation.startsWith(NEW_CHAT) && retiredAgents.has(conversation.slice(NEW_CHAT.length)));
431
- }
432
- function agentsReady() {
433
- agentsRead ??= readAgents().catch(() => {
434
- agentsRead = null;
435
- });
436
- return agentsRead;
482
+ if (!conversation.startsWith(NEW_CHAT))
483
+ return false;
484
+ const agent = conversation.slice(NEW_CHAT.length);
485
+ return [...listing.values()].some((entry) => entry.agent === agent && entry.agentRetired);
437
486
  }
438
487
  function live(conversation, change) {
439
488
  const owed = unsent.get(conversation);
@@ -456,6 +505,7 @@ export function createConversationStore(deps) {
456
505
  commands: facts.has('commands') ? QUIET.commands : held.commands,
457
506
  options: facts.has('options') ? QUIET.options : held.options,
458
507
  starting: facts.has('starting') ? QUIET.starting : held.starting,
508
+ subagents: facts.has('subagents') ? QUIET.subagents : held.subagents,
459
509
  link: facts.has('link') ? QUIET.link : held.link,
460
510
  deliveryUnknown: facts.has('deliveryUnknown')
461
511
  ? QUIET.deliveryUnknown
@@ -509,6 +559,20 @@ export function createConversationStore(deps) {
509
559
  deps.publish(conversationChangeSet(changed));
510
560
  });
511
561
  }
562
+ function missed(conversation) {
563
+ const read = reads.get(conversation);
564
+ const newest = listing.get(conversation)?.newest;
565
+ return (read === undefined ||
566
+ newest === undefined ||
567
+ partials.has(conversation) ||
568
+ (newest !== null && (read === null || newest > read)));
569
+ }
570
+ function noted(conversation, message) {
571
+ const entry = listing.get(conversation);
572
+ if (entry === undefined || (entry.newest !== null && entry.newest >= message.position))
573
+ return;
574
+ listing.set(conversation, { ...entry, newest: message.position });
575
+ }
512
576
  function gap(conversation) {
513
577
  gaps.set(conversation, (gaps.get(conversation) ?? 0) + 1);
514
578
  behind.add(conversation);
@@ -543,7 +607,7 @@ export function createConversationStore(deps) {
543
607
  }));
544
608
  while (waiting.length > 0) {
545
609
  const asking = waiting.slice(0, HISTORY_CONVERSATIONS);
546
- const result = await deps.call('conversation.history', {
610
+ const result = await deps.history({
547
611
  conversations: asking.map(({ conversation, after }) => ({
548
612
  conversation,
549
613
  ...(after === undefined ? {} : { after }),
@@ -646,6 +710,10 @@ export function createConversationStore(deps) {
646
710
  live(conversation, { starting: event.step });
647
711
  return;
648
712
  }
713
+ if (event.kind === 'subagents') {
714
+ live(conversation, { subagents: structuredClone(event.subagents) });
715
+ return;
716
+ }
649
717
  if (event.kind === 'link') {
650
718
  live(conversation, { link: { connected: event.connected } });
651
719
  return;
@@ -657,6 +725,7 @@ export function createConversationStore(deps) {
657
725
  const arriving = acceptedMessage(event.message);
658
726
  if (arriving === null)
659
727
  return;
728
+ noted(conversation, arriving);
660
729
  if (replicated.has(conversation)) {
661
730
  if (deps.full()) {
662
731
  gap(conversation);
@@ -750,20 +819,21 @@ export function createConversationStore(deps) {
750
819
  });
751
820
  }
752
821
  async function dispatched(conversation, submission) {
753
- const dispatch = {};
822
+ const dispatch = { answered: false };
754
823
  sending.set(submission.operation, dispatch);
755
824
  try {
756
- const result = await invoke('conversation.send', conversation, {
757
- text: submission.text,
825
+ const result = await invoke('conversations/send', conversation, {
758
826
  operation_id: submission.operation,
827
+ text: submission.text,
759
828
  });
829
+ dispatch.answered = result.kind !== 'transport-uncertainty';
760
830
  if (result.kind === 'revoked-authorization')
761
831
  return result;
762
832
  if (result.kind !== 'action' && result.retryable) {
763
833
  deps.unanswered();
764
834
  return result;
765
835
  }
766
- const turn = answered(result, 'turn');
836
+ const turn = answered(result, 'message_id');
767
837
  await withDraft(conversation, async (current, local) => {
768
838
  const held = current?.submitted?.find((one) => one.operation === submission.operation);
769
839
  if (current === undefined || held === undefined || held.turn !== null)
@@ -783,25 +853,34 @@ export function createConversationStore(deps) {
783
853
  sending.delete(submission.operation);
784
854
  }
785
855
  }
786
- function invoke(name, conversation, extra = {}) {
787
- return deps.call(name, { conversation, ...extra });
856
+ function invoke(name, conversation, extra = { operation_id: changeBatchIdentity() }) {
857
+ return deps.call(name, { conversation_id: conversation, ...extra });
788
858
  }
789
859
  const surface = {
790
- async list() {
791
- await agentsReady();
792
- return entries();
860
+ list() {
861
+ return new Promise((settle) => {
862
+ const answer = (listed) => {
863
+ unlisted.delete(answer);
864
+ listWatchers.delete(answer);
865
+ settle(listed);
866
+ };
867
+ unlisted.add(answer);
868
+ learned();
869
+ });
793
870
  },
794
871
  async read(conversation, options = {}) {
795
- const asked = askedOf(options);
872
+ const { text, ...windowed } = options;
873
+ const asked = askedOf(windowed);
874
+ const phrase = phraseOf(text);
796
875
  return deps.durably(async (local) => {
797
- const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
798
- const total = asked.total ? await local.messageCount(conversation) : null;
876
+ const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before, phrase);
877
+ const total = asked.total ? await local.messageCount(conversation, phrase) : null;
799
878
  return structuredClone(viewOf(conversation, messages, frameOf(asked, messages, more, total)));
800
879
  });
801
880
  },
802
881
  async create(input) {
803
- const result = await deps.call('conversation.create', input);
804
- const conversation = answered(result, 'conversation');
882
+ const result = await deps.call('conversations/create', input);
883
+ const conversation = answered(result, 'conversation_id');
805
884
  if (conversation === null)
806
885
  return result;
807
886
  if (!listing.has(conversation))
@@ -835,38 +914,20 @@ export function createConversationStore(deps) {
835
914
  }
836
915
  return OFFLINE;
837
916
  },
838
- async attach(room, file) {
839
- if (!deps.online())
840
- return OFFLINE;
841
- return deps.call('conversation.attach', {
842
- room,
843
- ...(await declaredFile(file)),
844
- blob: file.blob,
845
- });
846
- },
847
917
  answer(conversation, answer) {
848
- return invoke('conversation.answer', conversation, { answer });
918
+ return invoke('conversations/interaction/answer', conversation, {
919
+ operation_id: changeBatchIdentity(),
920
+ ...answer,
921
+ });
849
922
  },
850
923
  interrupt(conversation) {
851
- return invoke('conversation.interrupt', conversation);
924
+ return invoke('conversations/interrupt', conversation);
852
925
  },
853
926
  kill(conversation) {
854
- return invoke('conversation.kill', conversation);
855
- },
856
- async cancel(conversation, turn) {
857
- const result = await invoke('conversation.cancel', conversation, { turn });
858
- if (result.kind !== 'action')
859
- return result;
860
- await withDraft(conversation, (current) => {
861
- const held = current?.submitted?.find((one) => one.turn === turn);
862
- if (current === undefined || held === undefined)
863
- return undefined;
864
- return returned(current, held, current.submitted.filter((one) => one !== held));
865
- });
866
- return result;
927
+ return invoke('conversations/kill', conversation);
867
928
  },
868
929
  delete(conversation) {
869
- return invoke('conversation.delete', conversation);
930
+ return invoke('conversations/delete', conversation);
870
931
  },
871
932
  };
872
933
  const chatDraft = {
@@ -895,7 +956,15 @@ export function createConversationStore(deps) {
895
956
  return {
896
957
  surface,
897
958
  chatDraft,
898
- hydrate(held, kept) {
959
+ hydrate(held, kept, list, cursor) {
960
+ if (list !== null && !listKnown) {
961
+ listing.clear();
962
+ for (const entry of list)
963
+ listing.set(entry.conversation, { ...entry });
964
+ listHeld = true;
965
+ listCursor = cursor;
966
+ deps.stream()?.hold(cursor);
967
+ }
899
968
  stored.clear();
900
969
  reads.clear();
901
970
  partials.clear();
@@ -909,6 +978,8 @@ export function createConversationStore(deps) {
909
978
  drafts.clear();
910
979
  for (const record of kept)
911
980
  drafts.set(record.conversation, record);
981
+ if (listHeld)
982
+ learned();
912
983
  },
913
984
  async reconcile() {
914
985
  if (!listKnown)
@@ -920,7 +991,7 @@ export function createConversationStore(deps) {
920
991
  !creations.has(conversation) &&
921
992
  (!conversation.startsWith(NEW_CHAT) || retiredChat(conversation)));
922
993
  for (const conversation of named) {
923
- if (!replicated.has(conversation))
994
+ if (!replicated.has(conversation) && missed(conversation))
924
995
  behind.add(conversation);
925
996
  }
926
997
  replicated = named;
@@ -982,12 +1053,11 @@ export function createConversationStore(deps) {
982
1053
  known() {
983
1054
  return listKnown;
984
1055
  },
985
- reconnected() {
986
- for (const conversation of replicated)
987
- gap(conversation);
988
- },
989
1056
  reopened() {
990
- sending.clear();
1057
+ relisting = null;
1058
+ for (const [operation, dispatch] of sending)
1059
+ if (!dispatch.answered)
1060
+ sending.delete(operation);
991
1061
  },
992
1062
  lost() {
993
1063
  catching.clear();
@@ -1006,15 +1076,15 @@ export function createConversationStore(deps) {
1006
1076
  views.set(key, view);
1007
1077
  const watcher = { notify: deliver, ready: false };
1008
1078
  view.watchers.add(watcher);
1009
- void deps
1010
- .durably(async (local) => {
1079
+ const reading = new AbortController();
1080
+ void untilAnswered(() => deps.durably(async (local) => {
1011
1081
  if (view.window !== null)
1012
1082
  return;
1013
1083
  const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
1014
1084
  view.window = messages;
1015
1085
  view.more = more;
1016
1086
  view.total = asked.total ? await local.messageCount(conversation) : null;
1017
- })
1087
+ }), reading.signal)
1018
1088
  .then(() => {
1019
1089
  if (deps.closed() || !view.watchers.has(watcher))
1020
1090
  return;
@@ -1024,6 +1094,7 @@ export function createConversationStore(deps) {
1024
1094
  })
1025
1095
  .catch(() => { });
1026
1096
  return () => {
1097
+ reading.abort();
1027
1098
  if (!view.watchers.delete(watcher))
1028
1099
  return;
1029
1100
  if (view.watchers.size === 0)
@@ -1031,77 +1102,88 @@ export function createConversationStore(deps) {
1031
1102
  };
1032
1103
  },
1033
1104
  watchList(deliver) {
1034
- listWatchers.add(deliver);
1035
- void agentsReady().then(() => {
1036
- if (!deps.closed() && listWatchers.has(deliver))
1037
- deliver(entries());
1038
- });
1105
+ unlisted.add(deliver);
1106
+ learned();
1039
1107
  return () => {
1108
+ unlisted.delete(deliver);
1040
1109
  listWatchers.delete(deliver);
1041
1110
  };
1042
1111
  },
1043
1112
  watchAgents(deliver) {
1044
- agentWatchers.add(deliver);
1045
- void agentsReady().then(() => {
1046
- if (!deps.closed() && agentWatchers.has(deliver))
1047
- deliver(agents());
1048
- });
1113
+ unnamed.add(deliver);
1114
+ learned();
1115
+ readAgents();
1049
1116
  return () => {
1117
+ unnamed.delete(deliver);
1050
1118
  agentWatchers.delete(deliver);
1051
1119
  };
1052
1120
  },
1121
+ learned,
1053
1122
  changed(set) {
1054
1123
  for (const conversation of set.conversations)
1055
1124
  emit(conversation);
1056
- const declaration = deps.agents();
1057
- if (declaration !== undefined &&
1058
- set.documents.some((change) => change.locator === declaration.locator)) {
1059
- agentsRead = readAgents().catch(() => {
1060
- agentsRead = null;
1061
- });
1062
- }
1063
1125
  },
1064
1126
  receive(event) {
1065
1127
  if (deps.closed())
1066
1128
  return false;
1067
1129
  if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
1068
1130
  if (event.kind === 'list') {
1069
- listing.clear();
1131
+ if (event.whole)
1132
+ relisting ??= new Map();
1070
1133
  for (const entry of event.entries) {
1071
- listing.set(entry.conversation, { ...entry });
1072
- creations.delete(entry.conversation);
1134
+ if (relisting === null)
1135
+ listed(entry);
1136
+ else
1137
+ relisting.set(entry.conversation, { ...entry });
1073
1138
  }
1139
+ if (event.more)
1140
+ return false;
1141
+ if (relisting !== null) {
1142
+ listing.clear();
1143
+ for (const entry of relisting.values())
1144
+ listed(entry);
1145
+ relisting = null;
1146
+ }
1147
+ listCursor = event.cursor;
1148
+ deps.stream()?.hold(event.cursor);
1074
1149
  listKnown = true;
1150
+ for (const conversation of replicated) {
1151
+ if (!listing.has(conversation))
1152
+ continue;
1153
+ if (!missed(conversation))
1154
+ behind.delete(conversation);
1155
+ else if (!behind.has(conversation))
1156
+ gap(conversation);
1157
+ }
1075
1158
  openingEnded();
1076
1159
  }
1077
1160
  else if (event.kind === 'listed') {
1078
- listing.set(event.entry.conversation, { ...event.entry });
1079
- creations.delete(event.entry.conversation);
1161
+ listed(event.entry);
1162
+ relisting?.set(event.entry.conversation, { ...event.entry });
1080
1163
  }
1081
1164
  else {
1082
1165
  listing.delete(event.conversation);
1166
+ relisting?.delete(event.conversation);
1083
1167
  }
1168
+ keepList();
1084
1169
  emitList();
1085
- return (event.kind !== 'list' &&
1170
+ return ((event.kind !== 'list' &&
1086
1171
  listKnown &&
1087
1172
  (listing.size !== replicated.size ||
1088
- [...listing.keys()].some((conversation) => !replicated.has(conversation))));
1173
+ [...listing.keys()].some((conversation) => !replicated.has(conversation)))) ||
1174
+ (listKnown && [...drafts.keys()].some(retiredChat)));
1089
1175
  }
1090
1176
  heard(event);
1091
1177
  return false;
1092
1178
  },
1093
- searchable() {
1094
- return [...(listKnown ? listing.keys() : stored)].sort();
1095
- },
1096
- acquired(conversation) {
1097
- return reads.has(conversation) && !partials.has(conversation);
1098
- },
1099
1179
  close() {
1100
1180
  views.clear();
1101
1181
  lives.clear();
1102
1182
  unsent.clear();
1103
1183
  listWatchers.clear();
1184
+ unlisted.clear();
1104
1185
  agentWatchers.clear();
1186
+ unnamed.clear();
1105
1187
  },
1106
1188
  };
1107
1189
  }
@@ -2,7 +2,6 @@ import type { Persistence } from './readiness.js';
2
2
  export type RuntimeShell = {
3
3
  persistence: Persistence;
4
4
  generation: string | null;
5
- onScreen: boolean;
6
5
  keepGeneration(value: string): void | Promise<void>;
7
6
  dropGeneration(): void | Promise<void>;
8
7
  cleanUp?(): Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"durability.d.ts","sourceRoot":"","sources":["../src/durability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG/F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGrF"}
1
+ {"version":3,"file":"durability.d.ts","sourceRoot":"","sources":["../src/durability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG/F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGrF"}
package/dist/entry.d.ts CHANGED
@@ -6,6 +6,7 @@ export type EntryRoom = {
6
6
  locator: string;
7
7
  schema: string | null;
8
8
  documents: Readonly<Record<string, string>>;
9
+ revisions?: Readonly<Record<string, string>>;
9
10
  };
10
11
  export type EntryArguments = Readonly<Record<string, string>>;
11
12
  export type EntryParameterKind = 'string' | 'integer' | 'number' | 'boolean';
@@ -1 +1 @@
1
- {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK1D,OAAO,EAML,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AA0D7E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAE3E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAMpE;AAkCD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ7D;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CACzF,CAAC;AAEF,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,UAAU,GACrB,UAAU,CAmDZ"}
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK1D,OAAO,EAML,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AA0D7E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAE3E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAMpE;AAkCD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ7D;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CACzF,CAAC;AAEF,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,UAAU,GACrB,UAAU,CAoDZ"}
package/dist/entry.js CHANGED
@@ -129,8 +129,9 @@ export function entryScope(rooms, roomTypes, connection) {
129
129
  .map((path) => ({
130
130
  path,
131
131
  content: room.documents[path],
132
+ outline: null,
132
133
  binary: null,
133
- revision: null,
134
+ revision: room.revisions?.[path] ?? null,
134
135
  fileId: null,
135
136
  change: null,
136
137
  written: null,
package/dist/file.d.ts CHANGED
@@ -1,12 +1,3 @@
1
- export type ChosenFile = {
2
- name: string;
3
- blob: Blob;
4
- };
5
- export type FileDeclaration = {
6
- name: string;
7
- mediaType: string;
8
- byteLength: number;
9
- contentHash: string;
10
- };
11
- export declare function declaredFile(file: ChosenFile): Promise<FileDeclaration>;
1
+ import type { AttachRequest } from './adapter.js';
2
+ export declare function attachedFile(locator: string, file: File): Promise<AttachRequest>;
12
3
  //# sourceMappingURL=file.d.ts.map