@agentshouse/mdruntime 0.1.0-cab6762661a85 → 0.1.0-cac707d698ca2

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 (112) hide show
  1. package/README.md +1 -1
  2. package/dist/adapter.d.ts +68 -52
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +3 -10
  5. package/dist/attached-model.d.ts.map +1 -1
  6. package/dist/attached-model.js +21 -56
  7. package/dist/bootstrap.d.ts +3 -3
  8. package/dist/bootstrap.d.ts.map +1 -1
  9. package/dist/bootstrap.js +15 -11
  10. package/dist/chain.d.ts +2 -1
  11. package/dist/chain.d.ts.map +1 -1
  12. package/dist/client.d.ts +9 -5
  13. package/dist/client.d.ts.map +1 -1
  14. package/dist/client.js +2 -1
  15. package/dist/collection.d.ts +2 -1
  16. package/dist/collection.d.ts.map +1 -1
  17. package/dist/compile.d.ts +1 -6
  18. package/dist/compile.d.ts.map +1 -1
  19. package/dist/compile.js +90 -277
  20. package/dist/connection.d.ts +8 -7
  21. package/dist/connection.d.ts.map +1 -1
  22. package/dist/connection.js +613 -549
  23. package/dist/context.d.ts +2 -0
  24. package/dist/context.d.ts.map +1 -0
  25. package/dist/context.js +7 -0
  26. package/dist/conversation.d.ts +15 -14
  27. package/dist/conversation.d.ts.map +1 -1
  28. package/dist/conversation.js +136 -164
  29. package/dist/durability.d.ts +6 -0
  30. package/dist/durability.d.ts.map +1 -1
  31. package/dist/entry.d.ts +2 -2
  32. package/dist/entry.d.ts.map +1 -1
  33. package/dist/entry.js +16 -7
  34. package/dist/host.d.ts +3 -6
  35. package/dist/host.d.ts.map +1 -1
  36. package/dist/host.js +16 -23
  37. package/dist/identity.d.ts +0 -1
  38. package/dist/identity.d.ts.map +1 -1
  39. package/dist/identity.js +0 -3
  40. package/dist/index.d.ts +10 -7
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +3 -1
  43. package/dist/job.d.ts +14 -0
  44. package/dist/job.d.ts.map +1 -0
  45. package/dist/job.js +28 -0
  46. package/dist/live.d.ts +2 -1
  47. package/dist/live.d.ts.map +1 -1
  48. package/dist/live.js +10 -7
  49. package/dist/memory.d.ts +10 -4
  50. package/dist/memory.d.ts.map +1 -1
  51. package/dist/memory.js +163 -82
  52. package/dist/messages.d.ts +2 -2
  53. package/dist/messages.d.ts.map +1 -1
  54. package/dist/messages.js +15 -16
  55. package/dist/model.d.ts +2 -7
  56. package/dist/model.d.ts.map +1 -1
  57. package/dist/model.js +0 -3
  58. package/dist/observation.d.ts +2 -2
  59. package/dist/observation.d.ts.map +1 -1
  60. package/dist/observation.js +7 -2
  61. package/dist/query.d.ts +4 -209
  62. package/dist/query.d.ts.map +1 -1
  63. package/dist/query.js +3 -505
  64. package/dist/reach.d.ts +7 -7
  65. package/dist/reach.d.ts.map +1 -1
  66. package/dist/reach.js +33 -44
  67. package/dist/react.d.ts +3 -1
  68. package/dist/react.d.ts.map +1 -1
  69. package/dist/readiness.d.ts +0 -2
  70. package/dist/readiness.d.ts.map +1 -1
  71. package/dist/refresh.d.ts +6 -4
  72. package/dist/refresh.d.ts.map +1 -1
  73. package/dist/refresh.js +28 -4
  74. package/dist/replica.d.ts +8 -5
  75. package/dist/replica.d.ts.map +1 -1
  76. package/dist/replica.js +27 -9
  77. package/dist/room-draft.d.ts +4 -3
  78. package/dist/room-draft.d.ts.map +1 -1
  79. package/dist/room-draft.js +65 -52
  80. package/dist/rows.d.ts +14 -21
  81. package/dist/rows.d.ts.map +1 -1
  82. package/dist/rows.js +48 -184
  83. package/dist/search.d.ts +12 -63
  84. package/dist/search.d.ts.map +1 -1
  85. package/dist/search.js +9 -52
  86. package/dist/store.d.ts +6 -15
  87. package/dist/store.d.ts.map +1 -1
  88. package/dist/store.js +11 -34
  89. package/dist/stored.d.ts +3 -4
  90. package/dist/stored.d.ts.map +1 -1
  91. package/dist/stored.js +66 -122
  92. package/dist/tables.d.ts +8 -23
  93. package/dist/tables.d.ts.map +1 -1
  94. package/dist/tables.js +22 -50
  95. package/dist/validation.d.ts.map +1 -1
  96. package/dist/validation.js +4 -1
  97. package/dist/windows.d.ts +1 -12
  98. package/dist/windows.d.ts.map +1 -1
  99. package/dist/windows.js +2 -75
  100. package/dist/wire.d.ts +9 -4
  101. package/dist/wire.d.ts.map +1 -1
  102. package/dist/wire.js +3 -1
  103. package/package.json +2 -2
  104. package/dist/fulltext.d.ts +0 -27
  105. package/dist/fulltext.d.ts.map +0 -1
  106. package/dist/fulltext.js +0 -370
  107. package/dist/reads.d.ts +0 -11
  108. package/dist/reads.d.ts.map +0 -1
  109. package/dist/reads.js +0 -91
  110. package/dist/words.d.ts +0 -19
  111. package/dist/words.d.ts.map +0 -1
  112. package/dist/words.js +0 -156
@@ -1,10 +1,11 @@
1
+ import { cursorOf, decodedCursor } from '@agentshouse/mdmodel';
1
2
  import { conversationChangeSet } from './change-set.js';
2
3
  import { runtimeError } from './failure.js';
3
4
  import { refusedForSpace } from './durability.js';
4
5
  import { changeBatchIdentity, chatDraftRevision } from './identity.js';
5
6
  import { OFFLINE } from './outcome.js';
6
7
  import { untilAnswered } from './recovery.js';
7
- import { capped, cursorOf, decodedCursor, FROM_START, messageOrder, precedes } from './windows.js';
8
+ import { capped, FROM_START, messageOrder, precedes } from './windows.js';
8
9
  const QUIET = {
9
10
  turn: null,
10
11
  questions: [],
@@ -12,6 +13,7 @@ const QUIET = {
12
13
  commands: [],
13
14
  options: [],
14
15
  starting: null,
16
+ subagents: [],
15
17
  link: null,
16
18
  deliveryUnknown: [],
17
19
  };
@@ -21,6 +23,7 @@ const FACTS = [
21
23
  'commands',
22
24
  'options',
23
25
  'starting',
26
+ 'subagents',
24
27
  'link',
25
28
  'deliveryUnknown',
26
29
  ];
@@ -31,9 +34,11 @@ export function unheldView(conversation) {
31
34
  turn: null,
32
35
  questions: [],
33
36
  process: null,
37
+ processEnded: null,
34
38
  commands: [],
35
39
  options: [],
36
40
  starting: null,
41
+ subagents: [],
37
42
  link: null,
38
43
  deliveryUnknown: [],
39
44
  chatDraft: null,
@@ -48,10 +53,8 @@ export function newChat(agent) {
48
53
  function creationOf(input) {
49
54
  if (typeof input !== 'object' || input === null)
50
55
  return null;
51
- const { agent_id: agent, operation_id: operation, replaces, } = input;
52
- return typeof agent === 'string' && typeof operation === 'string' && replaces === undefined
53
- ? { agent, operation }
54
- : null;
56
+ const { agent_id: agent, operation_id: operation } = input;
57
+ return typeof agent === 'string' && typeof operation === 'string' ? { agent, operation } : null;
55
58
  }
56
59
  function startedTurn(turn, operation) {
57
60
  if (operation.op === 'begin')
@@ -210,7 +213,14 @@ function askedOf(options) {
210
213
  }
211
214
  return { limit: capped(limit), after, before: beforeOf(after), total: total === true };
212
215
  }
213
- const EXPIRED = { kind: 'rejected', code: 'expired', fields: {}, retryable: false };
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
+ }
214
224
  const DURABLE_WRITE = {
215
225
  kind: 'rejected',
216
226
  code: 'durable-write',
@@ -256,6 +266,8 @@ export function createConversationStore(deps) {
256
266
  const unsent = new Map();
257
267
  const views = new Map();
258
268
  const listing = new Map();
269
+ let relisting = null;
270
+ let listCursor = null;
259
271
  const creations = new Set();
260
272
  const listWatchers = new Set();
261
273
  const unlisted = new Set();
@@ -264,11 +276,9 @@ export function createConversationStore(deps) {
264
276
  let listKept = false;
265
277
  const agentWatchers = new Set();
266
278
  const unnamed = new Set();
267
- let agentsKnown = false;
268
- let agentNames = new Map();
269
- let retiredAgents = new Set();
270
- let agentsRead = null;
271
- let agentsFrom;
279
+ let agentsShown = null;
280
+ let listedAgents = null;
281
+ let agentsReading = false;
272
282
  let replicated = new Set();
273
283
  let handedReplicated;
274
284
  function liveOf(conversation) {
@@ -289,9 +299,11 @@ export function createConversationStore(deps) {
289
299
  turn: structuredClone(facts.turn),
290
300
  questions: structuredClone(facts.questions),
291
301
  process: facts.process === null ? null : { ...facts.process },
302
+ processEnded: listing.get(conversation)?.processEnded ?? null,
292
303
  commands: structuredClone(facts.commands),
293
304
  options: structuredClone(facts.options),
294
305
  starting: facts.starting,
306
+ subagents: structuredClone(facts.subagents),
295
307
  link: facts.link === null ? null : { ...facts.link },
296
308
  deliveryUnknown: [...facts.deliveryUnknown],
297
309
  chatDraft: draft === undefined || unwritten(draft)
@@ -347,7 +359,7 @@ export function createConversationStore(deps) {
347
359
  function entries() {
348
360
  return [...listing.values()].map((entry) => ({
349
361
  conversation: entry.conversation,
350
- agent: { identity: entry.agent, name: agentNames.get(entry.agent) ?? null },
362
+ agent: { identity: entry.agent, name: entry.agentName },
351
363
  name: entry.name,
352
364
  created: entry.created,
353
365
  finished: entry.finished,
@@ -366,9 +378,22 @@ export function createConversationStore(deps) {
366
378
  if (deps.closed())
367
379
  return;
368
380
  const entries = [...listing.values()];
369
- void deps.durably((local) => local.fact('conversationList', entries)).catch(() => { });
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(() => { });
370
388
  });
371
389
  }
390
+ function listed(entry) {
391
+ const ended = listing.get(entry.conversation)?.processEnded ?? null;
392
+ listing.set(entry.conversation, { ...entry });
393
+ creations.delete(entry.conversation);
394
+ if (entry.processEnded !== ended)
395
+ emit(entry.conversation);
396
+ }
372
397
  function emitList() {
373
398
  if (deps.closed())
374
399
  return;
@@ -377,18 +402,15 @@ export function createConversationStore(deps) {
377
402
  for (const watcher of listWatchers)
378
403
  watcher(value);
379
404
  }
405
+ emitAgents();
380
406
  learned();
381
407
  }
382
- function unlearnable() {
383
- return !deps.online() || (deps.listed() && deps.agents() === undefined);
384
- }
385
408
  function learned() {
386
409
  if (deps.closed())
387
410
  return;
388
- const named = agentsKnown || unlearnable();
389
- if (unlisted.size > 0 &&
390
- named &&
391
- (listKnown || listHeld || deps.stream() === undefined || unlearnable())) {
411
+ if (!listKnown && !listHeld && deps.stream() !== undefined && deps.online())
412
+ return;
413
+ if (unlisted.size > 0) {
392
414
  const value = entries();
393
415
  for (const watcher of [...unlisted]) {
394
416
  unlisted.delete(watcher);
@@ -396,7 +418,7 @@ export function createConversationStore(deps) {
396
418
  watcher(value);
397
419
  }
398
420
  }
399
- if (unnamed.size > 0 && named) {
421
+ if (unnamed.size > 0) {
400
422
  const value = agents();
401
423
  for (const watcher of [...unnamed]) {
402
424
  unnamed.delete(watcher);
@@ -406,17 +428,44 @@ export function createConversationStore(deps) {
406
428
  }
407
429
  }
408
430
  function agents() {
409
- return [...agentNames]
410
- .filter(([identity]) => !retiredAgents.has(identity))
411
- .map(([identity, name]) => ({ identity, name }))
431
+ const named = new Map();
432
+ for (const agent of listedAgents ?? [])
433
+ named.set(agent.agent, agent);
434
+ for (const entry of listing.values()) {
435
+ named.set(entry.agent, { name: entry.agentName, retired: entry.agentRetired });
436
+ }
437
+ return [...named]
438
+ .filter(([, agent]) => !agent.retired)
439
+ .map(([identity, agent]) => ({ identity, name: agent.name }))
412
440
  .sort((left, right) => left.name === right.name
413
441
  ? left.identity.localeCompare(right.identity)
414
442
  : left.name.localeCompare(right.name));
415
443
  }
444
+ function readAgents() {
445
+ const stream = deps.stream();
446
+ if (stream?.agents === undefined || !deps.online() || agentsReading)
447
+ return;
448
+ agentsReading = true;
449
+ void stream
450
+ .agents()
451
+ .then((read) => {
452
+ if (read === null)
453
+ return;
454
+ listedAgents = read;
455
+ emitAgents();
456
+ }, () => { })
457
+ .finally(() => {
458
+ agentsReading = false;
459
+ });
460
+ }
416
461
  function emitAgents() {
417
462
  if (deps.closed() || agentWatchers.size === 0)
418
463
  return;
419
464
  const value = agents();
465
+ const shown = JSON.stringify(value);
466
+ if (shown === agentsShown)
467
+ return;
468
+ agentsShown = shown;
420
469
  for (const watcher of agentWatchers)
421
470
  watcher(value);
422
471
  }
@@ -432,60 +481,11 @@ export function createConversationStore(deps) {
432
481
  if (stateOf(conversation) !== before || next?.turn?.started !== began)
433
482
  emitList();
434
483
  }
435
- async function readAgents() {
436
- const declaration = deps.agents();
437
- agentsFrom = JSON.stringify(declaration);
438
- if (declaration === undefined)
439
- return;
440
- const names = new Map();
441
- const retired = new Set();
442
- let covered = null;
443
- for (let after;;) {
444
- const read = await deps.documents(declaration, after);
445
- if ('pending' in read)
446
- return;
447
- const coverage = JSON.stringify(read.coverage);
448
- if (covered !== null && coverage !== covered)
449
- return readAgents();
450
- covered = coverage;
451
- for (const document of read.documents) {
452
- const identity = document.fields?.[declaration.identity];
453
- const name = document.fields?.[declaration.name];
454
- if (typeof identity !== 'string' || typeof name !== 'string')
455
- continue;
456
- names.set(identity, name);
457
- const ended = declaration.retired === undefined ? null : document.fields?.[declaration.retired];
458
- if (ended !== undefined && ended !== null)
459
- retired.add(identity);
460
- }
461
- if (read.next === undefined)
462
- break;
463
- after = read.next;
464
- }
465
- agentsKnown = true;
466
- const named = JSON.stringify([...names]) !== JSON.stringify([...agentNames]);
467
- if (!named && JSON.stringify([...retired]) === JSON.stringify([...retiredAgents])) {
468
- learned();
469
- return;
470
- }
471
- agentNames = names;
472
- retiredAgents = retired;
473
- emitAgents();
474
- if (named)
475
- emitList();
476
- learned();
477
- const ended = [...drafts.keys()].filter(retiredChat);
478
- if (ended.length > 0)
479
- await remove(ended);
480
- }
481
484
  function retiredChat(conversation) {
482
- return (conversation.startsWith(NEW_CHAT) && retiredAgents.has(conversation.slice(NEW_CHAT.length)));
483
- }
484
- function agentsReady() {
485
- agentsRead ??= readAgents().catch(() => {
486
- agentsRead = null;
487
- });
488
- return agentsRead;
485
+ if (!conversation.startsWith(NEW_CHAT))
486
+ return false;
487
+ const agent = conversation.slice(NEW_CHAT.length);
488
+ return [...listing.values()].some((entry) => entry.agent === agent && entry.agentRetired);
489
489
  }
490
490
  function live(conversation, change) {
491
491
  const owed = unsent.get(conversation);
@@ -508,6 +508,7 @@ export function createConversationStore(deps) {
508
508
  commands: facts.has('commands') ? QUIET.commands : held.commands,
509
509
  options: facts.has('options') ? QUIET.options : held.options,
510
510
  starting: facts.has('starting') ? QUIET.starting : held.starting,
511
+ subagents: facts.has('subagents') ? QUIET.subagents : held.subagents,
511
512
  link: facts.has('link') ? QUIET.link : held.link,
512
513
  deliveryUnknown: facts.has('deliveryUnknown')
513
514
  ? QUIET.deliveryUnknown
@@ -609,7 +610,7 @@ export function createConversationStore(deps) {
609
610
  }));
610
611
  while (waiting.length > 0) {
611
612
  const asking = waiting.slice(0, HISTORY_CONVERSATIONS);
612
- const result = await deps.call('conversation.history', {
613
+ const result = await deps.history({
613
614
  conversations: asking.map(({ conversation, after }) => ({
614
615
  conversation,
615
616
  ...(after === undefined ? {} : { after }),
@@ -712,6 +713,10 @@ export function createConversationStore(deps) {
712
713
  live(conversation, { starting: event.step });
713
714
  return;
714
715
  }
716
+ if (event.kind === 'subagents') {
717
+ live(conversation, { subagents: structuredClone(event.subagents) });
718
+ return;
719
+ }
715
720
  if (event.kind === 'link') {
716
721
  live(conversation, { link: { connected: event.connected } });
717
722
  return;
@@ -761,7 +766,7 @@ export function createConversationStore(deps) {
761
766
  const from = newChat(agent);
762
767
  return deps.durably(async (local) => {
763
768
  const held = drafts.get(from);
764
- const earlier = (held?.moves ?? []).filter((one) => !deps.expired(one));
769
+ const earlier = held?.moves ?? [];
765
770
  if (earlier.includes(operation))
766
771
  return;
767
772
  const blank = {
@@ -790,10 +795,8 @@ export function createConversationStore(deps) {
790
795
  }
791
796
  async function submitted(conversation, operation, draft) {
792
797
  let submission;
793
- let earlier = false;
794
798
  await withDraft(conversation, (current) => {
795
799
  submission = current?.submitted?.find((one) => one.operation === operation);
796
- earlier = submission !== undefined;
797
800
  if (submission !== undefined)
798
801
  return undefined;
799
802
  const said = draft ?? current;
@@ -806,23 +809,15 @@ export function createConversationStore(deps) {
806
809
  submitted: [...(current?.submitted ?? []), submission],
807
810
  };
808
811
  });
809
- return { submission: submission, earlier };
810
- }
811
- function forgotten(conversation, submission) {
812
- return withDraft(conversation, (current) => {
813
- const held = current?.submitted ?? [];
814
- if (current === undefined || !held.includes(submission))
815
- return undefined;
816
- return withSubmitted(current, held.filter((one) => one !== submission));
817
- });
812
+ return submission;
818
813
  }
819
814
  async function dispatched(conversation, submission) {
820
815
  const dispatch = { answered: false };
821
816
  sending.set(submission.operation, dispatch);
822
817
  try {
823
- const result = await invoke('conversation.send', conversation, {
824
- text: submission.text,
818
+ const result = await invoke('conversations/send', conversation, {
825
819
  operation_id: submission.operation,
820
+ text: submission.text,
826
821
  });
827
822
  dispatch.answered = result.kind !== 'transport-uncertainty';
828
823
  if (result.kind === 'revoked-authorization')
@@ -831,7 +826,7 @@ export function createConversationStore(deps) {
831
826
  deps.unanswered();
832
827
  return result;
833
828
  }
834
- const turn = answered(result, 'turn');
829
+ const turn = answered(result, 'message_id');
835
830
  await withDraft(conversation, async (current, local) => {
836
831
  const held = current?.submitted?.find((one) => one.operation === submission.operation);
837
832
  if (current === undefined || held === undefined || held.turn !== null)
@@ -851,12 +846,11 @@ export function createConversationStore(deps) {
851
846
  sending.delete(submission.operation);
852
847
  }
853
848
  }
854
- function invoke(name, conversation, extra = {}) {
855
- return deps.call(name, { conversation, ...extra });
849
+ function invoke(name, conversation, extra = { operation_id: changeBatchIdentity() }) {
850
+ return deps.call(name, { conversation_id: conversation, ...extra });
856
851
  }
857
852
  const surface = {
858
- async list() {
859
- await agentsReady();
853
+ list() {
860
854
  return new Promise((settle) => {
861
855
  const answer = (listed) => {
862
856
  unlisted.delete(answer);
@@ -868,16 +862,18 @@ export function createConversationStore(deps) {
868
862
  });
869
863
  },
870
864
  async read(conversation, options = {}) {
871
- const asked = askedOf(options);
865
+ const { text, ...windowed } = options;
866
+ const asked = askedOf(windowed);
867
+ const phrase = phraseOf(text);
872
868
  return deps.durably(async (local) => {
873
- const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before);
874
- const total = asked.total ? await local.messageCount(conversation) : null;
869
+ const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before, phrase);
870
+ const total = asked.total ? await local.messageCount(conversation, phrase) : null;
875
871
  return structuredClone(viewOf(conversation, messages, frameOf(asked, messages, more, total)));
876
872
  });
877
873
  },
878
874
  async create(input) {
879
- const result = await deps.call('conversation.create', input);
880
- const conversation = answered(result, 'conversation');
875
+ const result = await deps.call('conversations/create', input);
876
+ const conversation = answered(result, 'conversation_id');
881
877
  if (conversation === null)
882
878
  return result;
883
879
  if (!listing.has(conversation))
@@ -898,11 +894,7 @@ export function createConversationStore(deps) {
898
894
  });
899
895
  if (held === null)
900
896
  return DURABLE_WRITE;
901
- const { submission, earlier } = held;
902
- if (!earlier || !deps.expired(operation))
903
- return dispatched(conversation, submission);
904
- await forgotten(conversation, submission);
905
- return EXPIRED;
897
+ return dispatched(conversation, held);
906
898
  }
907
899
  if (draft !== undefined) {
908
900
  await withDraft(conversation, (current) => current?.submitted?.some((one) => one.operation === operation) === true
@@ -912,28 +904,19 @@ export function createConversationStore(deps) {
912
904
  return OFFLINE;
913
905
  },
914
906
  answer(conversation, answer) {
915
- return invoke('conversation.answer', conversation, { answer });
907
+ return invoke('conversations/interaction/answer', conversation, {
908
+ operation_id: changeBatchIdentity(),
909
+ ...answer,
910
+ });
916
911
  },
917
912
  interrupt(conversation) {
918
- return invoke('conversation.interrupt', conversation);
913
+ return invoke('conversations/interrupt', conversation);
919
914
  },
920
915
  kill(conversation) {
921
- return invoke('conversation.kill', conversation);
922
- },
923
- async cancel(conversation, turn) {
924
- const result = await invoke('conversation.cancel', conversation, { turn });
925
- if (result.kind !== 'action')
926
- return result;
927
- await withDraft(conversation, (current) => {
928
- const held = current?.submitted?.find((one) => one.turn === turn);
929
- if (current === undefined || held === undefined)
930
- return undefined;
931
- return returned(current, held, current.submitted.filter((one) => one !== held));
932
- });
933
- return result;
916
+ return invoke('conversations/kill', conversation);
934
917
  },
935
918
  delete(conversation) {
936
- return invoke('conversation.delete', conversation);
919
+ return invoke('conversations/delete', conversation);
937
920
  },
938
921
  };
939
922
  const chatDraft = {
@@ -962,12 +945,14 @@ export function createConversationStore(deps) {
962
945
  return {
963
946
  surface,
964
947
  chatDraft,
965
- hydrate(held, kept, list) {
948
+ hydrate(held, kept, list, cursor) {
966
949
  if (list !== null && !listKnown) {
967
950
  listing.clear();
968
951
  for (const entry of list)
969
952
  listing.set(entry.conversation, { ...entry });
970
953
  listHeld = true;
954
+ listCursor = cursor;
955
+ deps.stream()?.hold(cursor);
971
956
  }
972
957
  stored.clear();
973
958
  reads.clear();
@@ -1033,10 +1018,6 @@ export function createConversationStore(deps) {
1033
1018
  continue;
1034
1019
  if (deps.closed())
1035
1020
  return;
1036
- if (deps.expired(submission.operation)) {
1037
- await forgotten(conversation, submission);
1038
- continue;
1039
- }
1040
1021
  const result = await dispatched(conversation, submission);
1041
1022
  if (result.kind === 'revoked-authorization')
1042
1023
  return;
@@ -1058,6 +1039,7 @@ export function createConversationStore(deps) {
1058
1039
  return listKnown;
1059
1040
  },
1060
1041
  reopened() {
1042
+ relisting = null;
1061
1043
  for (const [operation, dispatch] of sending)
1062
1044
  if (!dispatch.answered)
1063
1045
  sending.delete(operation);
@@ -1105,56 +1087,50 @@ export function createConversationStore(deps) {
1105
1087
  };
1106
1088
  },
1107
1089
  watchList(deliver) {
1108
- let ended = false;
1109
- void agentsReady().then(() => {
1110
- if (ended)
1111
- return;
1112
- unlisted.add(deliver);
1113
- learned();
1114
- });
1090
+ unlisted.add(deliver);
1091
+ learned();
1115
1092
  return () => {
1116
- ended = true;
1117
1093
  unlisted.delete(deliver);
1118
1094
  listWatchers.delete(deliver);
1119
1095
  };
1120
1096
  },
1121
1097
  watchAgents(deliver) {
1122
1098
  unnamed.add(deliver);
1123
- void agentsReady().then(learned);
1099
+ learned();
1100
+ readAgents();
1124
1101
  return () => {
1125
1102
  unnamed.delete(deliver);
1126
1103
  agentWatchers.delete(deliver);
1127
1104
  };
1128
1105
  },
1129
1106
  learned,
1130
- declared() {
1131
- if (JSON.stringify(deps.agents()) === agentsFrom)
1132
- return;
1133
- agentsRead = readAgents().catch(() => {
1134
- agentsRead = null;
1135
- });
1136
- },
1137
1107
  changed(set) {
1138
1108
  for (const conversation of set.conversations)
1139
1109
  emit(conversation);
1140
- const declaration = deps.agents();
1141
- if (declaration !== undefined &&
1142
- set.documents.some((change) => change.locator === declaration.locator)) {
1143
- agentsRead = readAgents().catch(() => {
1144
- agentsRead = null;
1145
- });
1146
- }
1147
1110
  },
1148
1111
  receive(event) {
1149
1112
  if (deps.closed())
1150
1113
  return false;
1151
1114
  if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
1152
1115
  if (event.kind === 'list') {
1153
- listing.clear();
1116
+ if (event.whole)
1117
+ relisting ??= new Map();
1154
1118
  for (const entry of event.entries) {
1155
- listing.set(entry.conversation, { ...entry });
1156
- creations.delete(entry.conversation);
1119
+ if (relisting === null)
1120
+ listed(entry);
1121
+ else
1122
+ relisting.set(entry.conversation, { ...entry });
1157
1123
  }
1124
+ if (event.more)
1125
+ return false;
1126
+ if (relisting !== null) {
1127
+ listing.clear();
1128
+ for (const entry of relisting.values())
1129
+ listed(entry);
1130
+ relisting = null;
1131
+ }
1132
+ listCursor = event.cursor;
1133
+ deps.stream()?.hold(event.cursor);
1158
1134
  listKnown = true;
1159
1135
  for (const conversation of replicated) {
1160
1136
  if (!listing.has(conversation))
@@ -1167,28 +1143,24 @@ export function createConversationStore(deps) {
1167
1143
  openingEnded();
1168
1144
  }
1169
1145
  else if (event.kind === 'listed') {
1170
- listing.set(event.entry.conversation, { ...event.entry });
1171
- creations.delete(event.entry.conversation);
1146
+ listed(event.entry);
1147
+ relisting?.set(event.entry.conversation, { ...event.entry });
1172
1148
  }
1173
1149
  else {
1174
1150
  listing.delete(event.conversation);
1151
+ relisting?.delete(event.conversation);
1175
1152
  }
1176
1153
  keepList();
1177
1154
  emitList();
1178
- return (event.kind !== 'list' &&
1155
+ return ((event.kind !== 'list' &&
1179
1156
  listKnown &&
1180
1157
  (listing.size !== replicated.size ||
1181
- [...listing.keys()].some((conversation) => !replicated.has(conversation))));
1158
+ [...listing.keys()].some((conversation) => !replicated.has(conversation)))) ||
1159
+ (listKnown && [...drafts.keys()].some(retiredChat)));
1182
1160
  }
1183
1161
  heard(event);
1184
1162
  return false;
1185
1163
  },
1186
- searchable() {
1187
- return [...(listKnown ? listing.keys() : stored)].sort();
1188
- },
1189
- acquired(conversation) {
1190
- return reads.has(conversation) && !partials.has(conversation);
1191
- },
1192
1164
  close() {
1193
1165
  views.clear();
1194
1166
  lives.clear();
@@ -1,10 +1,16 @@
1
1
  import type { Persistence } from './readiness.js';
2
+ export type UnsentKind = 'pending-change' | 'call' | 'room-draft' | 'chat-draft';
3
+ export type UnsentWork = {
4
+ readonly kind: UnsentKind;
5
+ readonly count: number;
6
+ };
2
7
  export type RuntimeShell = {
3
8
  persistence: Persistence;
4
9
  generation: string | null;
5
10
  keepGeneration(value: string): void | Promise<void>;
6
11
  dropGeneration(): void | Promise<void>;
7
12
  cleanUp?(): Promise<number>;
13
+ reset(): Promise<void>;
8
14
  };
9
15
  export declare function refusedForSpace(error: unknown): boolean;
10
16
  export declare function detectStorageLoss(stored: string | null, reported: string | null): string | null;
@@ -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,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,UAAU,GAAG,gBAAgB,GAAG,MAAM,GAAG,YAAY,GAAG,YAAY,CAAC;AAEjF,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,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;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,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
@@ -1,7 +1,7 @@
1
- import type { VerifiedModel } from '@agentshouse/mdmodel';
1
+ import { type VerifiedModel } from '@agentshouse/mdmodel';
2
2
  import { type QueryRows } from './query.js';
3
3
  import type { Connection } from './tables.js';
4
- export { QueryError } from './query.js';
4
+ export { QueryError } from '@agentshouse/mdmodel';
5
5
  export type EntryRoom = {
6
6
  locator: string;
7
7
  schema: string | null;
@@ -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;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,CAmDZ"}
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAGnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,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;AAyCD,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"}