@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
package/dist/memory.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { documentFacts } from '@agentshouse/mdmodel';
2
+ import { NO_ROOM_TYPES, schemaTypes } from './attached-model.js';
1
3
  import { sameChange } from './overlay.js';
2
4
  const ATTACHMENTS = 'attachments';
3
5
  function lastName(path) {
@@ -5,7 +7,6 @@ function lastName(path) {
5
7
  }
6
8
  const FIXTURE_RETENTION = {
7
9
  history: { kind: 'duration', seconds: 1 },
8
- outcome: 604_800,
9
10
  refreshHorizon: 1,
10
11
  };
11
12
  function declaredRetention(value) {
@@ -52,15 +53,16 @@ export function createMemoryAdapter(options = {}) {
52
53
  const listeners = new Set();
53
54
  const modeObservers = new Set();
54
55
  const scripted = new Map();
55
- const unsealed = new Map();
56
- const sealed = new Set();
57
56
  const sentTurns = new Map();
58
57
  const historyPageSize = options.historyPageSize;
59
58
  const attached = new Map();
60
59
  const linked = new WeakMap();
61
- let held = [];
60
+ const carried = new Map();
62
61
  let expiring = [];
62
+ let openings = 0;
63
+ const declaredRooms = new Set();
63
64
  let replicated = [];
65
+ let heldCursor = null;
64
66
  let issued = 0;
65
67
  function scriptConversations(entries) {
66
68
  scripted.clear();
@@ -101,8 +103,35 @@ export function createMemoryAdapter(options = {}) {
101
103
  return path;
102
104
  }
103
105
  }
106
+ const saved = new WeakMap();
107
+ function factsAt(room, path, content) {
108
+ const types = schemaTypes(room.model?.kind === 'model' ? room.model.snapshot.schema : null, NO_ROOM_TYPES);
109
+ let held = saved.get(types);
110
+ if (held === undefined) {
111
+ held = new Map();
112
+ saved.set(types, held);
113
+ }
114
+ const key = `${path}\u0000${content}`;
115
+ if (!held.has(key)) {
116
+ const facts = documentFacts(path, content, { types });
117
+ held.set(key, facts === null ? null : JSON.parse(JSON.stringify(facts)));
118
+ }
119
+ return held.get(key);
120
+ }
121
+ function factsIn(room, paths) {
122
+ const facts = {};
123
+ for (const path of paths) {
124
+ const content = room.documents?.[path];
125
+ const held = room.facts?.[path] ?? (content === undefined ? null : factsAt(room, path, content));
126
+ if (held !== null)
127
+ facts[path] = held;
128
+ }
129
+ return facts;
130
+ }
104
131
  function retain(entries) {
105
132
  for (const room of entries) {
133
+ for (const [path, content] of Object.entries(room.documents ?? {}))
134
+ factsAt(room, path, content);
106
135
  note(room.locator, room);
107
136
  const versions = served.get(room.locator) ?? new Map();
108
137
  versions.set(room.roomVersion, room);
@@ -135,6 +164,7 @@ export function createMemoryAdapter(options = {}) {
135
164
  roomVersion: room.roomVersion,
136
165
  ...(opening ? { models: modelsOf(room) } : {}),
137
166
  documents: named(room.documents ?? {}, taken),
167
+ facts: factsIn(room, taken),
138
168
  revisions: named(room.revisions ?? {}, [...taken, ...targets]),
139
169
  ...(room.fileIds === undefined
140
170
  ? {}
@@ -155,7 +185,7 @@ export function createMemoryAdapter(options = {}) {
155
185
  ...(folderRemovals.length === 0 ? {} : { folderRemovals }),
156
186
  };
157
187
  }
158
- function advancement(room, from, at) {
188
+ function advancement(room, from, at, whole = false) {
159
189
  const current = room.documents ?? {};
160
190
  const previous = from.documents ?? {};
161
191
  const currentTargets = new Set(Object.keys(room.binaryFiles ?? {}));
@@ -166,7 +196,7 @@ export function createMemoryAdapter(options = {}) {
166
196
  const changed = Object.keys(current)
167
197
  .filter((path) => current[path] !== previous[path] || headMoved(path))
168
198
  .sort();
169
- const size = pageSize ?? changed.length;
199
+ const size = whole ? changed.length : (pageSize ?? changed.length);
170
200
  const taken = changed.slice(at, at + size);
171
201
  const next = at + taken.length;
172
202
  const opening = at === 0;
@@ -182,6 +212,7 @@ export function createMemoryAdapter(options = {}) {
182
212
  roomVersion: room.roomVersion,
183
213
  ...(models === undefined ? {} : { models }),
184
214
  documents: named(current, taken),
215
+ facts: factsIn(room, taken),
185
216
  revisions: named(room.revisions ?? {}, [...taken, ...targets]),
186
217
  ...(room.fileIds === undefined
187
218
  ? {}
@@ -198,6 +229,26 @@ export function createMemoryAdapter(options = {}) {
198
229
  ...(pageToken === undefined ? {} : { pageToken }),
199
230
  };
200
231
  }
232
+ function carry(locator) {
233
+ const at = carried.get(locator);
234
+ const current = rooms.find((entry) => entry.locator === locator);
235
+ if (at === undefined || current === undefined || current.roomVersion === at)
236
+ return;
237
+ const from = served.get(locator)?.get(at);
238
+ carried.set(locator, current.roomVersion);
239
+ if (from === undefined)
240
+ return;
241
+ const page = advancement(current, from, 0, true);
242
+ for (const observer of observers) {
243
+ observer({
244
+ kind: 'room-change',
245
+ locator,
246
+ from: at,
247
+ roomVersion: current.roomVersion,
248
+ read: async () => page,
249
+ });
250
+ }
251
+ }
201
252
  function pageOf(conversation, after) {
202
253
  const messages = conversation.messages ?? [];
203
254
  const first = typeof after === 'string' ? messages.findIndex((message) => message.position > after) : 0;
@@ -212,16 +263,13 @@ export function createMemoryAdapter(options = {}) {
212
263
  : {}),
213
264
  };
214
265
  }
215
- function historiesOf(input) {
216
- const asked = input?.conversations;
217
- if (!Array.isArray(asked))
218
- return { kind: 'rejected', code: 'invalid_request', fields: {}, retryable: false };
266
+ function historiesOf(request) {
219
267
  const histories = [];
220
- for (const entry of asked) {
221
- const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
268
+ for (const entry of request.conversations) {
269
+ const conversation = scripted.get(entry.conversation);
222
270
  if (conversation === undefined)
223
271
  continue;
224
- const outcome = conversation.outcomes?.['conversation.history'];
272
+ const outcome = conversation.outcomes?.history;
225
273
  if (outcome !== undefined)
226
274
  return outcome;
227
275
  histories.push(pageOf(conversation, entry.after));
@@ -232,15 +280,13 @@ export function createMemoryAdapter(options = {}) {
232
280
  function conversationAction(request) {
233
281
  const name = request.name;
234
282
  const input = (request.input ?? {});
235
- if (name === 'conversation.history')
236
- return historiesOf(request.input);
237
- if (name === 'conversation.create') {
283
+ if (name === 'conversations/create') {
238
284
  issued += 1;
239
285
  const conversation = `conversation-${issued}`;
240
286
  scripted.set(conversation, { conversation });
241
- return { kind: 'action', result: { conversation } };
287
+ return { kind: 'action', result: { conversation_id: conversation } };
242
288
  }
243
- const named = typeof input.conversation === 'string' ? input.conversation : '';
289
+ const named = typeof input.conversation_id === 'string' ? input.conversation_id : '';
244
290
  const conversation = scripted.get(named);
245
291
  if (conversation === undefined) {
246
292
  return {
@@ -253,36 +299,28 @@ export function createMemoryAdapter(options = {}) {
253
299
  const outcome = conversation.outcomes?.[name];
254
300
  if (outcome !== undefined)
255
301
  return outcome;
256
- if (name === 'conversation.send') {
302
+ if (name === 'conversations/send') {
257
303
  const operation = typeof input.operation_id === 'string' ? input.operation_id : null;
258
304
  const answered = operation === null ? undefined : sentTurns.get(operation);
259
305
  if (answered !== undefined)
260
- return { kind: 'action', result: { turn: answered } };
306
+ return { kind: 'action', result: { message_id: answered } };
261
307
  issued += 1;
262
308
  const turn = `turn-${issued}`;
263
- unsealed.set(turn, named);
264
309
  if (operation !== null)
265
310
  sentTurns.set(operation, turn);
266
- return { kind: 'action', result: { turn } };
267
- }
268
- if (name === 'conversation.cancel') {
269
- const turn = typeof input.turn === 'string' ? input.turn : '';
270
- if (sealed.has(turn) || !unsealed.has(turn)) {
271
- return { kind: 'rejected', code: 'turn-sealed', fields: { turn }, retryable: false };
272
- }
273
- unsealed.delete(turn);
274
- return { kind: 'action', result: { turn, cancelled: true } };
311
+ return { kind: 'action', result: { message_id: turn } };
275
312
  }
276
- if (name === 'conversation.delete')
313
+ if (name === 'conversations/delete')
277
314
  scripted.delete(named);
278
- return { kind: 'action', result: { conversation: named } };
315
+ return { kind: 'action', result: { conversation_id: named } };
279
316
  }
280
317
  function announceList() {
281
318
  const entries = [...scripted.values()].flatMap(({ conversation, listed, messages = [] }) => listed === undefined
282
319
  ? []
283
320
  : [{ conversation, ...listed, newest: messages.at(-1)?.position ?? null }]);
284
- for (const listener of listeners)
285
- listener({ kind: 'list', entries });
321
+ for (const listener of listeners) {
322
+ listener({ kind: 'list', entries, whole: true, more: false, cursor: null });
323
+ }
286
324
  }
287
325
  function discovery() {
288
326
  return {
@@ -294,9 +332,42 @@ export function createMemoryAdapter(options = {}) {
294
332
  ...(options.member === undefined ? {} : { member: options.member }),
295
333
  };
296
334
  }
335
+ function discovered() {
336
+ return resolveScript(scripts.discover, discovery, undefined).then((answer) => {
337
+ if (answer.kind === 'discovery')
338
+ for (const room of answer.rooms)
339
+ note(room.locator, room);
340
+ return answer;
341
+ });
342
+ }
343
+ function opened(notify) {
344
+ const opening = ++openings;
345
+ notify({ kind: 'opened' });
346
+ void discovered()
347
+ .catch(() => ({ kind: 'transport-uncertainty' }))
348
+ .then((answer) => {
349
+ if (opening !== openings)
350
+ return;
351
+ if (answer.kind !== 'discovery') {
352
+ openings += 1;
353
+ carried.clear();
354
+ const revoked = answer.kind === 'revoked-authorization';
355
+ notify({ kind: 'closed', revoked, lost: !revoked, authorityChanged: false });
356
+ return;
357
+ }
358
+ declaredRooms.clear();
359
+ for (const room of answer.rooms)
360
+ declaredRooms.add(room.locator);
361
+ notify({ kind: 'discovered', discovery: answer });
362
+ });
363
+ }
364
+ function emitAll(event) {
365
+ for (const observer of observers)
366
+ observer(event);
367
+ }
297
368
  return {
298
- ...(options.exhaustiveDiscovery === undefined ? {} : { exhaustiveDiscovery: true }),
299
369
  ...(options.roomTypes === undefined ? {} : { roomTypes: options.roomTypes }),
370
+ ...(options.typedPaths === undefined ? {} : { typedPaths: options.typedPaths }),
300
371
  setRooms(next) {
301
372
  rooms = [...next];
302
373
  retain(rooms);
@@ -305,33 +376,37 @@ export function createMemoryAdapter(options = {}) {
305
376
  scriptConversations(next);
306
377
  },
307
378
  open() {
379
+ carried.clear();
308
380
  announceList();
309
- for (const observer of observers)
310
- observer({ kind: 'opened' });
381
+ opened(emitAll);
311
382
  },
312
- close({ revoked = false, lost = !revoked } = {}) {
313
- for (const observer of observers)
314
- observer({ kind: 'closed', revoked, lost });
383
+ close({ revoked = false, lost = !revoked, authorityChanged = false } = {}) {
384
+ openings += 1;
385
+ carried.clear();
386
+ emitAll({ kind: 'closed', revoked, lost, authorityChanged });
315
387
  },
316
388
  expire(locators) {
317
389
  expiring = [...locators];
318
390
  },
319
- notifyRoomVersion({ locator, roomVersion }) {
320
- for (const observer of observers)
321
- observer({ kind: 'room-version', locator, roomVersion });
391
+ notifyRoomVersion({ locator }) {
392
+ carry(locator);
322
393
  },
323
- notifyAuthorityChanged(scope) {
324
- for (const observer of observers) {
325
- observer(scope === undefined
326
- ? { kind: 'authority-changed' }
327
- : { kind: 'authority-changed', scope });
328
- }
394
+ notifyAuthorityChanged(locators) {
395
+ const named = new Set(locators ?? [...declaredRooms, ...rooms.map((room) => room.locator)]);
396
+ const listed = rooms.filter((room) => named.has(room.locator));
397
+ const left = [...named].filter((locator) => !listed.some((room) => room.locator === locator));
398
+ for (const room of listed)
399
+ declaredRooms.add(room.locator);
400
+ for (const locator of left)
401
+ declaredRooms.delete(locator);
402
+ emitAll({
403
+ kind: 'authority-changed',
404
+ rooms: listed.map(declared),
405
+ left,
406
+ ...(options.member === undefined ? {} : { member: options.member }),
407
+ });
329
408
  },
330
409
  notifyConversation(event) {
331
- if (event.kind === 'accepted-message') {
332
- sealed.add(event.message.turn);
333
- unsealed.delete(event.message.turn);
334
- }
335
410
  for (const listener of listeners)
336
411
  listener(event);
337
412
  },
@@ -340,21 +415,31 @@ export function createMemoryAdapter(options = {}) {
340
415
  observer(mode);
341
416
  },
342
417
  heldRooms() {
343
- return held;
418
+ return [...carried.keys()].sort();
344
419
  },
345
420
  replicatedConversations() {
346
421
  return replicated;
347
422
  },
423
+ heldConversationCursor() {
424
+ return heldCursor;
425
+ },
348
426
  conversations: {
349
427
  replicate(next) {
350
428
  replicated = [...next];
351
429
  },
430
+ hold(cursor) {
431
+ heldCursor = cursor;
432
+ },
352
433
  observe(notify) {
353
434
  listeners.add(notify);
354
435
  return () => {
355
436
  listeners.delete(notify);
356
437
  };
357
438
  },
439
+ history: (request) => Promise.resolve(historiesOf(request)),
440
+ ...(options.agents === undefined
441
+ ? {}
442
+ : { agents: () => Promise.resolve(structuredClone(options.agents)) }),
358
443
  },
359
444
  serviceMode: {
360
445
  observe(notify) {
@@ -366,44 +451,45 @@ export function createMemoryAdapter(options = {}) {
366
451
  },
367
452
  roomStream: {
368
453
  hold(asked) {
369
- held = asked.map((room) => room.locator);
370
- const expired = expiring.filter((locator) => held.includes(locator));
371
- expiring = [];
372
- const moved = asked.flatMap((room) => {
454
+ const named = asked.map((room) => room.locator);
455
+ const unknown = asked.flatMap((room) => {
373
456
  const current = rooms.find((entry) => entry.locator === room.locator);
374
457
  return current === undefined ||
375
- expired.includes(room.locator) ||
376
- current.roomVersion === room.roomVersion
458
+ current.roomVersion === room.roomVersion ||
459
+ served.get(room.locator)?.has(room.roomVersion) === true
377
460
  ? []
378
- : [{ locator: room.locator, roomVersion: current.roomVersion }];
461
+ : [room.locator];
379
462
  });
463
+ const expired = [
464
+ ...new Set([...expiring.filter((locator) => named.includes(locator)), ...unknown]),
465
+ ];
466
+ expiring = expiring.filter((locator) => !named.includes(locator));
380
467
  queueMicrotask(() => {
381
- for (const observer of observers) {
382
- for (const room of moved)
383
- observer({ kind: 'room-version', ...room });
384
- observer({ kind: 'opening', expired });
468
+ for (const room of asked) {
469
+ if (expired.includes(room.locator))
470
+ carried.delete(room.locator);
471
+ else {
472
+ carried.set(room.locator, room.roomVersion);
473
+ carry(room.locator);
474
+ }
385
475
  }
476
+ emitAll({ kind: 'caught-up', expired });
386
477
  });
387
478
  },
388
- reopen() {
389
- queueMicrotask(() => {
390
- for (const observer of observers) {
391
- observer({ kind: 'closed', revoked: false, lost: false });
392
- }
393
- });
394
- },
395
- published() { },
396
479
  observe(notify) {
397
480
  observers.add(notify);
398
481
  queueMicrotask(() => {
399
482
  if (!observers.has(notify))
400
483
  return;
401
484
  if (options.unopened === true) {
402
- notify({ kind: 'closed', revoked: false, lost: true });
485
+ notify({ kind: 'closed', revoked: false, lost: true, authorityChanged: false });
403
486
  return;
404
487
  }
405
488
  announceList();
406
- notify({ kind: 'opened' });
489
+ opened((event) => {
490
+ if (observers.has(notify))
491
+ notify(event);
492
+ });
407
493
  });
408
494
  return () => {
409
495
  observers.delete(notify);
@@ -420,12 +506,7 @@ export function createMemoryAdapter(options = {}) {
420
506
  return resolveScript(scripts.authorize, () => ({}), undefined);
421
507
  },
422
508
  async discover(_authorization) {
423
- return resolveScript(scripts.discover, discovery, undefined).then((answer) => {
424
- if (answer.kind === 'discovery')
425
- for (const room of answer.rooms)
426
- note(room.locator, room);
427
- return answer;
428
- });
509
+ return discovered();
429
510
  },
430
511
  reached,
431
512
  follows(locator, roomVersion, next) {
@@ -539,7 +620,7 @@ export function createMemoryAdapter(options = {}) {
539
620
  },
540
621
  async action(_authorization, request) {
541
622
  return resolveScript(scripts.action, () => {
542
- if (request.name.startsWith('conversation.'))
623
+ if (request.name.startsWith('conversations/'))
543
624
  return conversationAction(request);
544
625
  return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
545
626
  }, request).then((answer) => {
@@ -20,8 +20,8 @@ export type ConversationWrite = {
20
20
  };
21
21
  export declare function heldConversations(connection: Connection): HeldConversation[];
22
22
  export declare function keptMessages(connection: Connection, { conversation, messages, read }: ConversationWrite): null;
23
- export declare function messageWindow(connection: Connection, conversation: string, limit: number, before: readonly [string, string] | null): MessageWindow;
24
- export declare function messageCount(connection: Connection, conversation: string): number;
23
+ export declare function messageWindow(connection: Connection, conversation: string, limit: number, before: readonly [string, string] | null, phrase: string | null): MessageWindow;
24
+ export declare function messageCount(connection: Connection, conversation: string, phrase: string | null): number;
25
25
  export declare function turnArrived(connection: Connection, conversation: string, turn: string): boolean;
26
26
  export declare function droppedMessages(connection: Connection, conversations: readonly string[]): void;
27
27
  export declare function forgottenMessages(connection: Connection): void;
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAM3C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3E,CAAC;AAMF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,EAAE,CAmB5E;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,iBAAiB,GAClD,IAAI,CAoCN;AAYD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GACvC,aAAa,CAUf;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAMjF;AAED,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO/F;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAW9F;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAG9D"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAM3C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3E,CAAC;AAMF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,EAAE,CAmB5E;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,iBAAiB,GAClD,IAAI,CA+BN;AAkBD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,EACxC,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,aAAa,CAWf;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,MAAM,CAOR;AAED,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO/F;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAK9F;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAG9D"}
package/dist/messages.js CHANGED
@@ -1,4 +1,4 @@
1
- import { indexMessage, unindexMessages } from './fulltext.js';
1
+ import { sql } from '@agentshouse/mdmodel';
2
2
  export const MESSAGE_TABLES = [
3
3
  'CREATE TABLE conversation_reads (conversation TEXT PRIMARY KEY, read TEXT, partial INTEGER NOT NULL) WITHOUT ROWID',
4
4
  'CREATE TABLE conversation_messages (id INTEGER PRIMARY KEY, conversation TEXT NOT NULL, identity TEXT NOT NULL, turn TEXT NOT NULL, position TEXT NOT NULL, message TEXT NOT NULL, text TEXT NOT NULL)',
@@ -36,17 +36,12 @@ export function keptMessages(connection, { conversation, messages, read }) {
36
36
  JSON.stringify(message.message ?? null),
37
37
  message.text,
38
38
  ];
39
- let id;
40
39
  if (held === undefined) {
41
40
  connection.run('INSERT INTO conversation_messages (conversation, identity, turn, position, message, text) VALUES (?, ?, ?, ?, ?, ?)', [conversation, message.identity, ...record]);
42
- id = Number(connection.rows('SELECT last_insert_rowid() AS id')[0].id);
43
41
  }
44
42
  else {
45
- id = Number(held.id);
46
- unindexMessages(connection, [id]);
47
- connection.run('UPDATE conversation_messages SET turn = ?, position = ?, message = ?, text = ? WHERE id = ?', [...record, id]);
43
+ connection.run('UPDATE conversation_messages SET turn = ?, position = ?, message = ?, text = ? WHERE id = ?', [...record, held.id]);
48
44
  }
49
- indexMessage(connection, id, message.text);
50
45
  }
51
46
  if (read !== undefined) {
52
47
  connection.run('INSERT OR REPLACE INTO conversation_reads (conversation, read, partial) VALUES (?, ?, ?)', [conversation, read.at, read.partial ? 1 : 0]);
@@ -62,14 +57,21 @@ function accepted(row) {
62
57
  message: JSON.parse(text(row.message)),
63
58
  };
64
59
  }
65
- export function messageWindow(connection, conversation, limit, before) {
66
- const rows = connection.rows(`SELECT identity, turn, position, message, text FROM conversation_messages WHERE conversation = ?${before === null ? '' : ' AND (position < ? OR (position = ? AND identity < ?))'} ORDER BY position DESC, identity DESC LIMIT ?`, before === null
67
- ? [conversation, limit + 1]
68
- : [conversation, before[0], before[0], before[1], limit + 1]);
60
+ function holding(phrase) {
61
+ return phrase === null
62
+ ? { sql: '', bind: [] }
63
+ : { sql: ` AND ${sql.HOLDS_PHRASE}(text, ?)`, bind: [phrase.toLowerCase()] };
64
+ }
65
+ export function messageWindow(connection, conversation, limit, before, phrase) {
66
+ const held = holding(phrase);
67
+ const rows = connection.rows(`SELECT identity, turn, position, message, text FROM conversation_messages WHERE conversation = ?${held.sql}${before === null ? '' : ' AND (position < ? OR (position = ? AND identity < ?))'} ORDER BY position DESC, identity DESC LIMIT ?`, before === null
68
+ ? [conversation, ...held.bind, limit + 1]
69
+ : [conversation, ...held.bind, before[0], before[0], before[1], limit + 1]);
69
70
  return { messages: rows.slice(0, limit).map(accepted).reverse(), more: rows.length > limit };
70
71
  }
71
- export function messageCount(connection, conversation) {
72
- const [counted] = connection.rows('SELECT count(*) AS held FROM conversation_messages WHERE conversation = ?', [conversation]);
72
+ export function messageCount(connection, conversation, phrase) {
73
+ const held = holding(phrase);
74
+ const [counted] = connection.rows(`SELECT count(*) AS held FROM conversation_messages WHERE conversation = ?${held.sql}`, [conversation, ...held.bind]);
73
75
  return Number(counted?.held ?? 0);
74
76
  }
75
77
  export function turnArrived(connection, conversation, turn) {
@@ -77,9 +79,6 @@ export function turnArrived(connection, conversation, turn) {
77
79
  }
78
80
  export function droppedMessages(connection, conversations) {
79
81
  for (const conversation of conversations) {
80
- unindexMessages(connection, connection
81
- .rows('SELECT id FROM conversation_messages WHERE conversation = ?', [conversation])
82
- .map((row) => Number(row.id)));
83
82
  connection.run('DELETE FROM conversation_messages WHERE conversation = ?', [conversation]);
84
83
  connection.run('DELETE FROM conversation_reads WHERE conversation = ?', [conversation]);
85
84
  }
package/dist/model.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Definition, ValueFacts, VerifiedModel } from '@agentshouse/mdmodel';
1
+ import type { Definition, VerifiedModel } from '@agentshouse/mdmodel';
2
2
  import type { Open } from './open.js';
3
3
  export type ModelIdentity = {
4
4
  identity: string;
@@ -8,7 +8,7 @@ export type ModelSnapshot = ModelIdentity & {
8
8
  schema: string | null;
9
9
  revision: string | null;
10
10
  };
11
- export type ModelUnavailableReason = Open<'not-readable' | 'revoked' | 'not-acquired' | 'invalid'>;
11
+ export type ModelUnavailableReason = Open<'not-readable' | 'revoked' | 'not-acquired'>;
12
12
  export type ModelResult = {
13
13
  kind: 'model';
14
14
  snapshot: ModelSnapshot;
@@ -20,8 +20,6 @@ export type MdType = Definition;
20
20
  export type ModelState = {
21
21
  status: 'unavailable';
22
22
  reason: ModelUnavailableReason;
23
- schema?: string | null;
24
- revision?: string | null;
25
23
  } | {
26
24
  status: 'current' | 'cached';
27
25
  snapshot: ModelSnapshot;
@@ -37,8 +35,6 @@ export type TypesResult = {
37
35
  status: Open<'unavailable'>;
38
36
  reason: ModelUnavailableReason;
39
37
  types: null;
40
- schema?: string | null;
41
- revision?: string | null;
42
38
  } | {
43
39
  status: Open<'current' | 'cached'>;
44
40
  identity: string;
@@ -59,5 +55,4 @@ export declare function modelTypes(state: ModelState): TypesResult;
59
55
  export declare function storedModel(state: ModelState): StoredModel;
60
56
  export declare function cached(state: ModelState): ModelState;
61
57
  export declare function sameModel(left: ModelIdentity, right: ModelIdentity): boolean;
62
- export declare function referenceField(facts: ValueFacts | undefined): boolean;
63
58
  //# sourceMappingURL=model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,GAAG,SAAS,GAAG,cAAc,CAAC,CAAC;AACvF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC;AAChC,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,GAC9C,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACzE,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC5E;IACE,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;CACpC,CAAC;AACF,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAGhG;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAczD;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAI1D;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEpD;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAE5E"}
package/dist/model.js CHANGED
@@ -29,6 +29,3 @@ export function cached(state) {
29
29
  export function sameModel(left, right) {
30
30
  return left.identity === right.identity && left.version === right.version;
31
31
  }
32
- export function referenceField(facts) {
33
- return facts?.reference !== undefined || facts?.items?.reference !== undefined;
34
- }
@@ -27,8 +27,8 @@ export declare function rowsOf(result: QueryResult): readonly (QueryDocument | Q
27
27
  export declare function whole(message: QueryMessage): message is KeyedResult;
28
28
  export declare function applied(keyed: KeyedResult, message: QueryMessage): KeyedResult;
29
29
  export declare function observed(first: unknown, stop: () => void, keyed: boolean): Observed;
30
- export declare function opened(watch: (deliver: (message: unknown) => void) => () => void, keyed: boolean): Promise<Observation<unknown>>;
31
- export declare function observing<Topic extends string>(watch: (topic: Topic, input: readonly unknown[], deliver: (message: unknown) => void) => () => void): (topic: Topic, ...input: unknown[]) => Promise<Observation<unknown>>;
30
+ export declare function opened(watch: (deliver: (message: unknown) => void, fail: (error: unknown) => void) => () => void, keyed: boolean): Promise<Observation<unknown>>;
31
+ export declare function observing<Topic extends string>(watch: (topic: Topic, input: readonly unknown[], deliver: (message: unknown) => void, fail: (error: unknown) => void) => () => void): (topic: Topic, ...input: unknown[]) => Promise<Observation<unknown>>;
32
32
  export type Digest = {
33
33
  readonly pending: string;
34
34
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"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"}
@@ -98,6 +98,11 @@ export function opened(watch, keyed) {
98
98
  }
99
99
  handle = observed(message, () => stop(), keyed);
100
100
  resolve(handle.observation);
101
+ }, (error) => {
102
+ if (handle !== undefined)
103
+ return;
104
+ stop();
105
+ reject(error);
101
106
  });
102
107
  }
103
108
  catch (error) {
@@ -106,9 +111,9 @@ export function opened(watch, keyed) {
106
111
  });
107
112
  }
108
113
  export function observing(watch) {
109
- return (topic, ...input) => opened((deliver) => watch(topic, input, (message) => {
114
+ return (topic, ...input) => opened((deliver, fail) => watch(topic, input, (message) => {
110
115
  deliver(structuredClone(message));
111
- }), topic === 'query');
116
+ }, fail), topic === 'query');
112
117
  }
113
118
  export function hashed(text) {
114
119
  let first = 0xdeadbeef;