@agentshouse/mdruntime 0.1.0-c2af3ddcc243b → 0.1.0-c2e433921a4d5

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 (172) hide show
  1. package/README.md +14 -13
  2. package/dist/acceptance.js +1 -1
  3. package/dist/adapter.d.ts +55 -9
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/attached-model.d.ts +0 -1
  6. package/dist/attached-model.d.ts.map +1 -1
  7. package/dist/attached-model.js +0 -5
  8. package/dist/authored.d.ts +88 -0
  9. package/dist/authored.d.ts.map +1 -0
  10. package/dist/authored.js +345 -0
  11. package/dist/change.d.ts +4 -0
  12. package/dist/change.d.ts.map +1 -1
  13. package/dist/change.js +3 -0
  14. package/dist/chat-types.d.ts +0 -2
  15. package/dist/chat-types.d.ts.map +1 -1
  16. package/dist/chat-types.js +0 -2
  17. package/dist/client.d.ts +5 -3
  18. package/dist/client.d.ts.map +1 -1
  19. package/dist/client.js +4 -7
  20. package/dist/collection.d.ts +4 -1
  21. package/dist/collection.d.ts.map +1 -1
  22. package/dist/collection.js +7 -0
  23. package/dist/column.d.ts +5 -0
  24. package/dist/column.d.ts.map +1 -0
  25. package/dist/column.js +9 -0
  26. package/dist/compile.d.ts.map +1 -1
  27. package/dist/compile.js +2 -3
  28. package/dist/connection.d.ts.map +1 -1
  29. package/dist/connection.js +6 -4
  30. package/dist/context.d.ts.map +1 -1
  31. package/dist/context.js +1 -1
  32. package/dist/conversation-live.d.ts +16 -6
  33. package/dist/conversation-live.d.ts.map +1 -1
  34. package/dist/conversation-live.js +15 -6
  35. package/dist/conversation-row.d.ts +8 -1
  36. package/dist/conversation-row.d.ts.map +1 -1
  37. package/dist/conversation-row.js +20 -7
  38. package/dist/conversation.d.ts +9 -5
  39. package/dist/conversation.d.ts.map +1 -1
  40. package/dist/conversation.js +155 -123
  41. package/dist/figures.d.ts.map +1 -1
  42. package/dist/figures.js +4 -2
  43. package/dist/file.d.ts.map +1 -1
  44. package/dist/file.js +2 -1
  45. package/dist/host.d.ts +1 -0
  46. package/dist/host.d.ts.map +1 -1
  47. package/dist/host.js +14 -8
  48. package/dist/index.d.ts +4 -3
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +2 -1
  51. package/dist/install.d.ts +8 -2
  52. package/dist/install.d.ts.map +1 -1
  53. package/dist/install.js +40 -33
  54. package/dist/lifecycle.d.ts.map +1 -1
  55. package/dist/lifecycle.js +15 -10
  56. package/dist/listing.d.ts +7 -3
  57. package/dist/listing.d.ts.map +1 -1
  58. package/dist/listing.js +26 -13
  59. package/dist/live.d.ts +5 -3
  60. package/dist/live.d.ts.map +1 -1
  61. package/dist/live.js +71 -30
  62. package/dist/loaded.d.ts +5 -0
  63. package/dist/loaded.d.ts.map +1 -0
  64. package/dist/loaded.js +40 -0
  65. package/dist/locks.d.ts.map +1 -1
  66. package/dist/locks.js +2 -2
  67. package/dist/lost.js +1 -1
  68. package/dist/media.d.ts +5 -0
  69. package/dist/media.d.ts.map +1 -1
  70. package/dist/media.js +65 -14
  71. package/dist/memory.d.ts +3 -1
  72. package/dist/memory.d.ts.map +1 -1
  73. package/dist/memory.js +17 -8
  74. package/dist/messages.d.ts +3 -1
  75. package/dist/messages.d.ts.map +1 -1
  76. package/dist/messages.js +5 -3
  77. package/dist/models.d.ts.map +1 -1
  78. package/dist/models.js +3 -3
  79. package/dist/observation.d.ts +27 -12
  80. package/dist/observation.d.ts.map +1 -1
  81. package/dist/observation.js +173 -69
  82. package/dist/outcome.d.ts +4 -0
  83. package/dist/outcome.d.ts.map +1 -1
  84. package/dist/outcome.js +8 -2
  85. package/dist/overlay.d.ts +1 -1
  86. package/dist/overlay.d.ts.map +1 -1
  87. package/dist/overlay.js +3 -5
  88. package/dist/preparation.d.ts +27 -6
  89. package/dist/preparation.d.ts.map +1 -1
  90. package/dist/preparation.js +131 -44
  91. package/dist/presence.d.ts +8 -2
  92. package/dist/presence.d.ts.map +1 -1
  93. package/dist/presence.js +24 -13
  94. package/dist/queries.d.ts +1 -1
  95. package/dist/queries.d.ts.map +1 -1
  96. package/dist/queries.js +43 -17
  97. package/dist/questions.d.ts +1 -0
  98. package/dist/questions.d.ts.map +1 -1
  99. package/dist/questions.js +1 -0
  100. package/dist/queue.d.ts.map +1 -1
  101. package/dist/queue.js +51 -21
  102. package/dist/reach.d.ts +2 -3
  103. package/dist/reach.d.ts.map +1 -1
  104. package/dist/reach.js +20 -7
  105. package/dist/react.d.ts +3 -1
  106. package/dist/react.d.ts.map +1 -1
  107. package/dist/readiness.d.ts +8 -2
  108. package/dist/readiness.d.ts.map +1 -1
  109. package/dist/readiness.js +3 -5
  110. package/dist/reads.d.ts +1 -1
  111. package/dist/reads.d.ts.map +1 -1
  112. package/dist/reads.js +2 -2
  113. package/dist/replica.d.ts.map +1 -1
  114. package/dist/replica.js +2 -2
  115. package/dist/room-draft.d.ts +28 -3
  116. package/dist/room-draft.d.ts.map +1 -1
  117. package/dist/room-draft.js +230 -12
  118. package/dist/room-drafts.d.ts.map +1 -1
  119. package/dist/room-drafts.js +5 -2
  120. package/dist/room-list.d.ts +10 -0
  121. package/dist/room-list.d.ts.map +1 -0
  122. package/dist/room-list.js +45 -0
  123. package/dist/rows.d.ts +2 -1
  124. package/dist/rows.d.ts.map +1 -1
  125. package/dist/rows.js +6 -6
  126. package/dist/save.d.ts.map +1 -1
  127. package/dist/save.js +17 -86
  128. package/dist/saves.d.ts.map +1 -1
  129. package/dist/saves.js +23 -7
  130. package/dist/seed.d.ts.map +1 -1
  131. package/dist/seed.js +2 -2
  132. package/dist/shown.d.ts +1 -1
  133. package/dist/shown.d.ts.map +1 -1
  134. package/dist/shown.js +51 -37
  135. package/dist/source.d.ts +5 -0
  136. package/dist/source.d.ts.map +1 -1
  137. package/dist/source.js +13 -2
  138. package/dist/store/installs.d.ts +2 -2
  139. package/dist/store/installs.d.ts.map +1 -1
  140. package/dist/store/installs.js +10 -4
  141. package/dist/store/readiness.d.ts +5 -4
  142. package/dist/store/readiness.d.ts.map +1 -1
  143. package/dist/store/readiness.js +28 -12
  144. package/dist/store/records.d.ts +10 -1
  145. package/dist/store/records.d.ts.map +1 -1
  146. package/dist/store/records.js +46 -19
  147. package/dist/store/rooms-shown.d.ts +8 -0
  148. package/dist/store/rooms-shown.d.ts.map +1 -0
  149. package/dist/store/rooms-shown.js +13 -0
  150. package/dist/store.d.ts +12 -8
  151. package/dist/store.d.ts.map +1 -1
  152. package/dist/store.js +8 -4
  153. package/dist/stored.d.ts +23 -13
  154. package/dist/stored.d.ts.map +1 -1
  155. package/dist/stored.js +73 -22
  156. package/dist/surface.d.ts +4 -2
  157. package/dist/surface.d.ts.map +1 -1
  158. package/dist/surface.js +7 -2
  159. package/dist/sync.d.ts +1 -1
  160. package/dist/sync.d.ts.map +1 -1
  161. package/dist/sync.js +8 -7
  162. package/dist/tables.d.ts +10 -49
  163. package/dist/tables.d.ts.map +1 -1
  164. package/dist/tables.js +60 -322
  165. package/dist/tallies.d.ts.map +1 -1
  166. package/dist/tallies.js +1 -2
  167. package/dist/validation.d.ts.map +1 -1
  168. package/dist/validation.js +3 -9
  169. package/dist/wire.d.ts +2 -8
  170. package/dist/wire.d.ts.map +1 -1
  171. package/dist/wire.js +2 -2
  172. package/package.json +2 -2
@@ -30,12 +30,12 @@ export function unheldView(conversation) {
30
30
  deliveryUnknown: [],
31
31
  chatDraft: null,
32
32
  dismissedSuggestion: null,
33
+ pins: [],
33
34
  };
34
35
  }
35
36
  export const SESSION_STARTED = 'Session started';
36
37
  const NEW_CHAT = 'new:';
37
38
  const LISTING = 'listing';
38
- const AGENTS = 'agents';
39
39
  export const CATCHING_UP = 'catching-up';
40
40
  export const HISTORY_CONVERSATIONS = 64;
41
41
  export function newChat(agent) {
@@ -209,7 +209,7 @@ function returned(draft, submission, others) {
209
209
  revision: chatDraftRevision(),
210
210
  }, others);
211
211
  }
212
- function viewOf(alive, conversation, held, frame, draft, ended, dismissed) {
212
+ function viewOf(alive, conversation, held, frame, { draft, ended, dismissed, pins }) {
213
213
  const facts = alive.liveOf(conversation);
214
214
  return {
215
215
  conversation,
@@ -233,6 +233,7 @@ function viewOf(alive, conversation, held, frame, draft, ended, dismissed) {
233
233
  deliveryUnknown: [...facts.deliveryUnknown],
234
234
  chatDraft: draft === null || unwritten(draft) ? null : { text: draft.text, revision: draft.revision },
235
235
  dismissedSuggestion: dismissed,
236
+ pins: [...pins],
236
237
  };
237
238
  }
238
239
  function sessionOf(facts, held, ended) {
@@ -252,14 +253,15 @@ function emit(alive, conversation) {
252
253
  if (alive.deps.closed())
253
254
  return;
254
255
  for (const view of alive.views()) {
255
- const { window, draft, ended, dismissed } = view.held.now();
256
+ const held = view.held.now();
257
+ const { window } = held;
256
258
  if (view.conversation !== conversation || window === null)
257
259
  continue;
258
260
  const ready = view.ready();
259
261
  if (ready.length === 0)
260
262
  continue;
261
263
  const frame = sharedFrame(view, window);
262
- const value = viewOf(alive, conversation, window, frame, draft, ended, dismissed);
264
+ const value = viewOf(alive, conversation, window, frame, held);
263
265
  for (const watcher of ready)
264
266
  watcher.notify(value);
265
267
  }
@@ -305,66 +307,90 @@ function rowOf(alive, conversation) {
305
307
  };
306
308
  }
307
309
  async function entries(alive) {
308
- const list = await heldList(alive);
309
- if (list === null)
310
+ const listing = await heldListing(alive);
311
+ if (listing === null)
312
+ return null;
313
+ const list = listing.conversations;
314
+ const agents = new Map(listing.agents.map((agent) => [agent.id, agent]));
315
+ if (list.some((entry) => !agents.has(entry.agent)))
310
316
  return null;
311
317
  const held = list.length === 0
312
318
  ? []
313
319
  : await alive.deps.durably((local) => local.conversationRows(list.map(({ conversation }) => conversation)));
314
320
  const rows = new Map(held.map((one) => [one.conversation, one]));
315
- return list.map((entry) => ({
316
- conversation: entry.conversation,
317
- agent: { identity: entry.agent, name: entry.agentName, retired: entry.agentRetired },
318
- name: entry.name,
319
- created: entry.created,
320
- finished: entry.finished,
321
- outcome: entry.outcome,
322
- waiting: entry.waiting,
323
- ...rowOf(alive, entry.conversation),
324
- ...heldFacts(rows.get(entry.conversation), entry),
325
- }));
321
+ return list.map((entry) => {
322
+ const agent = agents.get(entry.agent);
323
+ return {
324
+ conversation: entry.conversation,
325
+ agent: { identity: agent.id, name: agent.name, retired: agent.retired_at !== null },
326
+ name: entry.name,
327
+ created: entry.created,
328
+ finished: entry.finished,
329
+ outcome: entry.outcome,
330
+ waiting: entry.waiting,
331
+ subject: entry.subject,
332
+ ...rowOf(alive, entry.conversation),
333
+ ...heldFacts(rows.get(entry.conversation), entry),
334
+ };
335
+ });
326
336
  }
327
- async function heldList(alive) {
328
- const stored = (await (await alive.deps.local()).facts()).conversationList;
329
- if (stored !== null)
330
- return stored;
331
- return !alive.known() && alive.deps.stream() !== undefined && alive.deps.online() ? null : [];
337
+ async function heldListing(alive) {
338
+ const { conversationList, agentList } = await (await alive.deps.local()).facts();
339
+ if (conversationList !== null && agentList !== null)
340
+ return { conversations: conversationList, agents: agentList };
341
+ return !alive.known() && alive.deps.stream() !== undefined && alive.deps.online()
342
+ ? null
343
+ : { conversations: [], agents: [] };
332
344
  }
333
345
  async function endedIn(alive, conversation) {
334
- const list = await heldList(alive);
335
- return list?.find((entry) => entry.conversation === conversation)?.processEnded ?? null;
346
+ const listing = await heldListing(alive);
347
+ return (listing?.conversations.find((entry) => entry.conversation === conversation)?.processEnded ??
348
+ null);
349
+ }
350
+ function upserted(kept, set, key) {
351
+ const held = new Map(kept.map((one) => [key(one), one]));
352
+ for (const one of set)
353
+ held.set(key(one), { ...one });
354
+ return held;
336
355
  }
337
356
  function listChanged(alive, change) {
338
357
  void alive.deps
339
358
  .durably(async (local) => {
340
- const { conversationList, conversationCursor } = await local.facts();
341
- const kept = change.replacing ? [] : (conversationList ?? []);
342
- const held = new Map(kept.map((entry) => [entry.conversation, entry]));
343
- for (const entry of change.set) {
344
- held.set(entry.conversation, { ...entry });
359
+ const { conversationList, agentList, conversationCursor } = await local.facts();
360
+ const held = upserted(change.replacing ? [] : (conversationList ?? []), change.set, (entry) => entry.conversation);
361
+ for (const entry of change.set)
345
362
  alive.created(entry.conversation);
346
- }
347
363
  if (change.gone !== null)
348
364
  held.delete(change.gone);
349
365
  const list = [...held.values()];
366
+ const agents = [
367
+ ...upserted(change.replacing ? [] : (agentList ?? []), change.agents, (agent) => agent.id).values(),
368
+ ];
350
369
  if (JSON.stringify(list) !== JSON.stringify(conversationList)) {
351
370
  await local.fact('conversationList', list);
352
371
  }
372
+ if (JSON.stringify(agents) !== JSON.stringify(agentList)) {
373
+ await local.fact('agentList', agents);
374
+ }
353
375
  if (change.cursor !== undefined) {
354
376
  if (change.cursor !== conversationCursor) {
355
377
  await local.fact('conversationCursor', change.cursor);
356
378
  }
357
379
  alive.deps.stream()?.hold(change.cursor);
358
380
  }
359
- return list;
381
+ return { conversations: list, agents };
382
+ })
383
+ .catch(async () => {
384
+ const { conversationList, agentList } = await (await alive.deps.local()).facts();
385
+ return { conversations: conversationList ?? [], agents: agentList ?? [] };
360
386
  })
361
- .catch(async () => (await (await alive.deps.local()).facts()).conversationList ?? [])
362
- .then((list) => {
387
+ .then((listing) => {
363
388
  if (alive.deps.closed() || change.paged === true)
364
389
  return;
390
+ const list = listing.conversations;
365
391
  endedAnew(alive, list);
366
392
  if (change.cursor !== undefined) {
367
- alive.held.set({ listKnown: true });
393
+ alive.held.set({ listKnown: true, openingListed: true });
368
394
  settleBehind(alive, list);
369
395
  openingEnded(alive);
370
396
  alive.deps.settled();
@@ -372,11 +398,12 @@ function listChanged(alive, change) {
372
398
  emitList(alive);
373
399
  if (!alive.known())
374
400
  return;
375
- retiredDrafts(alive, list);
376
- const { replicated } = alive.held.now();
377
- if (change.cursor === undefined &&
378
- (list.length !== replicated.size ||
379
- list.some(({ conversation }) => !replicated.has(conversation)))) {
401
+ retiredDrafts(alive, listing);
402
+ const { replicated, openingRead } = alive.held.now();
403
+ if (change.cursor === undefined
404
+ ? list.length !== replicated.size ||
405
+ list.some(({ conversation }) => !replicated.has(conversation))
406
+ : openingRead) {
380
407
  alive.deps.again();
381
408
  }
382
409
  }, uncaught);
@@ -392,16 +419,16 @@ function endedAnew(alive, list) {
392
419
  emit(alive, view.conversation);
393
420
  }
394
421
  }
395
- function shownList(alive, work) {
396
- const reading = heldList(alive);
422
+ function shownListing(alive, work) {
423
+ const reading = heldListing(alive);
397
424
  alive.inOrder(async () => {
398
- const list = await reading.catch((error) => {
425
+ const listing = await reading.catch((error) => {
399
426
  uncaught(error);
400
427
  return null;
401
428
  });
402
- if (list === null || alive.deps.closed())
429
+ if (listing === null || alive.deps.closed())
403
430
  return;
404
- work(list);
431
+ work(listing);
405
432
  });
406
433
  }
407
434
  async function told(alive) {
@@ -446,66 +473,48 @@ export function conversationsLearned(alive) {
446
473
  return;
447
474
  if (alive.listeners.waiting())
448
475
  tellList(alive);
449
- if (!alive.agentListeners.waiting())
476
+ if (!alive.agentListeners.waiting() && !alive.listedListeners.waiting())
450
477
  return;
451
- shownList(alive, (list) => alive.agentListeners.welcome(agents(alive, list)));
478
+ shownListing(alive, (listing) => {
479
+ alive.agentListeners.welcome(agentsOf(listing));
480
+ alive.listedListeners.welcome(structuredClone(listing.agents));
481
+ });
452
482
  }
453
- function agents(alive, list) {
454
- const read = new Map((alive.held.now().listedAgents ?? []).map((one) => [one.agent, one]));
455
- const named = new Map(read);
456
- for (const entry of list) {
457
- named.set(entry.agent, { name: entry.agentName, retired: entry.agentRetired });
458
- }
459
- return [...named]
460
- .filter(([, agent]) => !agent.retired)
461
- .map(([identity, agent]) => {
462
- const held = read.get(identity);
463
- return held === undefined
464
- ? { identity, name: agent.name }
465
- : {
466
- identity,
467
- name: agent.name,
468
- cli: held.cli,
469
- environment: structuredClone(held.environment),
470
- };
471
- })
483
+ function agentsOf(listing) {
484
+ return listing.agents
485
+ .filter((agent) => agent.retired_at === null)
486
+ .map((agent) => ({
487
+ identity: agent.id,
488
+ name: agent.name,
489
+ cli: agent.cli,
490
+ model: agent.model,
491
+ effort: agent.effort,
492
+ environment: {
493
+ identity: agent.environment,
494
+ name: agent.environment_name,
495
+ state: agent.environment_connected ? 'online' : 'offline',
496
+ },
497
+ }))
472
498
  .sort((left, right) => left.name === right.name
473
499
  ? left.identity.localeCompare(right.identity)
474
500
  : left.name.localeCompare(right.name));
475
501
  }
476
- function readAgents(alive) {
477
- const stream = alive.deps.stream();
478
- if (stream?.agents === undefined || !alive.deps.online() || alive.held.now().agentsReading)
479
- return;
480
- const { agents: read } = stream;
481
- const { agentListeners } = alive;
482
- alive.held.set({ agentsReading: true });
483
- void alive.deps.recovery
484
- .attempt('agents', async () => {
485
- if (!alive.deps.online() || (!agentListeners.waiting() && !agentListeners.told())) {
486
- return 'done';
487
- }
488
- const listed = await retrying(alive.deps.retries, 'conversations', AGENTS, read)();
489
- if (listed === null)
490
- return 'done';
491
- alive.held.set({ listedAgents: listed });
492
- emitAgents(alive);
493
- return 'done';
494
- })
495
- .finally(() => {
496
- alive.held.set({ agentsReading: false });
497
- });
498
- }
499
502
  function emitAgents(alive) {
500
- if (alive.deps.closed() || !alive.agentListeners.told())
503
+ const { agentListeners, listedListeners } = alive;
504
+ if (alive.deps.closed() || (!agentListeners.told() && !listedListeners.told()))
501
505
  return;
502
- shownList(alive, (list) => {
503
- const value = agents(alive, list);
506
+ shownListing(alive, (listing) => {
507
+ const value = agentsOf(listing);
504
508
  const shown = JSON.stringify(value);
505
- if (shown === alive.held.now().agentsShown)
506
- return;
507
- alive.held.set({ agentsShown: shown });
508
- alive.agentListeners.tell(value);
509
+ if (shown !== alive.held.now().agentsShown) {
510
+ alive.held.set({ agentsShown: shown });
511
+ agentListeners.tell(value);
512
+ }
513
+ const listed = JSON.stringify(listing.agents);
514
+ if (listed !== alive.held.now().listedShown) {
515
+ alive.held.set({ listedShown: listed });
516
+ listedListeners.tell(structuredClone(listing.agents));
517
+ }
509
518
  });
510
519
  }
511
520
  function setLive(alive, conversation, next) {
@@ -519,11 +528,11 @@ function setLive(alive, conversation, next) {
519
528
  after.asked !== before.asked)
520
529
  tellSoon(alive);
521
530
  }
522
- function retiredChat(conversation, list) {
531
+ function retiredChat(conversation, listing) {
523
532
  if (!conversation.startsWith(NEW_CHAT))
524
533
  return false;
525
534
  const agent = conversation.slice(NEW_CHAT.length);
526
- return list.some((entry) => entry.agent === agent && entry.agentRetired);
535
+ return listing.agents.some((one) => one.id === agent && one.retired_at !== null);
527
536
  }
528
537
  function live(alive, conversation, change) {
529
538
  alive.factsHeard(conversation, FACTS.filter((one) => one in change));
@@ -611,7 +620,7 @@ async function readsOf(local, conversations) {
611
620
  return new Map((await local.conversations(conversations)).map((held) => [held.conversation, held]));
612
621
  }
613
622
  function retiredDrafts(alive, list) {
614
- if (!list.some((entry) => entry.agentRetired))
623
+ if (!list.agents.some((agent) => agent.retired_at !== null))
615
624
  return;
616
625
  void alive.deps
617
626
  .local()
@@ -944,7 +953,12 @@ export function conversationSurface(alive) {
944
953
  return alive.deps.durably(async (local) => {
945
954
  const { messages, more } = await local.messageWindow(conversation, asked.limit, asked.before, phrase);
946
955
  const total = asked.total ? await local.messageCount(conversation, phrase) : null;
947
- return structuredClone(viewOf(alive, conversation, messages, frameOf(asked, messages, more, total), (await local.chatDraft(conversation)) ?? null, await endedIn(alive, conversation), await dismissedIn(local, conversation)));
956
+ return structuredClone(viewOf(alive, conversation, messages, frameOf(asked, messages, more, total), {
957
+ draft: (await local.chatDraft(conversation)) ?? null,
958
+ ended: await endedIn(alive, conversation),
959
+ dismissed: await dismissedIn(local, conversation),
960
+ pins: (await local.facts()).chatPins,
961
+ }));
948
962
  });
949
963
  },
950
964
  async create(input) {
@@ -952,7 +966,7 @@ export function conversationSurface(alive) {
952
966
  const conversation = answered(result, 'conversation_id');
953
967
  if (conversation === null)
954
968
  return result;
955
- const listed = (await heldList(alive)) ?? [];
969
+ const listed = (await heldListing(alive))?.conversations ?? [];
956
970
  if (!listed.some((entry) => entry.conversation === conversation)) {
957
971
  alive.creating(conversation);
958
972
  }
@@ -1018,17 +1032,19 @@ export function conversationSurface(alive) {
1018
1032
  message_id: message,
1019
1033
  });
1020
1034
  },
1021
- async pins() {
1022
- return (await (await alive.deps.local()).facts()).chatPins;
1023
- },
1024
- pin(figures) {
1025
- return alive.deps.durably((local) => local.fact('chatPins', [...figures]));
1026
- },
1027
- async openedTurns() {
1028
- return factOf(await alive.deps.local(), 'openedTurn');
1035
+ async pin(figures) {
1036
+ const pins = [...figures];
1037
+ await alive.deps.durably((local) => local.fact('chatPins', pins));
1038
+ const views = [...alive.views()];
1039
+ for (const view of views)
1040
+ view.held.set({ pins });
1041
+ for (const conversation of new Set(views.map((view) => view.conversation))) {
1042
+ emit(alive, conversation);
1043
+ }
1029
1044
  },
1030
- openTurn(conversation, turn) {
1031
- return alive.deps.durably((local) => local.keepConversationFact({ conversation, name: 'openedTurn', value: turn }));
1045
+ async openTurn(conversation, turn) {
1046
+ await alive.deps.durably((local) => local.keepConversationFact({ conversation, name: 'openedTurn', value: turn }));
1047
+ tellList(alive);
1032
1048
  },
1033
1049
  dismissSuggestion(conversation, suggestion) {
1034
1050
  return alive.deps.durably(async (local) => {
@@ -1072,29 +1088,34 @@ export function chatDraftSurface(alive) {
1072
1088
  };
1073
1089
  }
1074
1090
  export async function conversationsOpened(alive, local) {
1075
- const { conversationList, conversationCursor } = await local.facts();
1076
- if (conversationList === null || alive.known())
1091
+ const { conversationList, agentList, conversationCursor } = await local.facts();
1092
+ if (conversationList === null || agentList === null || alive.known())
1077
1093
  return;
1078
1094
  alive.deps.stream()?.hold(conversationCursor);
1079
1095
  conversationsLearned(alive);
1080
1096
  }
1097
+ export function reconcileOpening(alive) {
1098
+ alive.held.set({ openingRead: true });
1099
+ return reconcileConversations(alive);
1100
+ }
1081
1101
  export async function reconcileConversations(alive) {
1082
1102
  if (!alive.known())
1083
1103
  return;
1084
1104
  const local = await alive.deps.local();
1085
- const [held, stored, { conversationList }] = await Promise.all([
1105
+ const [held, stored, { conversationList, agentList }] = await Promise.all([
1086
1106
  local.conversations(),
1087
1107
  local.storedConversations(),
1088
1108
  local.facts(),
1089
1109
  ]);
1090
1110
  const list = conversationList ?? [];
1111
+ const listing = { conversations: list, agents: agentList ?? [] };
1091
1112
  const entries = new Map(list.map((entry) => [entry.conversation, entry]));
1092
1113
  const named = new Set(entries.keys());
1093
1114
  const reads = new Map(held.map((one) => [one.conversation, one]));
1094
1115
  const { replicated } = alive.held.now();
1095
1116
  const leaving = [...new Set([...replicated, ...stored])].filter((conversation) => !named.has(conversation) &&
1096
1117
  !alive.isCreating(conversation) &&
1097
- (!conversation.startsWith(NEW_CHAT) || retiredChat(conversation, list)));
1118
+ (!conversation.startsWith(NEW_CHAT) || retiredChat(conversation, listing)));
1098
1119
  for (const conversation of named) {
1099
1120
  if (!replicated.has(conversation) &&
1100
1121
  missed(alive, conversation, reads.get(conversation), entries.get(conversation))) {
@@ -1178,6 +1199,7 @@ export function watchConversation(alive, conversation, options, deliver) {
1178
1199
  held.set({ draft: (await local.chatDraft(conversation)) ?? null });
1179
1200
  held.set({ ended: await endedIn(alive, conversation) });
1180
1201
  held.set({ dismissed: await dismissedIn(local, conversation) });
1202
+ held.set({ pins: (await local.facts()).chatPins });
1181
1203
  held.set({ window: messages });
1182
1204
  held.set({ more });
1183
1205
  held.set({ total: asked.total ? await local.messageCount(conversation) : null });
@@ -1185,10 +1207,10 @@ export function watchConversation(alive, conversation, options, deliver) {
1185
1207
  .then(() => {
1186
1208
  if (alive.deps.closed() || !view.admit(watcher))
1187
1209
  return;
1188
- const { window, draft, ended, dismissed } = held.now();
1189
- const shown = window ?? [];
1210
+ const now = held.now();
1211
+ const shown = now.window ?? [];
1190
1212
  const frame = sharedFrame(view, shown);
1191
- watcher.notify(viewOf(alive, conversation, shown, frame, draft, ended, dismissed));
1213
+ watcher.notify(viewOf(alive, conversation, shown, frame, now));
1192
1214
  })
1193
1215
  .catch(() => { });
1194
1216
  return () => {
@@ -1204,9 +1226,13 @@ export function watchConversationList(alive, deliver) {
1204
1226
  export function watchConversationAgents(alive, deliver) {
1205
1227
  alive.agentListeners.join(deliver);
1206
1228
  conversationsLearned(alive);
1207
- readAgents(alive);
1208
1229
  return () => alive.agentListeners.leave(deliver);
1209
1230
  }
1231
+ export function watchListedAgents(alive, deliver) {
1232
+ alive.listedListeners.join(deliver);
1233
+ conversationsLearned(alive);
1234
+ return () => alive.listedListeners.leave(deliver);
1235
+ }
1210
1236
  export function conversationsChanged(alive, set) {
1211
1237
  for (const conversation of set.conversations)
1212
1238
  emit(alive, conversation);
@@ -1218,26 +1244,32 @@ export function receiveConversationEvent(alive, event) {
1218
1244
  if (event.whole)
1219
1245
  alive.relistBegun();
1220
1246
  if (alive.relisting())
1221
- alive.relistHeard(event.entries);
1247
+ alive.relistHeard(event.entries, event.agents);
1222
1248
  if (event.more && alive.relisting())
1223
1249
  return;
1224
1250
  const whole = alive.relistTaken();
1225
1251
  listChanged(alive, {
1226
1252
  replacing: whole !== null,
1227
- set: whole === null ? event.entries : [...whole.values()],
1253
+ set: whole === null ? event.entries : [...whole.conversations.values()],
1254
+ agents: whole === null ? event.agents : [...whole.agents.values()],
1228
1255
  gone: null,
1229
1256
  ...(event.more ? { paged: true } : { cursor: event.cursor }),
1230
1257
  });
1231
1258
  return;
1232
1259
  }
1233
1260
  if (event.kind === 'listed') {
1234
- alive.relistHeard([event.entry]);
1235
- listChanged(alive, { replacing: false, set: [event.entry], gone: null });
1261
+ alive.relistHeard([event.entry], []);
1262
+ listChanged(alive, { replacing: false, set: [event.entry], agents: [], gone: null });
1263
+ return;
1264
+ }
1265
+ if (event.kind === 'agent') {
1266
+ alive.relistHeard([], [event.agent]);
1267
+ listChanged(alive, { replacing: false, set: [], agents: [event.agent], gone: null });
1236
1268
  return;
1237
1269
  }
1238
1270
  if (event.kind === 'unlisted') {
1239
1271
  alive.relistDropped(event.conversation);
1240
- listChanged(alive, { replacing: false, set: [], gone: event.conversation });
1272
+ listChanged(alive, { replacing: false, set: [], agents: [], gone: event.conversation });
1241
1273
  return;
1242
1274
  }
1243
1275
  heard(alive, event);
@@ -1 +1 @@
1
- {"version":3,"file":"figures.d.ts","sourceRoot":"","sources":["../src/figures.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC,eAAO,MAAM,WAAW;;;;iBAGZ,IAAI;;CACe,CAAC;AAGhC,eAAO,MAAM,cAAc,WAAa,CAAC;AAQzC,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;CAChF,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjG,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,CAAC;AAEpD,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,KAAK,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IACjF,aAAa,CACX,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,EACvC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAAC;IAChD,OAAO,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC9B,OAAO,IAAI,IAAI,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAgDF,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAsIlE"}
1
+ {"version":3,"file":"figures.d.ts","sourceRoot":"","sources":["../src/figures.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC,eAAO,MAAM,WAAW;;;;iBAGZ,IAAI;;CACe,CAAC;AAGhC,eAAO,MAAM,cAAc,WAAa,CAAC;AAQzC,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;CAChF,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjG,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,CAAC;AAEpD,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,KAAK,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IACjF,aAAa,CACX,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,EACvC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAAC;IAChD,OAAO,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC9B,OAAO,IAAI,IAAI,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAgDF,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAwIlE"}
package/dist/figures.js CHANGED
@@ -72,8 +72,9 @@ export function createFigures(sources) {
72
72
  }
73
73
  }
74
74
  async function tallied(rooms, since) {
75
+ const covered = new Set(rooms.map(({ locator }) => locator));
75
76
  for (const locator of held.rooms.keys()) {
76
- if (!rooms.some((room) => room.locator === locator))
77
+ if (!covered.has(locator))
77
78
  held.rooms.delete(locator);
78
79
  }
79
80
  const asked = rooms.filter(({ locator, key }) => held.staleRooms.has(locator) || held.rooms.get(locator)?.key !== key);
@@ -90,8 +91,9 @@ export function createFigures(sources) {
90
91
  ]);
91
92
  if (kept !== held)
92
93
  return false;
94
+ const byKey = new Map(asked.map((room) => [room.key, room]));
93
95
  for (const tally of roomTallies) {
94
- const room = asked.find(({ key }) => key === tally.key);
96
+ const room = byKey.get(tally.key);
95
97
  if (room !== undefined)
96
98
  held.rooms.set(room.locator, tally);
97
99
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAStF"}
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAIlD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAStF"}
package/dist/file.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { sha256 } from './digest.js';
2
+ import { declaredType } from './outcome.js';
2
3
  export async function attachedFile(locator, file) {
3
4
  return {
4
5
  locator,
5
6
  name: file.name,
6
- mediaType: file.type,
7
+ mediaType: declaredType(file),
7
8
  byteLength: file.size,
8
9
  sha256: await sha256(file),
9
10
  blob: file,
package/dist/host.d.ts CHANGED
@@ -39,6 +39,7 @@ export { entrySeedOf, type EntrySeed } from './seed.js';
39
39
  export type { PortReach, ReachedDocument } from './reach.js';
40
40
  export type { CodeAvailability, Persistence, Space } from './readiness.js';
41
41
  export { createRecovery, retryDelay, type Attempt, type Attempted, type AttemptOptions, type Recovery, type RecoveryOptions, } from './recovery.js';
42
+ export { replaces } from './observation.js';
42
43
  export { undeclared } from './outcome.js';
43
44
  export { wireAnswer, wireRequest, type RuntimePort, type WireAnswer, type WireRequest, } from './wire.js';
44
45
  //# sourceMappingURL=host.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
package/dist/host.js CHANGED
@@ -2,6 +2,7 @@ import { queryKey } from '@agentshouse/mdmodel';
2
2
  import { composeRuntime } from './connection.js';
3
3
  import { untilAnswered } from './recovery.js';
4
4
  import { described } from './failure.js';
5
+ import { observed } from './observation.js';
5
6
  import { answeredResult } from './outcome.js';
6
7
  import { AUTHORIZATION_ENDED, WIRE, wireRequest, } from './wire.js';
7
8
  const NARROWED = new Set(['within', 'whole']);
@@ -93,12 +94,8 @@ function answered(md, app, writtenBy, member, input) {
93
94
  return md.conversation.option(input[0], input[1], input[2], input[3]);
94
95
  case 'conversation.retry':
95
96
  return md.conversation.retry(input[0], input[1], input[2]);
96
- case 'conversation.pins':
97
- return md.conversation.pins();
98
97
  case 'conversation.pin':
99
98
  return md.conversation.pin(input[0]);
100
- case 'conversation.openedTurns':
101
- return md.conversation.openedTurns();
102
99
  case 'conversation.openTurn':
103
100
  return md.conversation.openTurn(input[0], input[1]);
104
101
  case 'conversation.dismissSuggestion':
@@ -124,7 +121,7 @@ function attempted(work) {
124
121
  function answeredMessage(value) {
125
122
  if (typeof value !== 'object' || value === null)
126
123
  return false;
127
- return !('result' in value) || answeredResult(value.result);
124
+ return 'result' in value ? answeredResult(value.result) : !('pending' in value);
128
125
  }
129
126
  export function serveMdRuntime(options) {
130
127
  const deploymentFacts = structuredClone(options.deploymentFacts);
@@ -277,9 +274,17 @@ export function serveMdRuntime(options) {
277
274
  readiness(deliver) {
278
275
  if (!serving)
279
276
  return () => { };
280
- const stop = view.watch('readiness', [], (value) => {
281
- if (serving)
282
- deliver(value);
277
+ let shown = null;
278
+ const stop = view.watch('readiness', [], (message) => {
279
+ if (!serving)
280
+ return;
281
+ if (shown !== null) {
282
+ shown.receive(message);
283
+ return;
284
+ }
285
+ shown = observed(message, () => { }, 'readiness');
286
+ shown.observation.subscribe((value) => deliver(value));
287
+ deliver(shown.observation.current());
283
288
  }, () => { });
284
289
  const end = () => {
285
290
  followed.delete(end);
@@ -319,5 +324,6 @@ export function serveMdRuntime(options) {
319
324
  }
320
325
  export { entrySeedOf } from './seed.js';
321
326
  export { createRecovery, retryDelay, } from './recovery.js';
327
+ export { replaces } from './observation.js';
322
328
  export { undeclared } from './outcome.js';
323
329
  export { wireAnswer, wireRequest, } from './wire.js';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type { AcceptedMessage, AcceptedRoom, ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, AttachRequest, AttachResult, AuthorityChange, Authorization, BinaryFile, BinaryLinkResult, BinaryRequest, BinaryResult, BootstrapPage, BootstrapRequest, BootstrapResult, Capability, ChangeAuthor, ContractUnavailable, ConversationAction, ConversationEvent, ConversationHistories, ConversationHistoryPage, ConversationHistoryRequest, ConversationMessage, ConversationStream, DiscoverResult, DiscoveredRoom, Discovery, SavedFacts, HistoryAuthor, HistoryRequest, HistoryResult, HistoryRetention, HistoryRevision, BootstrapPart, NotReady, HeldRoom, AgentEnvironment, ListedAgent, ListedConversation, MdModelIdentity, Member, MutationRequest, MutationResult, PageToken, ProviderLimit, ProviderRefusal, RefreshPage, RefreshRequest, RefreshResult, Retention, RetryableRefusal, RevokedAuthorization, RoomChange, RoomModels, RoomNotReadable, RoomStream, RoomStreamEvent, RoomVersionAt, SearchAnswer, SearchAsk, ServiceMode, ServiceModeSignal, TransportUncertainty, TurnOperation, TypedPath, TypedSelection, } from './adapter.js';
1
+ export type { AcceptedMessage, AcceptedRoom, ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, AttachRequest, AttachResult, AuthorityChange, Authorization, BinaryFile, BinaryLinkResult, BinaryRequest, BinaryResult, BootstrapPage, BootstrapRequest, BootstrapResult, Capability, ChangeAuthor, ContractUnavailable, ConversationAction, ConversationEvent, ConversationHistories, ConversationHistoryPage, ConversationHistoryRequest, ConversationMessage, ConversationStream, DiscoverResult, DiscoveredRoom, Discovery, SavedFacts, HistoryAuthor, HistoryRequest, HistoryResult, HistoryRetention, HistoryRevision, BootstrapPart, NotReady, HeldRoom, AgentEnvironment, ListedAgent, ListedConversation, ListedOwner, ListedSpaceRef, RoomList, RoomListEntry, SpaceListEntry, MdModelIdentity, Member, MutationRequest, MutationResult, PageToken, ProviderLimit, ProviderRefusal, RefreshPage, RefreshRequest, RefreshResult, Retention, RetryableRefusal, RevokedAuthorization, RoomChange, RoomModels, RoomNotReadable, RoomStream, RoomStreamEvent, RoomVersionAt, SearchAnswer, SearchAsk, ServiceMode, ServiceModeSignal, TransportUncertainty, TurnOperation, TypedPath, TypedSelection, } from './adapter.js';
2
2
  export type { Change, ChangeBatch, Precondition, RoomMove, WrittenBy } from './change.js';
3
3
  export { heldFacts } from './conversation-row.js';
4
4
  export type { ConversationAsk, ConversationHeld, ConversationLast, ConversationStart, } from './conversation-row.js';
@@ -16,13 +16,14 @@ export type { DayFigures, Figures, FiguresResult, RoomFigures } from './figures.
16
16
  export type { HeldApp, Holdings, RoomDocuments } from './holdings.js';
17
17
  export type { PresentationSurface, RoomDraftSurface } from './room-drafts.js';
18
18
  export type { AttachAnswer, BinaryAnswer, BinaryLinkAnswer, CallResult, DownloadAnswer, Failure, HistoryAnswer, Offline, QueueEntry, Resolution, Submission, } from './outcome.js';
19
+ export { blobOf, declaredType } from './outcome.js';
19
20
  export type { BinaryFileRecord } from './binary.js';
20
21
  export type { RuntimeError } from './failure.js';
21
22
  export { refusalError } from './failure.js';
22
- export type { ChangedPart, FieldValue, ReturnReason, RoomDraft, RoomDraftCreation, RoomDraftParts, RoomDraftWrite, TextParts, } from './room-draft.js';
23
+ export type { ChangedPart, FieldValue, Marks, ReturnReason, RoomDraft, RoomDraftCreation, RoomDraftParts, RoomDraftWrite, TextParts, } from './room-draft.js';
23
24
  export type { SaveRefusal } from './save.js';
24
25
  export type { SearchFound, SearchHit, SearchRequest, SearchResult } from './search.js';
25
- export { CHAT_MESSAGE_TYPE, CHAT_TYPE, keptFile, keptLines } from './chat-types.js';
26
+ export { keptFile, keptLines } from './chat-types.js';
26
27
  export { FIGURES_DAY_MS } from './figures.js';
27
28
  export { departure } from './change.js';
28
29
  export { definitionsIn, selected } from './collection.js';