@agentshouse/mdruntime 0.1.0-cefbc8bb8a1c0 → 0.1.0-cf08ada271a7f

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 (303) hide show
  1. package/README.md +10 -10
  2. package/dist/acceptance.d.ts +3 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +309 -0
  5. package/dist/actions.d.ts +20 -0
  6. package/dist/actions.d.ts.map +1 -0
  7. package/dist/actions.js +251 -0
  8. package/dist/adapter.d.ts +95 -104
  9. package/dist/adapter.d.ts.map +1 -1
  10. package/dist/attached-model.d.ts +3 -10
  11. package/dist/attached-model.d.ts.map +1 -1
  12. package/dist/attached-model.js +21 -56
  13. package/dist/bootstrap.d.ts +11 -10
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +205 -88
  16. package/dist/cell.d.ts +6 -0
  17. package/dist/cell.d.ts.map +1 -0
  18. package/dist/cell.js +9 -0
  19. package/dist/chain.d.ts +2 -1
  20. package/dist/chain.d.ts.map +1 -1
  21. package/dist/change-set.d.ts +4 -0
  22. package/dist/change-set.d.ts.map +1 -1
  23. package/dist/change-set.js +6 -0
  24. package/dist/change.d.ts +1 -0
  25. package/dist/change.d.ts.map +1 -1
  26. package/dist/change.js +4 -2
  27. package/dist/chat-types.d.ts +5 -0
  28. package/dist/chat-types.d.ts.map +1 -0
  29. package/dist/chat-types.js +13 -0
  30. package/dist/client.d.ts +24 -7
  31. package/dist/client.d.ts.map +1 -1
  32. package/dist/client.js +9 -5
  33. package/dist/collection.d.ts +23 -7
  34. package/dist/collection.d.ts.map +1 -1
  35. package/dist/collection.js +13 -19
  36. package/dist/compile.d.ts +6 -6
  37. package/dist/compile.d.ts.map +1 -1
  38. package/dist/compile.js +272 -334
  39. package/dist/connection.d.ts +5 -143
  40. package/dist/connection.d.ts.map +1 -1
  41. package/dist/connection.js +101 -5310
  42. package/dist/context.d.ts +2 -0
  43. package/dist/context.d.ts.map +1 -0
  44. package/dist/context.js +7 -0
  45. package/dist/conversation-live.d.ts +135 -0
  46. package/dist/conversation-live.d.ts.map +1 -0
  47. package/dist/conversation-live.js +247 -0
  48. package/dist/conversation-row.d.ts +33 -0
  49. package/dist/conversation-row.d.ts.map +1 -0
  50. package/dist/conversation-row.js +53 -0
  51. package/dist/conversation.d.ts +41 -47
  52. package/dist/conversation.d.ts.map +1 -1
  53. package/dist/conversation.js +873 -912
  54. package/dist/declaration.d.ts +10 -0
  55. package/dist/declaration.d.ts.map +1 -0
  56. package/dist/declaration.js +24 -0
  57. package/dist/discovery.d.ts +10 -0
  58. package/dist/discovery.d.ts.map +1 -0
  59. package/dist/discovery.js +177 -0
  60. package/dist/durability.d.ts +15 -1
  61. package/dist/durability.d.ts.map +1 -1
  62. package/dist/entry.d.ts +2 -2
  63. package/dist/entry.d.ts.map +1 -1
  64. package/dist/entry.js +17 -7
  65. package/dist/expectation.d.ts +4 -2
  66. package/dist/expectation.d.ts.map +1 -1
  67. package/dist/expectation.js +33 -11
  68. package/dist/failure.d.ts +1 -0
  69. package/dist/failure.d.ts.map +1 -1
  70. package/dist/failure.js +3 -0
  71. package/dist/figures.d.ts +49 -0
  72. package/dist/figures.d.ts.map +1 -0
  73. package/dist/figures.js +197 -0
  74. package/dist/holdings.d.ts +29 -0
  75. package/dist/holdings.d.ts.map +1 -0
  76. package/dist/holdings.js +95 -0
  77. package/dist/host.d.ts +20 -8
  78. package/dist/host.d.ts.map +1 -1
  79. package/dist/host.js +38 -33
  80. package/dist/identity.d.ts +0 -1
  81. package/dist/identity.d.ts.map +1 -1
  82. package/dist/identity.js +0 -3
  83. package/dist/index.d.ts +27 -8
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +9 -1
  86. package/dist/install.d.ts +55 -0
  87. package/dist/install.d.ts.map +1 -0
  88. package/dist/install.js +543 -0
  89. package/dist/job.d.ts +5 -0
  90. package/dist/job.d.ts.map +1 -0
  91. package/dist/job.js +7 -0
  92. package/dist/lifecycle.d.ts +7 -0
  93. package/dist/lifecycle.d.ts.map +1 -0
  94. package/dist/lifecycle.js +271 -0
  95. package/dist/listing.d.ts +53 -0
  96. package/dist/listing.d.ts.map +1 -0
  97. package/dist/listing.js +169 -0
  98. package/dist/live.d.ts +5 -4
  99. package/dist/live.d.ts.map +1 -1
  100. package/dist/live.js +64 -23
  101. package/dist/locks.d.ts +9 -0
  102. package/dist/locks.d.ts.map +1 -0
  103. package/dist/locks.js +62 -0
  104. package/dist/log.d.ts +1 -0
  105. package/dist/log.d.ts.map +1 -1
  106. package/dist/lost.d.ts +5 -0
  107. package/dist/lost.d.ts.map +1 -0
  108. package/dist/lost.js +61 -0
  109. package/dist/media.d.ts +1 -1
  110. package/dist/media.d.ts.map +1 -1
  111. package/dist/media.js +3 -3
  112. package/dist/memory.d.ts +14 -5
  113. package/dist/memory.d.ts.map +1 -1
  114. package/dist/memory.js +177 -85
  115. package/dist/messages.d.ts +24 -3
  116. package/dist/messages.d.ts.map +1 -1
  117. package/dist/messages.js +89 -31
  118. package/dist/model.d.ts +2 -11
  119. package/dist/model.d.ts.map +1 -1
  120. package/dist/model.js +0 -23
  121. package/dist/models.d.ts +10 -0
  122. package/dist/models.d.ts.map +1 -0
  123. package/dist/models.js +170 -0
  124. package/dist/observation.d.ts +2 -2
  125. package/dist/observation.d.ts.map +1 -1
  126. package/dist/observation.js +14 -14
  127. package/dist/opened.js +3 -3
  128. package/dist/opening.d.ts +4 -0
  129. package/dist/opening.d.ts.map +1 -0
  130. package/dist/opening.js +59 -0
  131. package/dist/outcome.d.ts +4 -4
  132. package/dist/outcome.d.ts.map +1 -1
  133. package/dist/outcome.js +3 -0
  134. package/dist/overlay.d.ts +3 -1
  135. package/dist/overlay.d.ts.map +1 -1
  136. package/dist/overlay.js +43 -21
  137. package/dist/parts.d.ts +11 -0
  138. package/dist/parts.d.ts.map +1 -0
  139. package/dist/parts.js +21 -0
  140. package/dist/paths.d.ts +1 -0
  141. package/dist/paths.d.ts.map +1 -1
  142. package/dist/paths.js +22 -0
  143. package/dist/preparation.d.ts +20 -0
  144. package/dist/preparation.d.ts.map +1 -0
  145. package/dist/preparation.js +233 -0
  146. package/dist/queries.d.ts +16 -0
  147. package/dist/queries.d.ts.map +1 -0
  148. package/dist/queries.js +272 -0
  149. package/dist/query.d.ts +14 -210
  150. package/dist/query.d.ts.map +1 -1
  151. package/dist/query.js +3 -505
  152. package/dist/questions.d.ts +34 -0
  153. package/dist/questions.d.ts.map +1 -0
  154. package/dist/questions.js +122 -0
  155. package/dist/queue.d.ts +39 -0
  156. package/dist/queue.d.ts.map +1 -0
  157. package/dist/queue.js +455 -0
  158. package/dist/reach.d.ts +15 -13
  159. package/dist/reach.d.ts.map +1 -1
  160. package/dist/reach.js +187 -140
  161. package/dist/react.d.ts +14 -2
  162. package/dist/react.d.ts.map +1 -1
  163. package/dist/react.js +10 -1
  164. package/dist/read.d.ts +7 -0
  165. package/dist/read.d.ts.map +1 -0
  166. package/dist/read.js +17 -0
  167. package/dist/readiness.d.ts +2 -16
  168. package/dist/readiness.d.ts.map +1 -1
  169. package/dist/readiness.js +4 -10
  170. package/dist/reads.d.ts +36 -10
  171. package/dist/reads.d.ts.map +1 -1
  172. package/dist/reads.js +160 -77
  173. package/dist/recovery.d.ts.map +1 -1
  174. package/dist/recovery.js +9 -1
  175. package/dist/refresh.d.ts +7 -5
  176. package/dist/refresh.d.ts.map +1 -1
  177. package/dist/refresh.js +35 -7
  178. package/dist/refusal.d.ts +5 -0
  179. package/dist/refusal.d.ts.map +1 -0
  180. package/dist/refusal.js +57 -0
  181. package/dist/replica.d.ts +11 -17
  182. package/dist/replica.d.ts.map +1 -1
  183. package/dist/replica.js +64 -34
  184. package/dist/room-draft.d.ts +7 -8
  185. package/dist/room-draft.d.ts.map +1 -1
  186. package/dist/room-draft.js +100 -103
  187. package/dist/room-drafts.d.ts +24 -0
  188. package/dist/room-drafts.d.ts.map +1 -0
  189. package/dist/room-drafts.js +217 -0
  190. package/dist/rows.d.ts +14 -21
  191. package/dist/rows.d.ts.map +1 -1
  192. package/dist/rows.js +49 -186
  193. package/dist/runtime.d.ts +32 -0
  194. package/dist/runtime.d.ts.map +1 -0
  195. package/dist/runtime.js +1 -0
  196. package/dist/save.d.ts +41 -86
  197. package/dist/save.d.ts.map +1 -1
  198. package/dist/save.js +239 -116
  199. package/dist/saves.d.ts +32 -0
  200. package/dist/saves.d.ts.map +1 -0
  201. package/dist/saves.js +413 -0
  202. package/dist/search.d.ts +12 -63
  203. package/dist/search.d.ts.map +1 -1
  204. package/dist/search.js +9 -52
  205. package/dist/seed.d.ts +11 -2
  206. package/dist/seed.d.ts.map +1 -1
  207. package/dist/seed.js +71 -1
  208. package/dist/shared.d.ts +1 -7
  209. package/dist/shared.d.ts.map +1 -1
  210. package/dist/shared.js +13 -105
  211. package/dist/shown.d.ts +32 -0
  212. package/dist/shown.d.ts.map +1 -0
  213. package/dist/shown.js +299 -0
  214. package/dist/socket/admission.d.ts +7 -0
  215. package/dist/socket/admission.d.ts.map +1 -0
  216. package/dist/socket/admission.js +39 -0
  217. package/dist/socket/answers.d.ts +6 -0
  218. package/dist/socket/answers.d.ts.map +1 -0
  219. package/dist/socket/answers.js +20 -0
  220. package/dist/socket/lanes.d.ts +20 -0
  221. package/dist/socket/lanes.d.ts.map +1 -0
  222. package/dist/socket/lanes.js +77 -0
  223. package/dist/socket/reads.d.ts +10 -0
  224. package/dist/socket/reads.d.ts.map +1 -0
  225. package/dist/socket/reads.js +31 -0
  226. package/dist/socket/rooms.d.ts +41 -0
  227. package/dist/socket/rooms.d.ts.map +1 -0
  228. package/dist/socket/rooms.js +90 -0
  229. package/dist/socket/session.d.ts +38 -0
  230. package/dist/socket/session.d.ts.map +1 -0
  231. package/dist/socket/session.js +23 -0
  232. package/dist/socket.d.ts +69 -0
  233. package/dist/socket.d.ts.map +1 -0
  234. package/dist/socket.js +175 -0
  235. package/dist/source.d.ts +61 -0
  236. package/dist/source.d.ts.map +1 -0
  237. package/dist/source.js +82 -0
  238. package/dist/status.d.ts +0 -6
  239. package/dist/status.d.ts.map +1 -1
  240. package/dist/status.js +0 -6
  241. package/dist/store/fences.d.ts +16 -0
  242. package/dist/store/fences.d.ts.map +1 -0
  243. package/dist/store/fences.js +26 -0
  244. package/dist/store/installs.d.ts +30 -0
  245. package/dist/store/installs.d.ts.map +1 -0
  246. package/dist/store/installs.js +34 -0
  247. package/dist/store/readiness.d.ts +10 -0
  248. package/dist/store/readiness.d.ts.map +1 -0
  249. package/dist/store/readiness.js +52 -0
  250. package/dist/store/records.d.ts +210 -0
  251. package/dist/store/records.d.ts.map +1 -0
  252. package/dist/store/records.js +428 -0
  253. package/dist/store/room-held.d.ts +8 -0
  254. package/dist/store/room-held.d.ts.map +1 -0
  255. package/dist/store/room-held.js +17 -0
  256. package/dist/store/space.d.ts +11 -0
  257. package/dist/store/space.d.ts.map +1 -0
  258. package/dist/store/space.js +41 -0
  259. package/dist/store/watchers.d.ts +17 -0
  260. package/dist/store/watchers.d.ts.map +1 -0
  261. package/dist/store/watchers.js +56 -0
  262. package/dist/store/writes.d.ts +24 -0
  263. package/dist/store/writes.d.ts.map +1 -0
  264. package/dist/store/writes.js +125 -0
  265. package/dist/store.d.ts +107 -157
  266. package/dist/store.d.ts.map +1 -1
  267. package/dist/store.js +143 -395
  268. package/dist/stored.d.ts +59 -38
  269. package/dist/stored.d.ts.map +1 -1
  270. package/dist/stored.js +279 -210
  271. package/dist/surface.d.ts +88 -0
  272. package/dist/surface.d.ts.map +1 -0
  273. package/dist/surface.js +224 -0
  274. package/dist/sync.d.ts +19 -0
  275. package/dist/sync.d.ts.map +1 -0
  276. package/dist/sync.js +530 -0
  277. package/dist/tables.d.ts +116 -56
  278. package/dist/tables.d.ts.map +1 -1
  279. package/dist/tables.js +214 -98
  280. package/dist/tallies.d.ts +18 -0
  281. package/dist/tallies.d.ts.map +1 -0
  282. package/dist/tallies.js +129 -0
  283. package/dist/transfer.d.ts +0 -5
  284. package/dist/transfer.d.ts.map +1 -1
  285. package/dist/validation.d.ts +3 -4
  286. package/dist/validation.d.ts.map +1 -1
  287. package/dist/validation.js +42 -100
  288. package/dist/windows.d.ts +1 -12
  289. package/dist/windows.d.ts.map +1 -1
  290. package/dist/windows.js +2 -75
  291. package/dist/wire.d.ts +21 -9
  292. package/dist/wire.d.ts.map +1 -1
  293. package/dist/wire.js +10 -4
  294. package/package.json +3 -2
  295. package/dist/fence.d.ts +0 -6
  296. package/dist/fence.d.ts.map +0 -1
  297. package/dist/fence.js +0 -10
  298. package/dist/fulltext.d.ts +0 -27
  299. package/dist/fulltext.d.ts.map +0 -1
  300. package/dist/fulltext.js +0 -370
  301. package/dist/words.d.ts +0 -19
  302. package/dist/words.d.ts.map +0 -1
  303. package/dist/words.js +0 -156
package/dist/memory.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { definitionAt, documentFacts, parse } 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,37 @@ 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, parse(content, path, definitionAt({ types }, path, options.typedPaths)), {
117
+ types,
118
+ });
119
+ held.set(key, facts === null ? null : JSON.parse(JSON.stringify(facts)));
120
+ }
121
+ return held.get(key);
122
+ }
123
+ function factsIn(room, paths) {
124
+ const facts = {};
125
+ for (const path of paths) {
126
+ const content = room.documents?.[path];
127
+ const held = room.facts?.[path] ?? (content === undefined ? null : factsAt(room, path, content));
128
+ if (held !== null)
129
+ facts[path] = held;
130
+ }
131
+ return facts;
132
+ }
104
133
  function retain(entries) {
105
134
  for (const room of entries) {
135
+ for (const [path, content] of Object.entries(room.documents ?? {}))
136
+ factsAt(room, path, content);
106
137
  note(room.locator, room);
107
138
  const versions = served.get(room.locator) ?? new Map();
108
139
  versions.set(room.roomVersion, room);
@@ -118,8 +149,9 @@ export function createMemoryAdapter(options = {}) {
118
149
  roomVersion: room.roomVersion,
119
150
  operations: room.operations,
120
151
  replica: room.replica,
121
- ...(room.typedSelection === undefined ? {} : { typedSelection: room.typedSelection }),
152
+ typedSelection: room.typedSelection ?? null,
122
153
  providerOwnedPaths: room.providerOwnedPaths,
154
+ authoredPaths: room.authoredPaths ?? ['**'],
123
155
  };
124
156
  }
125
157
  function page(room, after) {
@@ -135,10 +167,14 @@ export function createMemoryAdapter(options = {}) {
135
167
  roomVersion: room.roomVersion,
136
168
  ...(opening ? { models: modelsOf(room) } : {}),
137
169
  documents: named(room.documents ?? {}, taken),
170
+ facts: factsIn(room, taken),
138
171
  revisions: named(room.revisions ?? {}, [...taken, ...targets]),
139
172
  ...(room.fileIds === undefined
140
173
  ? {}
141
174
  : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
175
+ ...(room.created === undefined
176
+ ? {}
177
+ : { created: named(room.created, [...taken, ...targets]) }),
142
178
  changes: named(room.changes ?? {}, [...taken, ...targets]),
143
179
  binaryFiles: named(room.binaryFiles ?? {}, targets),
144
180
  ...(opening && room.folders !== undefined ? { folders: room.folders } : {}),
@@ -155,18 +191,19 @@ export function createMemoryAdapter(options = {}) {
155
191
  ...(folderRemovals.length === 0 ? {} : { folderRemovals }),
156
192
  };
157
193
  }
158
- function advancement(room, from, at) {
194
+ function advancement(room, from, at, whole = false) {
159
195
  const current = room.documents ?? {};
160
196
  const previous = from.documents ?? {};
161
197
  const currentTargets = new Set(Object.keys(room.binaryFiles ?? {}));
162
198
  const previousTargets = new Set(Object.keys(from.binaryFiles ?? {}));
163
199
  const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
164
200
  room.fileIds?.[path] !== from.fileIds?.[path] ||
201
+ room.created?.[path] !== from.created?.[path] ||
165
202
  !sameChange(room.changes?.[path], from.changes?.[path]);
166
203
  const changed = Object.keys(current)
167
204
  .filter((path) => current[path] !== previous[path] || headMoved(path))
168
205
  .sort();
169
- const size = pageSize ?? changed.length;
206
+ const size = whole ? changed.length : (pageSize ?? changed.length);
170
207
  const taken = changed.slice(at, at + size);
171
208
  const next = at + taken.length;
172
209
  const opening = at === 0;
@@ -182,10 +219,14 @@ export function createMemoryAdapter(options = {}) {
182
219
  roomVersion: room.roomVersion,
183
220
  ...(models === undefined ? {} : { models }),
184
221
  documents: named(current, taken),
222
+ facts: factsIn(room, taken),
185
223
  revisions: named(room.revisions ?? {}, [...taken, ...targets]),
186
224
  ...(room.fileIds === undefined
187
225
  ? {}
188
226
  : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
227
+ ...(room.created === undefined
228
+ ? {}
229
+ : { created: named(room.created, [...taken, ...targets]) }),
189
230
  changes: named(room.changes ?? {}, [...taken, ...targets]),
190
231
  binaryFiles: named(room.binaryFiles ?? {}, targets),
191
232
  ...(opening ? foldersMoved(room, from) : {}),
@@ -198,6 +239,26 @@ export function createMemoryAdapter(options = {}) {
198
239
  ...(pageToken === undefined ? {} : { pageToken }),
199
240
  };
200
241
  }
242
+ function carry(locator) {
243
+ const at = carried.get(locator);
244
+ const current = rooms.find((entry) => entry.locator === locator);
245
+ if (at === undefined || current === undefined || current.roomVersion === at)
246
+ return;
247
+ const from = served.get(locator)?.get(at);
248
+ carried.set(locator, current.roomVersion);
249
+ if (from === undefined)
250
+ return;
251
+ const page = advancement(current, from, 0, true);
252
+ for (const observer of observers) {
253
+ observer({
254
+ kind: 'room-change',
255
+ locator,
256
+ from: at,
257
+ roomVersion: current.roomVersion,
258
+ read: async () => page,
259
+ });
260
+ }
261
+ }
201
262
  function pageOf(conversation, after) {
202
263
  const messages = conversation.messages ?? [];
203
264
  const first = typeof after === 'string' ? messages.findIndex((message) => message.position > after) : 0;
@@ -212,16 +273,13 @@ export function createMemoryAdapter(options = {}) {
212
273
  : {}),
213
274
  };
214
275
  }
215
- function historiesOf(input) {
216
- const asked = input?.conversations;
217
- if (!Array.isArray(asked))
218
- return { kind: 'rejected', code: 'invalid_request', fields: {}, retryable: false };
276
+ function historiesOf(request) {
219
277
  const histories = [];
220
- for (const entry of asked) {
221
- const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
278
+ for (const entry of request.conversations) {
279
+ const conversation = scripted.get(entry.conversation);
222
280
  if (conversation === undefined)
223
281
  continue;
224
- const outcome = conversation.outcomes?.['conversation.history'];
282
+ const outcome = conversation.outcomes?.history;
225
283
  if (outcome !== undefined)
226
284
  return outcome;
227
285
  histories.push(pageOf(conversation, entry.after));
@@ -232,15 +290,13 @@ export function createMemoryAdapter(options = {}) {
232
290
  function conversationAction(request) {
233
291
  const name = request.name;
234
292
  const input = (request.input ?? {});
235
- if (name === 'conversation.history')
236
- return historiesOf(request.input);
237
- if (name === 'conversation.create') {
293
+ if (name === 'conversations/create') {
238
294
  issued += 1;
239
295
  const conversation = `conversation-${issued}`;
240
296
  scripted.set(conversation, { conversation });
241
- return { kind: 'action', result: { conversation } };
297
+ return { kind: 'action', result: { conversation_id: conversation } };
242
298
  }
243
- const named = typeof input.conversation === 'string' ? input.conversation : '';
299
+ const named = typeof input.conversation_id === 'string' ? input.conversation_id : '';
244
300
  const conversation = scripted.get(named);
245
301
  if (conversation === undefined) {
246
302
  return {
@@ -253,36 +309,28 @@ export function createMemoryAdapter(options = {}) {
253
309
  const outcome = conversation.outcomes?.[name];
254
310
  if (outcome !== undefined)
255
311
  return outcome;
256
- if (name === 'conversation.send') {
312
+ if (name === 'conversations/send') {
257
313
  const operation = typeof input.operation_id === 'string' ? input.operation_id : null;
258
314
  const answered = operation === null ? undefined : sentTurns.get(operation);
259
315
  if (answered !== undefined)
260
- return { kind: 'action', result: { turn: answered } };
316
+ return { kind: 'action', result: { message_id: answered } };
261
317
  issued += 1;
262
318
  const turn = `turn-${issued}`;
263
- unsealed.set(turn, named);
264
319
  if (operation !== null)
265
320
  sentTurns.set(operation, turn);
266
- return { kind: 'action', result: { turn } };
321
+ return { kind: 'action', result: { message_id: turn } };
267
322
  }
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 } };
275
- }
276
- if (name === 'conversation.delete')
323
+ if (name === 'conversations/delete')
277
324
  scripted.delete(named);
278
- return { kind: 'action', result: { conversation: named } };
325
+ return { kind: 'action', result: { conversation_id: named } };
279
326
  }
280
327
  function announceList() {
281
328
  const entries = [...scripted.values()].flatMap(({ conversation, listed, messages = [] }) => listed === undefined
282
329
  ? []
283
330
  : [{ conversation, ...listed, newest: messages.at(-1)?.position ?? null }]);
284
- for (const listener of listeners)
285
- listener({ kind: 'list', entries });
331
+ for (const listener of listeners) {
332
+ listener({ kind: 'list', entries, whole: true, more: false, cursor: null });
333
+ }
286
334
  }
287
335
  function discovery() {
288
336
  return {
@@ -294,9 +342,42 @@ export function createMemoryAdapter(options = {}) {
294
342
  ...(options.member === undefined ? {} : { member: options.member }),
295
343
  };
296
344
  }
345
+ function discovered() {
346
+ return resolveScript(scripts.discover, discovery, undefined).then((answer) => {
347
+ if (answer.kind === 'discovery')
348
+ for (const room of answer.rooms)
349
+ note(room.locator, room);
350
+ return answer;
351
+ });
352
+ }
353
+ function opened(notify) {
354
+ const opening = ++openings;
355
+ notify({ kind: 'opened' });
356
+ void discovered()
357
+ .catch(() => ({ kind: 'transport-uncertainty' }))
358
+ .then((answer) => {
359
+ if (opening !== openings)
360
+ return;
361
+ if (answer.kind !== 'discovery') {
362
+ openings += 1;
363
+ carried.clear();
364
+ const revoked = answer.kind === 'revoked-authorization';
365
+ notify({ kind: 'closed', revoked, lost: !revoked, authorityChanged: false });
366
+ return;
367
+ }
368
+ declaredRooms.clear();
369
+ for (const room of answer.rooms)
370
+ declaredRooms.add(room.locator);
371
+ notify({ kind: 'discovered', discovery: answer });
372
+ });
373
+ }
374
+ function emitAll(event) {
375
+ for (const observer of observers)
376
+ observer(event);
377
+ }
297
378
  return {
298
- ...(options.exhaustiveDiscovery === undefined ? {} : { exhaustiveDiscovery: true }),
299
379
  ...(options.roomTypes === undefined ? {} : { roomTypes: options.roomTypes }),
380
+ ...(options.typedPaths === undefined ? {} : { typedPaths: options.typedPaths }),
300
381
  setRooms(next) {
301
382
  rooms = [...next];
302
383
  retain(rooms);
@@ -305,33 +386,37 @@ export function createMemoryAdapter(options = {}) {
305
386
  scriptConversations(next);
306
387
  },
307
388
  open() {
389
+ carried.clear();
308
390
  announceList();
309
- for (const observer of observers)
310
- observer({ kind: 'opened' });
391
+ opened(emitAll);
311
392
  },
312
- close({ revoked = false, lost = !revoked } = {}) {
313
- for (const observer of observers)
314
- observer({ kind: 'closed', revoked, lost });
393
+ close({ revoked = false, lost = !revoked, authorityChanged = false } = {}) {
394
+ openings += 1;
395
+ carried.clear();
396
+ emitAll({ kind: 'closed', revoked, lost, authorityChanged });
315
397
  },
316
398
  expire(locators) {
317
399
  expiring = [...locators];
318
400
  },
319
- notifyRoomVersion({ locator, roomVersion }) {
320
- for (const observer of observers)
321
- observer({ kind: 'room-version', locator, roomVersion });
401
+ notifyRoomVersion({ locator }) {
402
+ carry(locator);
322
403
  },
323
- notifyAuthorityChanged(scope) {
324
- for (const observer of observers) {
325
- observer(scope === undefined
326
- ? { kind: 'authority-changed' }
327
- : { kind: 'authority-changed', scope });
328
- }
404
+ notifyAuthorityChanged(locators) {
405
+ const named = new Set(locators ?? [...declaredRooms, ...rooms.map((room) => room.locator)]);
406
+ const listed = rooms.filter((room) => named.has(room.locator));
407
+ const left = [...named].filter((locator) => !listed.some((room) => room.locator === locator));
408
+ for (const room of listed)
409
+ declaredRooms.add(room.locator);
410
+ for (const locator of left)
411
+ declaredRooms.delete(locator);
412
+ emitAll({
413
+ kind: 'authority-changed',
414
+ rooms: listed.map(declared),
415
+ left,
416
+ ...(options.member === undefined ? {} : { member: options.member }),
417
+ });
329
418
  },
330
419
  notifyConversation(event) {
331
- if (event.kind === 'accepted-message') {
332
- sealed.add(event.message.turn);
333
- unsealed.delete(event.message.turn);
334
- }
335
420
  for (const listener of listeners)
336
421
  listener(event);
337
422
  },
@@ -340,21 +425,31 @@ export function createMemoryAdapter(options = {}) {
340
425
  observer(mode);
341
426
  },
342
427
  heldRooms() {
343
- return held;
428
+ return [...carried.keys()].sort();
344
429
  },
345
430
  replicatedConversations() {
346
431
  return replicated;
347
432
  },
433
+ heldConversationCursor() {
434
+ return heldCursor;
435
+ },
348
436
  conversations: {
349
437
  replicate(next) {
350
438
  replicated = [...next];
351
439
  },
440
+ hold(cursor) {
441
+ heldCursor = cursor;
442
+ },
352
443
  observe(notify) {
353
444
  listeners.add(notify);
354
445
  return () => {
355
446
  listeners.delete(notify);
356
447
  };
357
448
  },
449
+ history: (request) => Promise.resolve(historiesOf(request)),
450
+ ...(options.agents === undefined
451
+ ? {}
452
+ : { agents: () => Promise.resolve(structuredClone(options.agents)) }),
358
453
  },
359
454
  serviceMode: {
360
455
  observe(notify) {
@@ -366,44 +461,46 @@ export function createMemoryAdapter(options = {}) {
366
461
  },
367
462
  roomStream: {
368
463
  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) => {
464
+ const named = asked.map((room) => room.locator);
465
+ const unknown = asked.flatMap((room) => {
373
466
  const current = rooms.find((entry) => entry.locator === room.locator);
467
+ const version = room.roomVersion;
374
468
  return current === undefined ||
375
- expired.includes(room.locator) ||
376
- current.roomVersion === room.roomVersion
469
+ (version !== null &&
470
+ (current.roomVersion === version || served.get(room.locator)?.has(version) === true))
377
471
  ? []
378
- : [{ locator: room.locator, roomVersion: current.roomVersion }];
472
+ : [room.locator];
379
473
  });
474
+ const expired = [
475
+ ...new Set([...expiring.filter((locator) => named.includes(locator)), ...unknown]),
476
+ ];
477
+ expiring = expiring.filter((locator) => !named.includes(locator));
380
478
  queueMicrotask(() => {
381
- for (const observer of observers) {
382
- for (const room of moved)
383
- observer({ kind: 'room-version', ...room });
384
- observer({ kind: 'opening', expired });
479
+ for (const room of asked) {
480
+ if (expired.includes(room.locator) || room.roomVersion === null)
481
+ carried.delete(room.locator);
482
+ else {
483
+ carried.set(room.locator, room.roomVersion);
484
+ carry(room.locator);
485
+ }
385
486
  }
487
+ emitAll({ kind: 'caught-up', expired });
386
488
  });
387
489
  },
388
- reopen() {
389
- queueMicrotask(() => {
390
- for (const observer of observers) {
391
- observer({ kind: 'closed', revoked: false, lost: false });
392
- }
393
- });
394
- },
395
- published() { },
396
490
  observe(notify) {
397
491
  observers.add(notify);
398
492
  queueMicrotask(() => {
399
493
  if (!observers.has(notify))
400
494
  return;
401
495
  if (options.unopened === true) {
402
- notify({ kind: 'closed', revoked: false, lost: true });
496
+ notify({ kind: 'closed', revoked: false, lost: true, authorityChanged: false });
403
497
  return;
404
498
  }
405
499
  announceList();
406
- notify({ kind: 'opened' });
500
+ opened((event) => {
501
+ if (observers.has(notify))
502
+ notify(event);
503
+ });
407
504
  });
408
505
  return () => {
409
506
  observers.delete(notify);
@@ -420,12 +517,7 @@ export function createMemoryAdapter(options = {}) {
420
517
  return resolveScript(scripts.authorize, () => ({}), undefined);
421
518
  },
422
519
  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
- });
520
+ return discovered();
429
521
  },
430
522
  reached,
431
523
  follows(locator, roomVersion, next) {
@@ -509,7 +601,7 @@ export function createMemoryAdapter(options = {}) {
509
601
  return { kind: 'room-not-readable', locator: request.locator };
510
602
  const blob = heldBlob(room, request.path);
511
603
  return blob === undefined
512
- ? { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false }
604
+ ? { kind: 'rejected', code: 'not_found', fields: {}, retryable: false }
513
605
  : { kind: 'binary', body: blob.stream(), mediaType: blob.type };
514
606
  }, request);
515
607
  },
@@ -520,7 +612,7 @@ export function createMemoryAdapter(options = {}) {
520
612
  return { kind: 'room-not-readable', locator: request.locator };
521
613
  const blob = heldBlob(room, request.path);
522
614
  if (blob === undefined) {
523
- return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
615
+ return { kind: 'rejected', code: 'not_found', fields: {}, retryable: false };
524
616
  }
525
617
  const url = linked.get(blob) ?? URL.createObjectURL(blob);
526
618
  linked.set(blob, url);
@@ -539,7 +631,7 @@ export function createMemoryAdapter(options = {}) {
539
631
  },
540
632
  async action(_authorization, request) {
541
633
  return resolveScript(scripts.action, () => {
542
- if (request.name.startsWith('conversation.'))
634
+ if (request.name.startsWith('conversations/'))
543
635
  return conversationAction(request);
544
636
  return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
545
637
  }, request).then((answer) => {
@@ -1,6 +1,7 @@
1
1
  import type { AcceptedMessage } from './adapter.js';
2
2
  import type { Connection } from './tables.js';
3
3
  export declare const MESSAGE_TABLES: readonly string[];
4
+ 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 asking.text 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";
4
5
  export type HeldConversation = {
5
6
  readonly conversation: string;
6
7
  readonly read: string | null | undefined;
@@ -10,6 +11,25 @@ export type MessageWindow = {
10
11
  readonly messages: AcceptedMessage[];
11
12
  readonly more: boolean;
12
13
  };
14
+ export type HeldSource = {
15
+ readonly source: unknown;
16
+ readonly sender: string | null;
17
+ };
18
+ export type HeldRow = {
19
+ readonly conversation: string;
20
+ readonly said: {
21
+ readonly text: string;
22
+ readonly role: string | null;
23
+ readonly at: string | null;
24
+ } | null;
25
+ readonly failure: string | null;
26
+ readonly opened: HeldSource | null;
27
+ readonly asking: (HeldSource & {
28
+ readonly identity: string;
29
+ readonly text: string;
30
+ readonly at: string | null;
31
+ }) | null;
32
+ };
13
33
  export type ConversationWrite = {
14
34
  readonly conversation: string;
15
35
  readonly messages: readonly AcceptedMessage[];
@@ -18,10 +38,11 @@ export type ConversationWrite = {
18
38
  readonly partial: boolean;
19
39
  };
20
40
  };
21
- export declare function heldConversations(connection: Connection): HeldConversation[];
41
+ export declare function heldConversations(connection: Connection, conversations: readonly string[] | null): HeldConversation[];
22
42
  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;
43
+ export declare function messageWindow(connection: Connection, conversation: string, limit: number, before: readonly [string, string] | null, phrase: string | null): MessageWindow;
44
+ export declare function messageCount(connection: Connection, conversation: string, phrase: string | null): number;
45
+ export declare function conversationRows(connection: Connection, conversations: readonly string[]): HeldRow[];
25
46
  export declare function turnArrived(connection: Connection, conversation: string, turn: string): boolean;
26
47
  export declare function droppedMessages(connection: Connection, conversations: readonly string[]): void;
27
48
  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;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAM1D,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAO3C,CAAC;AAQF,eAAO,MAAM,IAAI,qwDAwBqD,CAAC;AAEvE,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,UAAU,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEtF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,MAAM,EACX,CAAC,UAAU,GAAG;QACZ,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC,GACF,IAAI,CAAC;CACV,CAAC;AAEF,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,CAC/B,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GACtC,gBAAgB,EAAE,CA0BpB;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,iBAAiB,GAClD,IAAI,CAqBN;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;AAaD,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,OAAO,EAAE,CAuBX;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,CAU9F;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAG9D"}