@agentshouse/mdruntime 0.1.0-ca7c26c6bc27e → 0.1.0-ca8707258fdde

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 (253) hide show
  1. package/README.md +25 -12
  2. package/dist/acceptance.d.ts +26 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +384 -0
  5. package/dist/adapter.d.ts +200 -54
  6. package/dist/adapter.d.ts.map +1 -1
  7. package/dist/adapter.js +1 -9
  8. package/dist/attached-model.d.ts +7 -10
  9. package/dist/attached-model.d.ts.map +1 -1
  10. package/dist/attached-model.js +40 -28
  11. package/dist/attempt.d.ts +16 -0
  12. package/dist/attempt.d.ts.map +1 -0
  13. package/dist/attempt.js +70 -0
  14. package/dist/binary.d.ts +18 -0
  15. package/dist/binary.d.ts.map +1 -0
  16. package/dist/binary.js +8 -0
  17. package/dist/bootstrap.d.ts +37 -5
  18. package/dist/bootstrap.d.ts.map +1 -1
  19. package/dist/bootstrap.js +336 -51
  20. package/dist/chain.d.ts +12 -0
  21. package/dist/chain.d.ts.map +1 -0
  22. package/dist/chain.js +64 -0
  23. package/dist/change-set.d.ts +9 -14
  24. package/dist/change-set.d.ts.map +1 -1
  25. package/dist/change-set.js +11 -56
  26. package/dist/change.d.ts +46 -0
  27. package/dist/change.d.ts.map +1 -1
  28. package/dist/change.js +34 -0
  29. package/dist/chat-types.d.ts +3 -0
  30. package/dist/chat-types.d.ts.map +1 -0
  31. package/dist/chat-types.js +2 -0
  32. package/dist/client.d.ts +50 -18
  33. package/dist/client.d.ts.map +1 -1
  34. package/dist/client.js +162 -30
  35. package/dist/collection.d.ts +13 -14
  36. package/dist/collection.d.ts.map +1 -1
  37. package/dist/collection.js +52 -56
  38. package/dist/compile.d.ts +16 -0
  39. package/dist/compile.d.ts.map +1 -0
  40. package/dist/compile.js +717 -0
  41. package/dist/connection.d.ts +61 -43
  42. package/dist/connection.d.ts.map +1 -1
  43. package/dist/connection.js +2377 -1476
  44. package/dist/context.d.ts +2 -0
  45. package/dist/context.d.ts.map +1 -0
  46. package/dist/context.js +7 -0
  47. package/dist/conversation-row.d.ts +33 -0
  48. package/dist/conversation-row.d.ts.map +1 -0
  49. package/dist/conversation-row.js +47 -0
  50. package/dist/conversation.d.ts +71 -22
  51. package/dist/conversation.d.ts.map +1 -1
  52. package/dist/conversation.js +996 -273
  53. package/dist/digest.d.ts +7 -0
  54. package/dist/digest.d.ts.map +1 -0
  55. package/dist/digest.js +113 -0
  56. package/dist/durability.d.ts +10 -1
  57. package/dist/durability.d.ts.map +1 -1
  58. package/dist/durability.js +5 -0
  59. package/dist/entry.d.ts +20 -0
  60. package/dist/entry.d.ts.map +1 -0
  61. package/dist/entry.js +161 -0
  62. package/dist/expectation.d.ts +21 -0
  63. package/dist/expectation.d.ts.map +1 -0
  64. package/dist/expectation.js +70 -0
  65. package/dist/failure.d.ts +13 -0
  66. package/dist/failure.d.ts.map +1 -0
  67. package/dist/failure.js +19 -0
  68. package/dist/figures.d.ts +48 -0
  69. package/dist/figures.d.ts.map +1 -0
  70. package/dist/figures.js +197 -0
  71. package/dist/file.d.ts +2 -19
  72. package/dist/file.d.ts.map +1 -1
  73. package/dist/file.js +7 -122
  74. package/dist/host.d.ts +11 -2
  75. package/dist/host.d.ts.map +1 -1
  76. package/dist/host.js +134 -34
  77. package/dist/identity.d.ts +3 -0
  78. package/dist/identity.d.ts.map +1 -1
  79. package/dist/identity.js +13 -1
  80. package/dist/index.d.ts +31 -10
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +13 -0
  83. package/dist/install.d.ts +86 -0
  84. package/dist/install.d.ts.map +1 -0
  85. package/dist/install.js +537 -0
  86. package/dist/job.d.ts +33 -0
  87. package/dist/job.d.ts.map +1 -0
  88. package/dist/job.js +54 -0
  89. package/dist/live.d.ts +23 -0
  90. package/dist/live.d.ts.map +1 -0
  91. package/dist/live.js +165 -0
  92. package/dist/log.d.ts +1 -0
  93. package/dist/log.d.ts.map +1 -1
  94. package/dist/media.d.ts +8 -0
  95. package/dist/media.d.ts.map +1 -0
  96. package/dist/media.js +218 -0
  97. package/dist/memory.d.ts +22 -8
  98. package/dist/memory.d.ts.map +1 -1
  99. package/dist/memory.js +299 -94
  100. package/dist/messages.d.ts +52 -0
  101. package/dist/messages.d.ts.map +1 -0
  102. package/dist/messages.js +168 -0
  103. package/dist/model.d.ts +17 -12
  104. package/dist/model.d.ts.map +1 -1
  105. package/dist/model.js +9 -9
  106. package/dist/name.d.ts +4 -0
  107. package/dist/name.d.ts.map +1 -0
  108. package/dist/name.js +122 -0
  109. package/dist/observation.d.ts +22 -4
  110. package/dist/observation.d.ts.map +1 -1
  111. package/dist/observation.js +120 -14
  112. package/dist/open.d.ts +2 -0
  113. package/dist/open.d.ts.map +1 -0
  114. package/dist/open.js +1 -0
  115. package/dist/opened.d.ts +22 -0
  116. package/dist/opened.d.ts.map +1 -0
  117. package/dist/opened.js +107 -0
  118. package/dist/outcome.d.ts +73 -5
  119. package/dist/outcome.d.ts.map +1 -1
  120. package/dist/outcome.js +84 -1
  121. package/dist/overlay.d.ts +16 -5
  122. package/dist/overlay.d.ts.map +1 -1
  123. package/dist/overlay.js +147 -180
  124. package/dist/parts.d.ts +59 -0
  125. package/dist/parts.d.ts.map +1 -0
  126. package/dist/parts.js +118 -0
  127. package/dist/paths.d.ts +1 -1
  128. package/dist/paths.d.ts.map +1 -1
  129. package/dist/paths.js +4 -16
  130. package/dist/query.d.ts +52 -181
  131. package/dist/query.d.ts.map +1 -1
  132. package/dist/query.js +3 -423
  133. package/dist/questions.d.ts +32 -0
  134. package/dist/questions.d.ts.map +1 -0
  135. package/dist/questions.js +118 -0
  136. package/dist/reach.d.ts +19 -5
  137. package/dist/reach.d.ts.map +1 -1
  138. package/dist/reach.js +309 -92
  139. package/dist/react.d.ts +46 -0
  140. package/dist/react.d.ts.map +1 -0
  141. package/dist/react.js +54 -0
  142. package/dist/read.d.ts +7 -0
  143. package/dist/read.d.ts.map +1 -0
  144. package/dist/read.js +17 -0
  145. package/dist/readiness.d.ts +50 -0
  146. package/dist/readiness.d.ts.map +1 -0
  147. package/dist/readiness.js +27 -0
  148. package/dist/reads.d.ts +35 -0
  149. package/dist/reads.d.ts.map +1 -0
  150. package/dist/reads.js +128 -0
  151. package/dist/recovery.d.ts +26 -0
  152. package/dist/recovery.d.ts.map +1 -0
  153. package/dist/recovery.js +232 -0
  154. package/dist/refresh.d.ts +20 -7
  155. package/dist/refresh.d.ts.map +1 -1
  156. package/dist/refresh.js +155 -59
  157. package/dist/replica.d.ts +58 -34
  158. package/dist/replica.d.ts.map +1 -1
  159. package/dist/replica.js +355 -162
  160. package/dist/room-draft.d.ts +59 -11
  161. package/dist/room-draft.d.ts.map +1 -1
  162. package/dist/room-draft.js +276 -80
  163. package/dist/room-drafts.d.ts +29 -0
  164. package/dist/room-drafts.d.ts.map +1 -0
  165. package/dist/room-drafts.js +216 -0
  166. package/dist/rows.d.ts +32 -34
  167. package/dist/rows.d.ts.map +1 -1
  168. package/dist/rows.js +65 -87
  169. package/dist/save.d.ts +74 -6
  170. package/dist/save.d.ts.map +1 -1
  171. package/dist/save.js +902 -182
  172. package/dist/saves.d.ts +96 -0
  173. package/dist/saves.d.ts.map +1 -0
  174. package/dist/saves.js +999 -0
  175. package/dist/search.d.ts +15 -54
  176. package/dist/search.d.ts.map +1 -1
  177. package/dist/search.js +10 -121
  178. package/dist/seed.d.ts +30 -0
  179. package/dist/seed.d.ts.map +1 -0
  180. package/dist/seed.js +141 -0
  181. package/dist/shared.d.ts +15 -0
  182. package/dist/shared.d.ts.map +1 -0
  183. package/dist/shared.js +421 -0
  184. package/dist/socket/admission.d.ts +7 -0
  185. package/dist/socket/admission.d.ts.map +1 -0
  186. package/dist/socket/admission.js +39 -0
  187. package/dist/socket/answers.d.ts +6 -0
  188. package/dist/socket/answers.d.ts.map +1 -0
  189. package/dist/socket/answers.js +20 -0
  190. package/dist/socket/reads.d.ts +10 -0
  191. package/dist/socket/reads.d.ts.map +1 -0
  192. package/dist/socket/reads.js +31 -0
  193. package/dist/socket.d.ts +43 -0
  194. package/dist/socket.d.ts.map +1 -0
  195. package/dist/socket.js +96 -0
  196. package/dist/source.d.ts +61 -0
  197. package/dist/source.d.ts.map +1 -0
  198. package/dist/source.js +81 -0
  199. package/dist/status.d.ts +7 -4
  200. package/dist/status.d.ts.map +1 -1
  201. package/dist/status.js +3 -15
  202. package/dist/store/fences.d.ts +16 -0
  203. package/dist/store/fences.d.ts.map +1 -0
  204. package/dist/store/fences.js +26 -0
  205. package/dist/store/installs.d.ts +30 -0
  206. package/dist/store/installs.d.ts.map +1 -0
  207. package/dist/store/installs.js +34 -0
  208. package/dist/store/records.d.ts +212 -0
  209. package/dist/store/records.d.ts.map +1 -0
  210. package/dist/store/records.js +408 -0
  211. package/dist/store/room-held.d.ts +8 -0
  212. package/dist/store/room-held.d.ts.map +1 -0
  213. package/dist/store/room-held.js +17 -0
  214. package/dist/store/watchers.d.ts +15 -0
  215. package/dist/store/watchers.d.ts.map +1 -0
  216. package/dist/store/watchers.js +36 -0
  217. package/dist/store/writes.d.ts +24 -0
  218. package/dist/store/writes.d.ts.map +1 -0
  219. package/dist/store/writes.js +125 -0
  220. package/dist/store.d.ts +77 -93
  221. package/dist/store.d.ts.map +1 -1
  222. package/dist/store.js +118 -389
  223. package/dist/stored.d.ts +156 -0
  224. package/dist/stored.d.ts.map +1 -0
  225. package/dist/stored.js +637 -0
  226. package/dist/tables.d.ts +407 -0
  227. package/dist/tables.d.ts.map +1 -0
  228. package/dist/tables.js +724 -0
  229. package/dist/tallies.d.ts +18 -0
  230. package/dist/tallies.d.ts.map +1 -0
  231. package/dist/tallies.js +129 -0
  232. package/dist/transfer.d.ts +0 -5
  233. package/dist/transfer.d.ts.map +1 -1
  234. package/dist/turn.d.ts +9 -0
  235. package/dist/turn.d.ts.map +1 -0
  236. package/dist/turn.js +75 -0
  237. package/dist/validation.d.ts +29 -0
  238. package/dist/validation.d.ts.map +1 -0
  239. package/dist/validation.js +104 -0
  240. package/dist/windows.d.ts +11 -0
  241. package/dist/windows.d.ts.map +1 -0
  242. package/dist/windows.js +16 -0
  243. package/dist/wire.d.ts +185 -45
  244. package/dist/wire.d.ts.map +1 -1
  245. package/dist/wire.js +75 -46
  246. package/package.json +33 -10
  247. package/AGENTS.md +0 -215
  248. package/dist/attachment.d.ts +0 -3
  249. package/dist/attachment.d.ts.map +0 -1
  250. package/dist/attachment.js +0 -8
  251. package/dist/read-side.d.ts +0 -18
  252. package/dist/read-side.d.ts.map +0 -1
  253. package/dist/read-side.js +0 -377
package/dist/memory.js CHANGED
@@ -1,9 +1,12 @@
1
- import { ROOM_CONTRACT_VERSION, } from './adapter.js';
2
- import { MD_MODEL } from './collection.js';
1
+ import { documentFacts, parse } from '@agentshouse/mdmodel';
2
+ import { NO_ROOM_TYPES, schemaTypes } from './attached-model.js';
3
3
  import { sameChange } from './overlay.js';
4
+ const ATTACHMENTS = 'attachments';
5
+ function lastName(path) {
6
+ return path.slice(path.lastIndexOf('/') + 1);
7
+ }
4
8
  const FIXTURE_RETENTION = {
5
9
  history: { kind: 'duration', seconds: 1 },
6
- outcome: 1,
7
10
  refreshHorizon: 1,
8
11
  };
9
12
  function declaredRetention(value) {
@@ -17,12 +20,7 @@ function declaredRetention(value) {
17
20
  }
18
21
  const MODEL_ABSENT = { kind: 'model-unavailable', reason: 'not-readable' };
19
22
  function modelsOf(room) {
20
- return {
21
- collection: room.model ?? MODEL_ABSENT,
22
- ...(room.typedSelection === undefined
23
- ? {}
24
- : { selection: room.selectionModel ?? MODEL_ABSENT }),
25
- };
23
+ return { collection: room.model ?? MODEL_ABSENT };
26
24
  }
27
25
  function changedModels(room, from) {
28
26
  const now = modelsOf(room);
@@ -44,8 +42,6 @@ async function resolveScript(answer, fallback, request) {
44
42
  }
45
43
  export function createMemoryAdapter(options = {}) {
46
44
  let rooms = options.rooms === undefined ? [] : [...options.rooms];
47
- const mdModel = options.mdModel ?? MD_MODEL;
48
- const supportedVersions = options.supportedVersions ?? [ROOM_CONTRACT_VERSION];
49
45
  const capabilities = options.capabilities ?? [];
50
46
  const providerLimits = options.providerLimits ?? [];
51
47
  const retention = declaredRetention(options.retention);
@@ -57,12 +53,16 @@ export function createMemoryAdapter(options = {}) {
57
53
  const listeners = new Set();
58
54
  const modeObservers = new Set();
59
55
  const scripted = new Map();
60
- const unsealed = new Map();
61
- const sealed = new Set();
56
+ const sentTurns = new Map();
62
57
  const historyPageSize = options.historyPageSize;
63
- let held = [];
58
+ const attached = new Map();
59
+ const linked = new WeakMap();
60
+ const carried = new Map();
64
61
  let expiring = [];
62
+ let openings = 0;
63
+ const declaredRooms = new Set();
65
64
  let replicated = [];
65
+ let heldCursor = null;
66
66
  let issued = 0;
67
67
  function scriptConversations(entries) {
68
68
  scripted.clear();
@@ -90,8 +90,48 @@ export function createMemoryAdapter(options = {}) {
90
90
  const wanted = ordinals.get(`${locator}\u0000${target}`);
91
91
  return held !== undefined && wanted !== undefined && held >= wanted;
92
92
  }
93
+ function heldBlob(room, path) {
94
+ return attached.get(`${room.locator}\u0000${path}`) ?? room.blobs?.[path];
95
+ }
96
+ function freePath(room, name) {
97
+ const dot = name.lastIndexOf('.');
98
+ const stem = dot > 0 ? name.slice(0, dot) : name;
99
+ const extension = dot > 0 ? name.slice(dot) : '';
100
+ for (let count = 1;; count += 1) {
101
+ const path = `${ATTACHMENTS}/${count === 1 ? stem : `${stem}-${count}`}${extension}`;
102
+ if (heldBlob(room, path) === undefined && room.documents?.[path] === undefined)
103
+ return path;
104
+ }
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, parse(content, path), { 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
+ }
93
131
  function retain(entries) {
94
132
  for (const room of entries) {
133
+ for (const [path, content] of Object.entries(room.documents ?? {}))
134
+ factsAt(room, path, content);
95
135
  note(room.locator, room);
96
136
  const versions = served.get(room.locator) ?? new Map();
97
137
  versions.set(room.roomVersion, room);
@@ -103,6 +143,7 @@ export function createMemoryAdapter(options = {}) {
103
143
  return {
104
144
  name: room.name,
105
145
  locator: room.locator,
146
+ handle: room.handle,
106
147
  roomVersion: room.roomVersion,
107
148
  operations: room.operations,
108
149
  replica: room.replica,
@@ -110,35 +151,56 @@ export function createMemoryAdapter(options = {}) {
110
151
  providerOwnedPaths: room.providerOwnedPaths,
111
152
  };
112
153
  }
113
- function page(room, from) {
154
+ function page(room, after) {
114
155
  const paths = Object.keys(room.documents ?? {}).sort();
156
+ const opening = after === undefined;
157
+ const from = opening ? 0 : paths.filter((path) => path <= after).length;
115
158
  const size = pageSize ?? paths.length;
116
159
  const taken = paths.slice(from, from + size);
117
160
  const next = from + taken.length;
118
- const targets = from === 0 ? (room.binaryTargets ?? []) : [];
161
+ const targets = opening ? Object.keys(room.binaryFiles ?? {}) : [];
119
162
  return {
120
163
  kind: 'bootstrap',
121
164
  roomVersion: room.roomVersion,
122
- ...(from === 0 ? { models: modelsOf(room) } : {}),
165
+ ...(opening ? { models: modelsOf(room) } : {}),
123
166
  documents: named(room.documents ?? {}, taken),
124
- revisions: named(room.revisions ?? {}, taken),
167
+ facts: factsIn(room, taken),
168
+ revisions: named(room.revisions ?? {}, [...taken, ...targets]),
169
+ ...(room.fileIds === undefined
170
+ ? {}
171
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
172
+ ...(room.created === undefined
173
+ ? {}
174
+ : { created: named(room.created, [...taken, ...targets]) }),
125
175
  changes: named(room.changes ?? {}, [...taken, ...targets]),
126
- binaryTargets: targets,
127
- ...(from === 0 && room.attachments !== undefined ? { attachments: room.attachments } : {}),
128
- ...(next < paths.length ? { pageToken: String(next) } : {}),
176
+ binaryFiles: named(room.binaryFiles ?? {}, targets),
177
+ ...(opening && room.folders !== undefined ? { folders: room.folders } : {}),
178
+ ...(next < paths.length ? { pageToken: taken.at(-1) } : {}),
179
+ };
180
+ }
181
+ function foldersMoved(room, from) {
182
+ const now = new Set(room.folders ?? []);
183
+ const before = new Set(from.folders ?? []);
184
+ const folders = [...now].filter((folder) => !before.has(folder)).sort();
185
+ const folderRemovals = [...before].filter((folder) => !now.has(folder)).sort();
186
+ return {
187
+ ...(folders.length === 0 ? {} : { folders }),
188
+ ...(folderRemovals.length === 0 ? {} : { folderRemovals }),
129
189
  };
130
190
  }
131
- function advancement(room, from, at) {
191
+ function advancement(room, from, at, whole = false) {
132
192
  const current = room.documents ?? {};
133
193
  const previous = from.documents ?? {};
134
- const currentTargets = new Set(room.binaryTargets ?? []);
135
- const previousTargets = new Set(from.binaryTargets ?? []);
194
+ const currentTargets = new Set(Object.keys(room.binaryFiles ?? {}));
195
+ const previousTargets = new Set(Object.keys(from.binaryFiles ?? {}));
136
196
  const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
197
+ room.fileIds?.[path] !== from.fileIds?.[path] ||
198
+ room.created?.[path] !== from.created?.[path] ||
137
199
  !sameChange(room.changes?.[path], from.changes?.[path]);
138
200
  const changed = Object.keys(current)
139
201
  .filter((path) => current[path] !== previous[path] || headMoved(path))
140
202
  .sort();
141
- const size = pageSize ?? changed.length;
203
+ const size = whole ? changed.length : (pageSize ?? changed.length);
142
204
  const taken = changed.slice(at, at + size);
143
205
  const next = at + taken.length;
144
206
  const opening = at === 0;
@@ -148,27 +210,52 @@ export function createMemoryAdapter(options = {}) {
148
210
  const targets = opening
149
211
  ? [...currentTargets].filter((target) => !previousTargets.has(target) || headMoved(target))
150
212
  : [];
151
- const attachments = room.attachments ?? [];
152
- const declared = opening && JSON.stringify(attachments) !== JSON.stringify(from.attachments ?? []);
153
213
  const models = opening ? changedModels(room, from) : undefined;
154
214
  return {
155
215
  kind: 'net-advancement',
156
216
  roomVersion: room.roomVersion,
157
217
  ...(models === undefined ? {} : { models }),
158
218
  documents: named(current, taken),
159
- revisions: named(room.revisions ?? {}, taken),
219
+ facts: factsIn(room, taken),
220
+ revisions: named(room.revisions ?? {}, [...taken, ...targets]),
221
+ ...(room.fileIds === undefined
222
+ ? {}
223
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
224
+ ...(room.created === undefined
225
+ ? {}
226
+ : { created: named(room.created, [...taken, ...targets]) }),
160
227
  changes: named(room.changes ?? {}, [...taken, ...targets]),
161
- binaryTargets: targets,
228
+ binaryFiles: named(room.binaryFiles ?? {}, targets),
229
+ ...(opening ? foldersMoved(room, from) : {}),
162
230
  removals: opening
163
231
  ? [
164
232
  ...Object.keys(previous).filter((path) => !(path in current) && !currentTargets.has(path)),
165
233
  ...[...previousTargets].filter((target) => !currentTargets.has(target) && !(target in current)),
166
234
  ].sort()
167
235
  : [],
168
- ...(declared ? { attachments } : {}),
169
236
  ...(pageToken === undefined ? {} : { pageToken }),
170
237
  };
171
238
  }
239
+ function carry(locator) {
240
+ const at = carried.get(locator);
241
+ const current = rooms.find((entry) => entry.locator === locator);
242
+ if (at === undefined || current === undefined || current.roomVersion === at)
243
+ return;
244
+ const from = served.get(locator)?.get(at);
245
+ carried.set(locator, current.roomVersion);
246
+ if (from === undefined)
247
+ return;
248
+ const page = advancement(current, from, 0, true);
249
+ for (const observer of observers) {
250
+ observer({
251
+ kind: 'room-change',
252
+ locator,
253
+ from: at,
254
+ roomVersion: current.roomVersion,
255
+ read: async () => page,
256
+ });
257
+ }
258
+ }
172
259
  function pageOf(conversation, after) {
173
260
  const messages = conversation.messages ?? [];
174
261
  const first = typeof after === 'string' ? messages.findIndex((message) => message.position > after) : 0;
@@ -183,16 +270,13 @@ export function createMemoryAdapter(options = {}) {
183
270
  : {}),
184
271
  };
185
272
  }
186
- function historiesOf(input) {
187
- const asked = input?.conversations;
188
- if (!Array.isArray(asked))
189
- return { kind: 'rejected', code: 'invalid_request', fields: {} };
273
+ function historiesOf(request) {
190
274
  const histories = [];
191
- for (const entry of asked) {
192
- const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
275
+ for (const entry of request.conversations) {
276
+ const conversation = scripted.get(entry.conversation);
193
277
  if (conversation === undefined)
194
278
  continue;
195
- const outcome = conversation.outcomes?.['conversation.history'];
279
+ const outcome = conversation.outcomes?.history;
196
280
  if (outcome !== undefined)
197
281
  return outcome;
198
282
  histories.push(pageOf(conversation, entry.after));
@@ -203,52 +287,94 @@ export function createMemoryAdapter(options = {}) {
203
287
  function conversationAction(request) {
204
288
  const name = request.name;
205
289
  const input = (request.input ?? {});
206
- if (name === 'conversation.history')
207
- return historiesOf(request.input);
208
- if (name === 'conversation.create') {
290
+ if (name === 'conversations/create') {
209
291
  issued += 1;
210
292
  const conversation = `conversation-${issued}`;
211
293
  scripted.set(conversation, { conversation });
212
- return { kind: 'action', result: { conversation } };
294
+ return { kind: 'action', result: { conversation_id: conversation } };
213
295
  }
214
- const named = typeof input.conversation === 'string' ? input.conversation : '';
296
+ const named = typeof input.conversation_id === 'string' ? input.conversation_id : '';
215
297
  const conversation = scripted.get(named);
216
298
  if (conversation === undefined) {
217
- return { kind: 'rejected', code: 'unknown-conversation', fields: { conversation: named } };
299
+ return {
300
+ kind: 'rejected',
301
+ code: 'unknown-conversation',
302
+ fields: { conversation: named },
303
+ retryable: false,
304
+ };
218
305
  }
219
306
  const outcome = conversation.outcomes?.[name];
220
307
  if (outcome !== undefined)
221
308
  return outcome;
222
- if (name === 'conversation.send') {
309
+ if (name === 'conversations/send') {
310
+ const operation = typeof input.operation_id === 'string' ? input.operation_id : null;
311
+ const answered = operation === null ? undefined : sentTurns.get(operation);
312
+ if (answered !== undefined)
313
+ return { kind: 'action', result: { message_id: answered } };
223
314
  issued += 1;
224
315
  const turn = `turn-${issued}`;
225
- unsealed.set(turn, named);
226
- return { kind: 'action', result: { turn } };
316
+ if (operation !== null)
317
+ sentTurns.set(operation, turn);
318
+ return { kind: 'action', result: { message_id: turn } };
227
319
  }
228
- if (name === 'conversation.cancel') {
229
- const turn = typeof input.turn === 'string' ? input.turn : '';
230
- if (sealed.has(turn) || !unsealed.has(turn)) {
231
- return { kind: 'rejected', code: 'turn-sealed', fields: { turn } };
232
- }
233
- unsealed.delete(turn);
234
- return { kind: 'action', result: { turn, cancelled: true } };
235
- }
236
- if (name === 'conversation.delete')
320
+ if (name === 'conversations/delete')
237
321
  scripted.delete(named);
238
- return { kind: 'action', result: { conversation: named } };
322
+ return { kind: 'action', result: { conversation_id: named } };
323
+ }
324
+ function announceList() {
325
+ const entries = [...scripted.values()].flatMap(({ conversation, listed, messages = [] }) => listed === undefined
326
+ ? []
327
+ : [{ conversation, ...listed, newest: messages.at(-1)?.position ?? null }]);
328
+ for (const listener of listeners) {
329
+ listener({ kind: 'list', entries, whole: true, more: false, cursor: null });
330
+ }
239
331
  }
240
332
  function discovery() {
241
333
  return {
242
334
  kind: 'discovery',
243
- supportedVersions,
244
- mdModel,
245
335
  rooms: rooms.map(declared),
246
336
  capabilities,
247
337
  providerLimits,
248
338
  retention,
339
+ ...(options.member === undefined ? {} : { member: options.member }),
249
340
  };
250
341
  }
342
+ function discovered() {
343
+ return resolveScript(scripts.discover, discovery, undefined).then((answer) => {
344
+ if (answer.kind === 'discovery')
345
+ for (const room of answer.rooms)
346
+ note(room.locator, room);
347
+ return answer;
348
+ });
349
+ }
350
+ function opened(notify) {
351
+ const opening = ++openings;
352
+ notify({ kind: 'opened' });
353
+ void discovered()
354
+ .catch(() => ({ kind: 'transport-uncertainty' }))
355
+ .then((answer) => {
356
+ if (opening !== openings)
357
+ return;
358
+ if (answer.kind !== 'discovery') {
359
+ openings += 1;
360
+ carried.clear();
361
+ const revoked = answer.kind === 'revoked-authorization';
362
+ notify({ kind: 'closed', revoked, lost: !revoked, authorityChanged: false });
363
+ return;
364
+ }
365
+ declaredRooms.clear();
366
+ for (const room of answer.rooms)
367
+ declaredRooms.add(room.locator);
368
+ notify({ kind: 'discovered', discovery: answer });
369
+ });
370
+ }
371
+ function emitAll(event) {
372
+ for (const observer of observers)
373
+ observer(event);
374
+ }
251
375
  return {
376
+ ...(options.roomTypes === undefined ? {} : { roomTypes: options.roomTypes }),
377
+ ...(options.typedPaths === undefined ? {} : { typedPaths: options.typedPaths }),
252
378
  setRooms(next) {
253
379
  rooms = [...next];
254
380
  retain(rooms);
@@ -257,25 +383,37 @@ export function createMemoryAdapter(options = {}) {
257
383
  scriptConversations(next);
258
384
  },
259
385
  open() {
260
- for (const observer of observers)
261
- observer({ kind: 'opened' });
386
+ carried.clear();
387
+ announceList();
388
+ opened(emitAll);
262
389
  },
263
- close(revoked = false) {
264
- for (const observer of observers)
265
- observer({ kind: 'closed', revoked });
390
+ close({ revoked = false, lost = !revoked, authorityChanged = false } = {}) {
391
+ openings += 1;
392
+ carried.clear();
393
+ emitAll({ kind: 'closed', revoked, lost, authorityChanged });
266
394
  },
267
395
  expire(locators) {
268
396
  expiring = [...locators];
269
397
  },
270
- notifyRoomVersion({ locator, roomVersion }) {
271
- for (const observer of observers)
272
- observer({ kind: 'room-version', locator, roomVersion });
398
+ notifyRoomVersion({ locator }) {
399
+ carry(locator);
400
+ },
401
+ notifyAuthorityChanged(locators) {
402
+ const named = new Set(locators ?? [...declaredRooms, ...rooms.map((room) => room.locator)]);
403
+ const listed = rooms.filter((room) => named.has(room.locator));
404
+ const left = [...named].filter((locator) => !listed.some((room) => room.locator === locator));
405
+ for (const room of listed)
406
+ declaredRooms.add(room.locator);
407
+ for (const locator of left)
408
+ declaredRooms.delete(locator);
409
+ emitAll({
410
+ kind: 'authority-changed',
411
+ rooms: listed.map(declared),
412
+ left,
413
+ ...(options.member === undefined ? {} : { member: options.member }),
414
+ });
273
415
  },
274
416
  notifyConversation(event) {
275
- if (event.kind === 'accepted-message') {
276
- sealed.add(event.message.turn);
277
- unsealed.delete(event.message.turn);
278
- }
279
417
  for (const listener of listeners)
280
418
  listener(event);
281
419
  },
@@ -284,21 +422,31 @@ export function createMemoryAdapter(options = {}) {
284
422
  observer(mode);
285
423
  },
286
424
  heldRooms() {
287
- return held;
425
+ return [...carried.keys()].sort();
288
426
  },
289
427
  replicatedConversations() {
290
428
  return replicated;
291
429
  },
430
+ heldConversationCursor() {
431
+ return heldCursor;
432
+ },
292
433
  conversations: {
293
434
  replicate(next) {
294
435
  replicated = [...next];
295
436
  },
437
+ hold(cursor) {
438
+ heldCursor = cursor;
439
+ },
296
440
  observe(notify) {
297
441
  listeners.add(notify);
298
442
  return () => {
299
443
  listeners.delete(notify);
300
444
  };
301
445
  },
446
+ history: (request) => Promise.resolve(historiesOf(request)),
447
+ ...(options.agents === undefined
448
+ ? {}
449
+ : { agents: () => Promise.resolve(structuredClone(options.agents)) }),
302
450
  },
303
451
  serviceMode: {
304
452
  observe(notify) {
@@ -310,23 +458,30 @@ export function createMemoryAdapter(options = {}) {
310
458
  },
311
459
  roomStream: {
312
460
  hold(asked) {
313
- held = asked.map((room) => room.locator);
314
- const expired = expiring.filter((locator) => held.includes(locator));
315
- expiring = [];
316
- const moved = asked.flatMap((room) => {
461
+ const named = asked.map((room) => room.locator);
462
+ const unknown = asked.flatMap((room) => {
317
463
  const current = rooms.find((entry) => entry.locator === room.locator);
464
+ const version = room.roomVersion;
318
465
  return current === undefined ||
319
- expired.includes(room.locator) ||
320
- current.roomVersion === room.roomVersion
466
+ (version !== null &&
467
+ (current.roomVersion === version || served.get(room.locator)?.has(version) === true))
321
468
  ? []
322
- : [{ locator: room.locator, roomVersion: current.roomVersion }];
469
+ : [room.locator];
323
470
  });
471
+ const expired = [
472
+ ...new Set([...expiring.filter((locator) => named.includes(locator)), ...unknown]),
473
+ ];
474
+ expiring = expiring.filter((locator) => !named.includes(locator));
324
475
  queueMicrotask(() => {
325
- for (const observer of observers) {
326
- for (const room of moved)
327
- observer({ kind: 'room-version', ...room });
328
- observer({ kind: 'opening', expired });
476
+ for (const room of asked) {
477
+ if (expired.includes(room.locator) || room.roomVersion === null)
478
+ carried.delete(room.locator);
479
+ else {
480
+ carried.set(room.locator, room.roomVersion);
481
+ carry(room.locator);
482
+ }
329
483
  }
484
+ emitAll({ kind: 'caught-up', expired });
330
485
  });
331
486
  },
332
487
  observe(notify) {
@@ -334,7 +489,15 @@ export function createMemoryAdapter(options = {}) {
334
489
  queueMicrotask(() => {
335
490
  if (!observers.has(notify))
336
491
  return;
337
- notify(options.unopened === true ? { kind: 'closed', revoked: false } : { kind: 'opened' });
492
+ if (options.unopened === true) {
493
+ notify({ kind: 'closed', revoked: false, lost: true, authorityChanged: false });
494
+ return;
495
+ }
496
+ announceList();
497
+ opened((event) => {
498
+ if (observers.has(notify))
499
+ notify(event);
500
+ });
338
501
  });
339
502
  return () => {
340
503
  observers.delete(notify);
@@ -351,12 +514,7 @@ export function createMemoryAdapter(options = {}) {
351
514
  return resolveScript(scripts.authorize, () => ({}), undefined);
352
515
  },
353
516
  async discover(_authorization) {
354
- return resolveScript(scripts.discover, discovery, undefined).then((answer) => {
355
- if (answer.kind === 'discovery')
356
- for (const room of answer.rooms)
357
- note(room.locator, room);
358
- return answer;
359
- });
517
+ return discovered();
360
518
  },
361
519
  reached,
362
520
  follows(locator, roomVersion, next) {
@@ -373,7 +531,7 @@ export function createMemoryAdapter(options = {}) {
373
531
  if (room === undefined) {
374
532
  return { kind: 'room-not-readable', locator: request.locator };
375
533
  }
376
- return page(room, request.pageToken === undefined ? 0 : Number(request.pageToken));
534
+ return page(room, request.pageToken);
377
535
  }, request).then((answer) => note(request.locator, answer));
378
536
  },
379
537
  async refresh(_authorization, request) {
@@ -406,8 +564,20 @@ export function createMemoryAdapter(options = {}) {
406
564
  if (room === undefined) {
407
565
  return { kind: 'room-not-readable', locator: request.locator };
408
566
  }
409
- return { kind: 'rejected', code: 'unscripted-mutation', fields: {}, affected: {} };
410
- }, request).then((answer) => note(request.locator, answer));
567
+ return {
568
+ kind: 'rejected',
569
+ code: 'unscripted-mutation',
570
+ fields: {},
571
+ retryable: false,
572
+ affected: {},
573
+ };
574
+ }, request).then((answer) => {
575
+ const destination = request.changeBatch.between?.destination.room;
576
+ if (answer.kind === 'accepted' && answer.destination !== undefined && destination) {
577
+ note(destination, answer.destination);
578
+ }
579
+ return note(request.locator, answer);
580
+ });
411
581
  },
412
582
  async history(_authorization, request) {
413
583
  return resolveScript(scripts.history, () => {
@@ -421,11 +591,46 @@ export function createMemoryAdapter(options = {}) {
421
591
  };
422
592
  }, request);
423
593
  },
594
+ async binary(_authorization, request) {
595
+ return resolveScript(scripts.binary, () => {
596
+ const room = rooms.find((entry) => entry.locator === request.locator);
597
+ if (room === undefined)
598
+ return { kind: 'room-not-readable', locator: request.locator };
599
+ const blob = heldBlob(room, request.path);
600
+ return blob === undefined
601
+ ? { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false }
602
+ : { kind: 'binary', body: blob.stream(), mediaType: blob.type };
603
+ }, request);
604
+ },
605
+ async link(_authorization, request) {
606
+ return resolveScript(scripts.link, () => {
607
+ const room = rooms.find((entry) => entry.locator === request.locator);
608
+ if (room === undefined)
609
+ return { kind: 'room-not-readable', locator: request.locator };
610
+ const blob = heldBlob(room, request.path);
611
+ if (blob === undefined) {
612
+ return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
613
+ }
614
+ const url = linked.get(blob) ?? URL.createObjectURL(blob);
615
+ linked.set(blob, url);
616
+ return { kind: 'link', url, name: lastName(request.path), mediaType: blob.type };
617
+ }, request);
618
+ },
619
+ async attach(_authorization, request) {
620
+ return resolveScript(scripts.attach, () => {
621
+ const room = rooms.find((entry) => entry.locator === request.locator);
622
+ if (room === undefined)
623
+ return { kind: 'room-not-readable', locator: request.locator };
624
+ const path = freePath(room, request.name);
625
+ attached.set(`${room.locator}\u0000${path}`, request.blob);
626
+ return { kind: 'attached', path, revision: `attached-${attached.size}` };
627
+ }, request);
628
+ },
424
629
  async action(_authorization, request) {
425
630
  return resolveScript(scripts.action, () => {
426
- if (request.name.startsWith('conversation.'))
631
+ if (request.name.startsWith('conversations/'))
427
632
  return conversationAction(request);
428
- return { kind: 'rejected', code: 'unscripted-action', fields: {} };
633
+ return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
429
634
  }, request).then((answer) => {
430
635
  if (answer.kind === 'action' && answer.at !== undefined)
431
636
  note(answer.at.locator, answer.at);
@@ -0,0 +1,52 @@
1
+ import type { AcceptedMessage } from './adapter.js';
2
+ import type { JobMarker } from './job.js';
3
+ import type { Connection } from './tables.js';
4
+ export declare const MESSAGE_TABLES: readonly string[];
5
+ export declare const ROWS = "WITH chosen AS (\n SELECT listed.value AS conversation,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND json_extract(message, '$.role') = 'assistant' ORDER BY position DESC, identity DESC LIMIT 1) AS answer,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND text <> '' ORDER BY position DESC, identity DESC LIMIT 1) AS said,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND json_extract(message, '$.role') = 'house' ORDER BY position, identity LIMIT 1) AS opened,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND json_extract(message, '$.role') = 'house' AND json_extract(message, '$.waiting') = 1 ORDER BY position, identity LIMIT 1) AS asking\n FROM json_each(?) AS listed\n )\n SELECT chosen.conversation AS conversation,\n substr(said.text, 1, 512) AS said_text,\n json_extract(said.message, '$.role') AS said_role,\n json_extract(said.message, '$.accepted_at') AS said_at,\n substr(json_extract(answer.message, '$.failure'), 1, 512) AS failure,\n json_extract(opened.message, '$.source') AS opened_source,\n json_extract(opened.message, '$.sender') AS opened_sender,\n asking.identity AS asking_identity,\n substr(asking.text, 1, 512) AS asking_text,\n json_extract(asking.message, '$.accepted_at') AS asking_at,\n json_extract(asking.message, '$.source') AS asking_source,\n json_extract(asking.message, '$.sender') AS asking_sender\n FROM chosen\n LEFT JOIN conversation_messages said ON said.id = chosen.said\n LEFT JOIN conversation_messages answer ON answer.id = chosen.answer\n LEFT JOIN conversation_messages opened ON opened.id = chosen.opened\n LEFT JOIN conversation_messages asking ON asking.id = chosen.asking";
6
+ export declare const JOB_MARKERS = "SELECT json_extract(part.value, '$.text') AS said,\n json_extract(message, '$.accepted_at') AS at\n FROM conversation_messages, json_each(message, '$.parts') AS part\n WHERE conversation = ? AND instr(message, '\"marker\":\"job\"') > 0\n AND json_extract(part.value, '$.type') = 'marker'\n AND json_extract(part.value, '$.marker') = 'job'\n ORDER BY position, identity, part.key";
7
+ export type HeldConversation = {
8
+ readonly conversation: string;
9
+ readonly read: string | null | undefined;
10
+ readonly partial: boolean;
11
+ };
12
+ export type MessageWindow = {
13
+ readonly messages: AcceptedMessage[];
14
+ readonly more: boolean;
15
+ };
16
+ export type HeldSource = {
17
+ readonly source: unknown;
18
+ readonly sender: string | null;
19
+ };
20
+ export type HeldRow = {
21
+ readonly conversation: string;
22
+ readonly said: {
23
+ readonly text: string;
24
+ readonly role: string | null;
25
+ readonly at: string | null;
26
+ } | null;
27
+ readonly failure: string | null;
28
+ readonly opened: HeldSource | null;
29
+ readonly asking: (HeldSource & {
30
+ readonly identity: string;
31
+ readonly text: string;
32
+ readonly at: string | null;
33
+ }) | null;
34
+ };
35
+ export type ConversationWrite = {
36
+ readonly conversation: string;
37
+ readonly messages: readonly AcceptedMessage[];
38
+ readonly read?: {
39
+ readonly at: string | null;
40
+ readonly partial: boolean;
41
+ };
42
+ };
43
+ export declare function heldConversations(connection: Connection, conversations: readonly string[] | null): HeldConversation[];
44
+ export declare function keptMessages(connection: Connection, { conversation, messages, read }: ConversationWrite): null;
45
+ export declare function messageWindow(connection: Connection, conversation: string, limit: number, before: readonly [string, string] | null, phrase: string | null): MessageWindow;
46
+ export declare function messageCount(connection: Connection, conversation: string, phrase: string | null): number;
47
+ export declare function conversationRows(connection: Connection, conversations: readonly string[]): HeldRow[];
48
+ export declare function jobMarkers(connection: Connection, conversation: string): JobMarker[];
49
+ export declare function turnArrived(connection: Connection, conversation: string, turn: string): boolean;
50
+ export declare function droppedMessages(connection: Connection, conversations: readonly string[]): void;
51
+ export declare function forgottenMessages(connection: Connection): void;
52
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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"}