@agentshouse/mdruntime 0.1.0-cedb03eaa48b6 → 0.1.0-cedd665dffa4c

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 (395) hide show
  1. package/README.md +24 -19
  2. package/dist/acceptance.d.ts +3 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +299 -0
  5. package/dist/act-lanes.d.ts +30 -0
  6. package/dist/act-lanes.d.ts.map +1 -0
  7. package/dist/act-lanes.js +225 -0
  8. package/dist/actions.d.ts +26 -0
  9. package/dist/actions.d.ts.map +1 -0
  10. package/dist/actions.js +302 -0
  11. package/dist/adapter.d.ts +173 -125
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +6 -10
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +35 -41
  16. package/dist/binary.d.ts +0 -5
  17. package/dist/binary.d.ts.map +1 -1
  18. package/dist/binary.js +1 -1
  19. package/dist/bootstrap.d.ts +30 -11
  20. package/dist/bootstrap.d.ts.map +1 -1
  21. package/dist/bootstrap.js +309 -113
  22. package/dist/cell.d.ts +6 -0
  23. package/dist/cell.d.ts.map +1 -0
  24. package/dist/cell.js +9 -0
  25. package/dist/chain.d.ts +12 -0
  26. package/dist/chain.d.ts.map +1 -0
  27. package/dist/chain.js +64 -0
  28. package/dist/change-set.d.ts +13 -16
  29. package/dist/change-set.d.ts.map +1 -1
  30. package/dist/change-set.js +17 -89
  31. package/dist/change.d.ts +36 -1
  32. package/dist/change.d.ts.map +1 -1
  33. package/dist/change.js +17 -3
  34. package/dist/chat-types.d.ts +3 -0
  35. package/dist/chat-types.d.ts.map +1 -0
  36. package/dist/chat-types.js +11 -0
  37. package/dist/client.d.ts +37 -26
  38. package/dist/client.d.ts.map +1 -1
  39. package/dist/client.js +113 -23
  40. package/dist/collection.d.ts +32 -21
  41. package/dist/collection.d.ts.map +1 -1
  42. package/dist/collection.js +53 -318
  43. package/dist/compile.d.ts +18 -0
  44. package/dist/compile.d.ts.map +1 -0
  45. package/dist/compile.js +723 -0
  46. package/dist/connection.d.ts +7 -137
  47. package/dist/connection.d.ts.map +1 -1
  48. package/dist/connection.js +110 -3602
  49. package/dist/context.d.ts +2 -0
  50. package/dist/context.d.ts.map +1 -0
  51. package/dist/{chat/context.js → context.js} +2 -5
  52. package/dist/conversation-live.d.ts +150 -0
  53. package/dist/conversation-live.d.ts.map +1 -0
  54. package/dist/conversation-live.js +259 -0
  55. package/dist/conversation-row.d.ts +40 -0
  56. package/dist/conversation-row.d.ts.map +1 -0
  57. package/dist/conversation-row.js +66 -0
  58. package/dist/conversation.d.ts +75 -49
  59. package/dist/conversation.d.ts.map +1 -1
  60. package/dist/conversation.js +1029 -806
  61. package/dist/declaration.d.ts +10 -0
  62. package/dist/declaration.d.ts.map +1 -0
  63. package/dist/declaration.js +24 -0
  64. package/dist/digest.d.ts +7 -0
  65. package/dist/digest.d.ts.map +1 -0
  66. package/dist/digest.js +113 -0
  67. package/dist/discovery.d.ts +10 -0
  68. package/dist/discovery.d.ts.map +1 -0
  69. package/dist/discovery.js +150 -0
  70. package/dist/durability.d.ts +20 -4
  71. package/dist/durability.d.ts.map +1 -1
  72. package/dist/durability.js +9 -0
  73. package/dist/entry.d.ts +5 -2
  74. package/dist/entry.d.ts.map +1 -1
  75. package/dist/entry.js +33 -29
  76. package/dist/expectation.d.ts +26 -13
  77. package/dist/expectation.d.ts.map +1 -1
  78. package/dist/expectation.js +72 -19
  79. package/dist/failure.d.ts +3 -0
  80. package/dist/failure.d.ts.map +1 -1
  81. package/dist/failure.js +6 -0
  82. package/dist/figures.d.ts +49 -0
  83. package/dist/figures.d.ts.map +1 -0
  84. package/dist/figures.js +199 -0
  85. package/dist/file.d.ts +2 -19
  86. package/dist/file.d.ts.map +1 -1
  87. package/dist/file.js +8 -122
  88. package/dist/holdings.d.ts +29 -0
  89. package/dist/holdings.d.ts.map +1 -0
  90. package/dist/holdings.js +95 -0
  91. package/dist/host.d.ts +21 -8
  92. package/dist/host.d.ts.map +1 -1
  93. package/dist/host.js +119 -51
  94. package/dist/identity.d.ts +0 -2
  95. package/dist/identity.d.ts.map +1 -1
  96. package/dist/identity.js +0 -6
  97. package/dist/index.d.ts +41 -16
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +19 -4
  100. package/dist/install.d.ts +60 -0
  101. package/dist/install.d.ts.map +1 -0
  102. package/dist/install.js +537 -0
  103. package/dist/lifecycle.d.ts +7 -0
  104. package/dist/lifecycle.d.ts.map +1 -0
  105. package/dist/lifecycle.js +278 -0
  106. package/dist/listing.d.ts +52 -0
  107. package/dist/listing.d.ts.map +1 -0
  108. package/dist/listing.js +152 -0
  109. package/dist/live.d.ts +25 -0
  110. package/dist/live.d.ts.map +1 -0
  111. package/dist/live.js +206 -0
  112. package/dist/loaded.d.ts +5 -0
  113. package/dist/loaded.d.ts.map +1 -0
  114. package/dist/loaded.js +40 -0
  115. package/dist/locks.d.ts +7 -0
  116. package/dist/locks.d.ts.map +1 -0
  117. package/dist/locks.js +32 -0
  118. package/dist/lost.d.ts +5 -0
  119. package/dist/lost.d.ts.map +1 -0
  120. package/dist/lost.js +49 -0
  121. package/dist/media.d.ts +13 -0
  122. package/dist/media.d.ts.map +1 -0
  123. package/dist/media.js +269 -0
  124. package/dist/memory.d.ts +19 -7
  125. package/dist/memory.d.ts.map +1 -1
  126. package/dist/memory.js +281 -118
  127. package/dist/messages.d.ts +58 -0
  128. package/dist/messages.d.ts.map +1 -0
  129. package/dist/messages.js +162 -0
  130. package/dist/model.d.ts +8 -11
  131. package/dist/model.d.ts.map +1 -1
  132. package/dist/model.js +6 -23
  133. package/dist/models.d.ts +10 -0
  134. package/dist/models.d.ts.map +1 -0
  135. package/dist/models.js +153 -0
  136. package/dist/name.d.ts +4 -0
  137. package/dist/name.d.ts.map +1 -0
  138. package/dist/name.js +122 -0
  139. package/dist/observation.d.ts +38 -10
  140. package/dist/observation.d.ts.map +1 -1
  141. package/dist/observation.js +232 -44
  142. package/dist/opened.d.ts +22 -0
  143. package/dist/opened.d.ts.map +1 -0
  144. package/dist/opened.js +107 -0
  145. package/dist/opening.d.ts +4 -0
  146. package/dist/opening.d.ts.map +1 -0
  147. package/dist/opening.js +53 -0
  148. package/dist/outcome.d.ts +51 -9
  149. package/dist/outcome.d.ts.map +1 -1
  150. package/dist/outcome.js +62 -2
  151. package/dist/overlay.d.ts +8 -6
  152. package/dist/overlay.d.ts.map +1 -1
  153. package/dist/overlay.js +121 -182
  154. package/dist/page-metadata.d.ts +8 -0
  155. package/dist/page-metadata.d.ts.map +1 -0
  156. package/dist/page-metadata.js +19 -0
  157. package/dist/parts.d.ts +4 -0
  158. package/dist/parts.d.ts.map +1 -0
  159. package/dist/parts.js +13 -0
  160. package/dist/paths.d.ts +2 -0
  161. package/dist/paths.d.ts.map +1 -1
  162. package/dist/paths.js +26 -0
  163. package/dist/preparation.d.ts +41 -0
  164. package/dist/preparation.d.ts.map +1 -0
  165. package/dist/preparation.js +314 -0
  166. package/dist/presence.d.ts +58 -0
  167. package/dist/presence.d.ts.map +1 -0
  168. package/dist/presence.js +231 -0
  169. package/dist/queries.d.ts +16 -0
  170. package/dist/queries.d.ts.map +1 -0
  171. package/dist/queries.js +308 -0
  172. package/dist/query.d.ts +21 -207
  173. package/dist/query.d.ts.map +1 -1
  174. package/dist/query.js +3 -493
  175. package/dist/{chat/questions.d.ts → questions.d.ts} +5 -7
  176. package/dist/questions.d.ts.map +1 -0
  177. package/dist/{chat/questions.js → questions.js} +11 -7
  178. package/dist/queue.d.ts +40 -0
  179. package/dist/queue.d.ts.map +1 -0
  180. package/dist/queue.js +480 -0
  181. package/dist/reach.d.ts +21 -11
  182. package/dist/reach.d.ts.map +1 -1
  183. package/dist/reach.js +342 -112
  184. package/dist/react.d.ts +17 -3
  185. package/dist/react.d.ts.map +1 -1
  186. package/dist/react.js +33 -1
  187. package/dist/{chat/read.d.ts → read.d.ts} +2 -0
  188. package/dist/read.d.ts.map +1 -0
  189. package/dist/{chat/read.js → read.js} +4 -0
  190. package/dist/readiness.d.ts +22 -20
  191. package/dist/readiness.d.ts.map +1 -1
  192. package/dist/readiness.js +5 -13
  193. package/dist/reads.d.ts +38 -10
  194. package/dist/reads.d.ts.map +1 -1
  195. package/dist/reads.js +163 -83
  196. package/dist/recovery.d.ts +5 -2
  197. package/dist/recovery.d.ts.map +1 -1
  198. package/dist/recovery.js +65 -8
  199. package/dist/refresh.d.ts +18 -15
  200. package/dist/refresh.d.ts.map +1 -1
  201. package/dist/refresh.js +145 -60
  202. package/dist/refusal.d.ts +5 -0
  203. package/dist/refusal.d.ts.map +1 -0
  204. package/dist/refusal.js +55 -0
  205. package/dist/replica.d.ts +49 -36
  206. package/dist/replica.d.ts.map +1 -1
  207. package/dist/replica.js +322 -198
  208. package/dist/retried.d.ts +30 -0
  209. package/dist/retried.d.ts.map +1 -0
  210. package/dist/retried.js +72 -0
  211. package/dist/room-draft.d.ts +55 -13
  212. package/dist/room-draft.d.ts.map +1 -1
  213. package/dist/room-draft.js +416 -122
  214. package/dist/room-drafts.d.ts +24 -0
  215. package/dist/room-drafts.d.ts.map +1 -0
  216. package/dist/room-drafts.js +220 -0
  217. package/dist/rows.d.ts +32 -31
  218. package/dist/rows.d.ts.map +1 -1
  219. package/dist/rows.js +59 -124
  220. package/dist/runtime.d.ts +34 -0
  221. package/dist/runtime.d.ts.map +1 -0
  222. package/dist/runtime.js +1 -0
  223. package/dist/save.d.ts +43 -49
  224. package/dist/save.d.ts.map +1 -1
  225. package/dist/save.js +736 -302
  226. package/dist/saves.d.ts +32 -0
  227. package/dist/saves.d.ts.map +1 -0
  228. package/dist/saves.js +426 -0
  229. package/dist/search.d.ts +12 -95
  230. package/dist/search.d.ts.map +1 -1
  231. package/dist/search.js +10 -266
  232. package/dist/seed.d.ts +11 -2
  233. package/dist/seed.d.ts.map +1 -1
  234. package/dist/seed.js +71 -1
  235. package/dist/shared.d.ts +6 -7
  236. package/dist/shared.d.ts.map +1 -1
  237. package/dist/shared.js +75 -104
  238. package/dist/shown.d.ts +33 -0
  239. package/dist/shown.d.ts.map +1 -0
  240. package/dist/shown.js +309 -0
  241. package/dist/socket/admission.d.ts +7 -0
  242. package/dist/socket/admission.d.ts.map +1 -0
  243. package/dist/socket/admission.js +39 -0
  244. package/dist/socket/answers.d.ts +6 -0
  245. package/dist/socket/answers.d.ts.map +1 -0
  246. package/dist/socket/answers.js +20 -0
  247. package/dist/socket/lanes.d.ts +28 -0
  248. package/dist/socket/lanes.d.ts.map +1 -0
  249. package/dist/socket/lanes.js +103 -0
  250. package/dist/socket/reads.d.ts +10 -0
  251. package/dist/socket/reads.d.ts.map +1 -0
  252. package/dist/socket/reads.js +31 -0
  253. package/dist/socket/session.d.ts +38 -0
  254. package/dist/socket/session.d.ts.map +1 -0
  255. package/dist/socket/session.js +23 -0
  256. package/dist/socket.d.ts +67 -0
  257. package/dist/socket.d.ts.map +1 -0
  258. package/dist/socket.js +164 -0
  259. package/dist/source.d.ts +59 -0
  260. package/dist/source.d.ts.map +1 -0
  261. package/dist/source.js +93 -0
  262. package/dist/status.d.ts +4 -5
  263. package/dist/status.d.ts.map +1 -1
  264. package/dist/status.js +3 -7
  265. package/dist/store/installs.d.ts +30 -0
  266. package/dist/store/installs.d.ts.map +1 -0
  267. package/dist/store/installs.js +40 -0
  268. package/dist/store/readiness.d.ts +11 -0
  269. package/dist/store/readiness.d.ts.map +1 -0
  270. package/dist/store/readiness.js +68 -0
  271. package/dist/store/records.d.ts +217 -0
  272. package/dist/store/records.d.ts.map +1 -0
  273. package/dist/store/records.js +464 -0
  274. package/dist/store/room-held.d.ts +8 -0
  275. package/dist/store/room-held.d.ts.map +1 -0
  276. package/dist/store/room-held.js +17 -0
  277. package/dist/store/rooms-shown.d.ts +8 -0
  278. package/dist/store/rooms-shown.d.ts.map +1 -0
  279. package/dist/store/rooms-shown.js +13 -0
  280. package/dist/store/space.d.ts +11 -0
  281. package/dist/store/space.d.ts.map +1 -0
  282. package/dist/store/space.js +41 -0
  283. package/dist/store/watchers.d.ts +17 -0
  284. package/dist/store/watchers.d.ts.map +1 -0
  285. package/dist/store/watchers.js +56 -0
  286. package/dist/store/writes.d.ts +24 -0
  287. package/dist/store/writes.d.ts.map +1 -0
  288. package/dist/store/writes.js +125 -0
  289. package/dist/store.d.ts +114 -163
  290. package/dist/store.d.ts.map +1 -1
  291. package/dist/store.js +163 -750
  292. package/dist/stored.d.ts +167 -0
  293. package/dist/stored.d.ts.map +1 -0
  294. package/dist/stored.js +703 -0
  295. package/dist/surface.d.ts +89 -0
  296. package/dist/surface.d.ts.map +1 -0
  297. package/dist/surface.js +222 -0
  298. package/dist/sync.d.ts +19 -0
  299. package/dist/sync.d.ts.map +1 -0
  300. package/dist/sync.js +535 -0
  301. package/dist/tables.d.ts +419 -0
  302. package/dist/tables.d.ts.map +1 -0
  303. package/dist/tables.js +758 -0
  304. package/dist/tallies.d.ts +18 -0
  305. package/dist/tallies.d.ts.map +1 -0
  306. package/dist/tallies.js +128 -0
  307. package/dist/transfer.d.ts +0 -5
  308. package/dist/transfer.d.ts.map +1 -1
  309. package/dist/turn.d.ts +4 -2
  310. package/dist/turn.d.ts.map +1 -1
  311. package/dist/turn.js +46 -22
  312. package/dist/validation.d.ts +29 -0
  313. package/dist/validation.d.ts.map +1 -0
  314. package/dist/validation.js +98 -0
  315. package/dist/windows.d.ts +1 -16
  316. package/dist/windows.d.ts.map +1 -1
  317. package/dist/windows.js +2 -79
  318. package/dist/wire.d.ts +74 -9
  319. package/dist/wire.d.ts.map +1 -1
  320. package/dist/wire.js +26 -6
  321. package/package.json +19 -19
  322. package/AGENTS.md +0 -305
  323. package/dist/attempt.d.ts +0 -16
  324. package/dist/attempt.d.ts.map +0 -1
  325. package/dist/attempt.js +0 -70
  326. package/dist/chat/acts.d.ts +0 -33
  327. package/dist/chat/acts.d.ts.map +0 -1
  328. package/dist/chat/acts.js +0 -36
  329. package/dist/chat/context.d.ts +0 -3
  330. package/dist/chat/context.d.ts.map +0 -1
  331. package/dist/chat/earlier.d.ts +0 -10
  332. package/dist/chat/earlier.d.ts.map +0 -1
  333. package/dist/chat/earlier.js +0 -54
  334. package/dist/chat/input.d.ts +0 -9
  335. package/dist/chat/input.d.ts.map +0 -1
  336. package/dist/chat/input.js +0 -99
  337. package/dist/chat/kit.d.ts +0 -61
  338. package/dist/chat/kit.d.ts.map +0 -1
  339. package/dist/chat/kit.js +0 -123
  340. package/dist/chat/lasting.d.ts +0 -6
  341. package/dist/chat/lasting.d.ts.map +0 -1
  342. package/dist/chat/lasting.js +0 -19
  343. package/dist/chat/list.d.ts +0 -27
  344. package/dist/chat/list.d.ts.map +0 -1
  345. package/dist/chat/list.js +0 -99
  346. package/dist/chat/markdown.d.ts +0 -20
  347. package/dist/chat/markdown.d.ts.map +0 -1
  348. package/dist/chat/markdown.js +0 -188
  349. package/dist/chat/message.d.ts +0 -6
  350. package/dist/chat/message.d.ts.map +0 -1
  351. package/dist/chat/message.js +0 -192
  352. package/dist/chat/messages.d.ts +0 -22
  353. package/dist/chat/messages.d.ts.map +0 -1
  354. package/dist/chat/messages.js +0 -155
  355. package/dist/chat/name.d.ts +0 -6
  356. package/dist/chat/name.d.ts.map +0 -1
  357. package/dist/chat/name.js +0 -37
  358. package/dist/chat/opened.d.ts +0 -11
  359. package/dist/chat/opened.d.ts.map +0 -1
  360. package/dist/chat/opened.js +0 -17
  361. package/dist/chat/overlay.d.ts +0 -31
  362. package/dist/chat/overlay.d.ts.map +0 -1
  363. package/dist/chat/overlay.js +0 -97
  364. package/dist/chat/parts.d.ts +0 -57
  365. package/dist/chat/parts.d.ts.map +0 -1
  366. package/dist/chat/parts.js +0 -119
  367. package/dist/chat/process.d.ts +0 -20
  368. package/dist/chat/process.d.ts.map +0 -1
  369. package/dist/chat/process.js +0 -32
  370. package/dist/chat/provider.d.ts +0 -63
  371. package/dist/chat/provider.d.ts.map +0 -1
  372. package/dist/chat/provider.js +0 -628
  373. package/dist/chat/question.d.ts +0 -9
  374. package/dist/chat/question.d.ts.map +0 -1
  375. package/dist/chat/question.js +0 -69
  376. package/dist/chat/questions.d.ts.map +0 -1
  377. package/dist/chat/read.d.ts.map +0 -1
  378. package/dist/chat/ready.d.ts +0 -34
  379. package/dist/chat/ready.d.ts.map +0 -1
  380. package/dist/chat/ready.js +0 -91
  381. package/dist/chat/style.d.ts +0 -4
  382. package/dist/chat/style.d.ts.map +0 -1
  383. package/dist/chat/style.js +0 -302
  384. package/dist/chat.d.ts +0 -14
  385. package/dist/chat.d.ts.map +0 -1
  386. package/dist/chat.js +0 -8
  387. package/dist/fence.d.ts +0 -6
  388. package/dist/fence.d.ts.map +0 -1
  389. package/dist/fence.js +0 -10
  390. package/dist/log.d.ts +0 -5
  391. package/dist/log.d.ts.map +0 -1
  392. package/dist/log.js +0 -14
  393. package/dist/read-side.d.ts +0 -27
  394. package/dist/read-side.d.ts.map +0 -1
  395. package/dist/read-side.js +0 -824
package/dist/memory.js CHANGED
@@ -1,7 +1,14 @@
1
+ import { definitionAt, documentFacts, parse } from '@agentshouse/mdmodel';
2
+ import { NO_ROOM_TYPES, schemaTypes } from './attached-model.js';
3
+ import { selected } from './collection.js';
4
+ import { declaredType } from './outcome.js';
1
5
  import { sameChange } from './overlay.js';
6
+ const ATTACHMENTS = 'attachments';
7
+ function lastName(path) {
8
+ return path.slice(path.lastIndexOf('/') + 1);
9
+ }
2
10
  const FIXTURE_RETENTION = {
3
11
  history: { kind: 'duration', seconds: 1 },
4
- outcome: 604_800,
5
12
  refreshHorizon: 1,
6
13
  };
7
14
  function declaredRetention(value) {
@@ -15,12 +22,7 @@ function declaredRetention(value) {
15
22
  }
16
23
  const MODEL_ABSENT = { kind: 'model-unavailable', reason: 'not-readable' };
17
24
  function modelsOf(room) {
18
- return {
19
- collection: room.model ?? MODEL_ABSENT,
20
- ...(room.typedSelection === undefined
21
- ? {}
22
- : { selection: room.selectionModel ?? MODEL_ABSENT }),
23
- };
25
+ return { collection: room.model ?? MODEL_ABSENT };
24
26
  }
25
27
  function changedModels(room, from) {
26
28
  const now = modelsOf(room);
@@ -53,13 +55,17 @@ export function createMemoryAdapter(options = {}) {
53
55
  const listeners = new Set();
54
56
  const modeObservers = new Set();
55
57
  const scripted = new Map();
56
- const unsealed = new Map();
57
- const sealed = new Set();
58
- const sentTurns = new Map();
58
+ const repeats = new Map();
59
59
  const historyPageSize = options.historyPageSize;
60
- let held = [];
60
+ const attached = new Map();
61
+ const linked = new WeakMap();
62
+ const carried = new Map();
61
63
  let expiring = [];
64
+ let openings = 0;
65
+ const declaredRooms = new Set();
62
66
  let replicated = [];
67
+ let heldCursor = null;
68
+ let agents = structuredClone(options.agents ?? []);
63
69
  let issued = 0;
64
70
  function scriptConversations(entries) {
65
71
  scripted.clear();
@@ -87,8 +93,53 @@ export function createMemoryAdapter(options = {}) {
87
93
  const wanted = ordinals.get(`${locator}\u0000${target}`);
88
94
  return held !== undefined && wanted !== undefined && held >= wanted;
89
95
  }
96
+ function heldBlob(room, path) {
97
+ return attached.get(`${room.locator}\u0000${path}`) ?? room.blobs?.[path];
98
+ }
99
+ function freePath(room, name) {
100
+ const dot = name.lastIndexOf('.');
101
+ const stem = dot > 0 ? name.slice(0, dot) : name;
102
+ const extension = dot > 0 ? name.slice(dot) : '';
103
+ for (let count = 1;; count += 1) {
104
+ const path = `${ATTACHMENTS}/${count === 1 ? stem : `${stem}-${count}`}${extension}`;
105
+ if (heldBlob(room, path) === undefined && room.documents?.[path] === undefined)
106
+ return path;
107
+ }
108
+ }
109
+ const saved = new WeakMap();
110
+ const roomTypes = options.roomTypes ?? NO_ROOM_TYPES;
111
+ function factsAt(room, path, content) {
112
+ const types = selected({ selection: room.typedSelection ?? null }, path)
113
+ ? roomTypes.types
114
+ : schemaTypes(room.model?.kind === 'model' ? room.model.snapshot.schema : null, roomTypes);
115
+ let held = saved.get(types);
116
+ if (held === undefined) {
117
+ held = new Map();
118
+ saved.set(types, held);
119
+ }
120
+ const key = `${path}\u0000${content}`;
121
+ if (!held.has(key)) {
122
+ const facts = documentFacts(path, parse(content, path, definitionAt({ types }, path, options.typedPaths)), {
123
+ types,
124
+ });
125
+ held.set(key, facts === null ? null : JSON.parse(JSON.stringify(facts)));
126
+ }
127
+ return held.get(key);
128
+ }
129
+ function factsIn(room, paths) {
130
+ const facts = {};
131
+ for (const path of paths) {
132
+ const content = room.documents?.[path];
133
+ const held = room.facts?.[path] ?? (content === undefined ? null : factsAt(room, path, content));
134
+ if (held !== null)
135
+ facts[path] = held;
136
+ }
137
+ return facts;
138
+ }
90
139
  function retain(entries) {
91
140
  for (const room of entries) {
141
+ for (const [path, content] of Object.entries(room.documents ?? {}))
142
+ factsAt(room, path, content);
92
143
  note(room.locator, room);
93
144
  const versions = served.get(room.locator) ?? new Map();
94
145
  versions.set(room.roomVersion, room);
@@ -104,8 +155,9 @@ export function createMemoryAdapter(options = {}) {
104
155
  roomVersion: room.roomVersion,
105
156
  operations: room.operations,
106
157
  replica: room.replica,
107
- ...(room.typedSelection === undefined ? {} : { typedSelection: room.typedSelection }),
158
+ typedSelection: room.typedSelection ?? null,
108
159
  providerOwnedPaths: room.providerOwnedPaths,
160
+ authoredPaths: room.authoredPaths ?? ['**'],
109
161
  };
110
162
  }
111
163
  function page(room, after) {
@@ -121,27 +173,43 @@ export function createMemoryAdapter(options = {}) {
121
173
  roomVersion: room.roomVersion,
122
174
  ...(opening ? { models: modelsOf(room) } : {}),
123
175
  documents: named(room.documents ?? {}, taken),
176
+ facts: factsIn(room, taken),
124
177
  revisions: named(room.revisions ?? {}, [...taken, ...targets]),
125
178
  ...(room.fileIds === undefined
126
179
  ? {}
127
180
  : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
181
+ ...(room.created === undefined
182
+ ? {}
183
+ : { created: named(room.created, [...taken, ...targets]) }),
128
184
  changes: named(room.changes ?? {}, [...taken, ...targets]),
129
185
  binaryFiles: named(room.binaryFiles ?? {}, targets),
186
+ ...(opening && room.folders !== undefined ? { folders: room.folders } : {}),
130
187
  ...(next < paths.length ? { pageToken: taken.at(-1) } : {}),
131
188
  };
132
189
  }
133
- function advancement(room, from, at) {
190
+ function foldersMoved(room, from) {
191
+ const now = new Set(room.folders ?? []);
192
+ const before = new Set(from.folders ?? []);
193
+ const folders = [...now].filter((folder) => !before.has(folder)).sort();
194
+ const folderRemovals = [...before].filter((folder) => !now.has(folder)).sort();
195
+ return {
196
+ ...(folders.length === 0 ? {} : { folders }),
197
+ ...(folderRemovals.length === 0 ? {} : { folderRemovals }),
198
+ };
199
+ }
200
+ function advancement(room, from, at, whole = false) {
134
201
  const current = room.documents ?? {};
135
202
  const previous = from.documents ?? {};
136
203
  const currentTargets = new Set(Object.keys(room.binaryFiles ?? {}));
137
204
  const previousTargets = new Set(Object.keys(from.binaryFiles ?? {}));
138
205
  const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
139
206
  room.fileIds?.[path] !== from.fileIds?.[path] ||
207
+ room.created?.[path] !== from.created?.[path] ||
140
208
  !sameChange(room.changes?.[path], from.changes?.[path]);
141
209
  const changed = Object.keys(current)
142
210
  .filter((path) => current[path] !== previous[path] || headMoved(path))
143
211
  .sort();
144
- const size = pageSize ?? changed.length;
212
+ const size = whole ? changed.length : (pageSize ?? changed.length);
145
213
  const taken = changed.slice(at, at + size);
146
214
  const next = at + taken.length;
147
215
  const opening = at === 0;
@@ -157,12 +225,17 @@ export function createMemoryAdapter(options = {}) {
157
225
  roomVersion: room.roomVersion,
158
226
  ...(models === undefined ? {} : { models }),
159
227
  documents: named(current, taken),
228
+ facts: factsIn(room, taken),
160
229
  revisions: named(room.revisions ?? {}, [...taken, ...targets]),
161
230
  ...(room.fileIds === undefined
162
231
  ? {}
163
232
  : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
233
+ ...(room.created === undefined
234
+ ? {}
235
+ : { created: named(room.created, [...taken, ...targets]) }),
164
236
  changes: named(room.changes ?? {}, [...taken, ...targets]),
165
237
  binaryFiles: named(room.binaryFiles ?? {}, targets),
238
+ ...(opening ? foldersMoved(room, from) : {}),
166
239
  removals: opening
167
240
  ? [
168
241
  ...Object.keys(previous).filter((path) => !(path in current) && !currentTargets.has(path)),
@@ -172,30 +245,45 @@ export function createMemoryAdapter(options = {}) {
172
245
  ...(pageToken === undefined ? {} : { pageToken }),
173
246
  };
174
247
  }
248
+ function carry(locator) {
249
+ const at = carried.get(locator);
250
+ const current = rooms.find((entry) => entry.locator === locator);
251
+ if (at === undefined || current === undefined || current.roomVersion === at)
252
+ return;
253
+ const from = served.get(locator)?.get(at);
254
+ carried.set(locator, current.roomVersion);
255
+ if (from === undefined)
256
+ return;
257
+ const page = advancement(current, from, 0, true);
258
+ for (const observer of observers) {
259
+ observer({
260
+ kind: 'room-change',
261
+ locator,
262
+ from: at,
263
+ roomVersion: current.roomVersion,
264
+ read: async () => page,
265
+ });
266
+ }
267
+ }
175
268
  function pageOf(conversation, after) {
176
269
  const messages = conversation.messages ?? [];
177
- const first = typeof after === 'string' ? messages.findIndex((message) => message.position > after) : 0;
270
+ const first = typeof after === 'string' ? messages.findIndex((message) => message.change > after) : 0;
178
271
  const from = first === -1 ? messages.length : first;
179
272
  const page = messages.slice(from, from + (historyPageSize ?? messages.length));
180
273
  const last = page.at(-1);
181
274
  return {
182
275
  conversation: conversation.conversation,
183
276
  messages: page,
184
- ...(last !== undefined && from + page.length < messages.length
185
- ? { next: last.position }
186
- : {}),
277
+ ...(last !== undefined && from + page.length < messages.length ? { next: last.change } : {}),
187
278
  };
188
279
  }
189
- function historiesOf(input) {
190
- const asked = input?.conversations;
191
- if (!Array.isArray(asked))
192
- return { kind: 'rejected', code: 'invalid_request', fields: {}, retryable: false };
280
+ function historiesOf(request) {
193
281
  const histories = [];
194
- for (const entry of asked) {
195
- const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
282
+ for (const entry of request.conversations) {
283
+ const conversation = scripted.get(entry.conversation);
196
284
  if (conversation === undefined)
197
285
  continue;
198
- const outcome = conversation.outcomes?.['conversation.history'];
286
+ const outcome = conversation.outcomes?.history;
199
287
  if (outcome !== undefined)
200
288
  return outcome;
201
289
  histories.push(pageOf(conversation, entry.after));
@@ -206,15 +294,22 @@ export function createMemoryAdapter(options = {}) {
206
294
  function conversationAction(request) {
207
295
  const name = request.name;
208
296
  const input = (request.input ?? {});
209
- if (name === 'conversation.history')
210
- return historiesOf(request.input);
211
- if (name === 'conversation.create') {
297
+ const operation = typeof input.operation_id === 'string' ? `${name}\u0000${input.operation_id}` : null;
298
+ const first = (answer) => {
299
+ if (operation !== null)
300
+ repeats.set(operation, answer);
301
+ return answer;
302
+ };
303
+ const repeated = operation === null ? undefined : repeats.get(operation);
304
+ if (name === 'conversations/create') {
305
+ if (repeated !== undefined)
306
+ return repeated;
212
307
  issued += 1;
213
308
  const conversation = `conversation-${issued}`;
214
309
  scripted.set(conversation, { conversation });
215
- return { kind: 'action', result: { conversation } };
310
+ return first({ kind: 'action', result: { conversation_id: conversation } });
216
311
  }
217
- const named = typeof input.conversation === 'string' ? input.conversation : '';
312
+ const named = typeof input.conversation_id === 'string' ? input.conversation_id : '';
218
313
  const conversation = scripted.get(named);
219
314
  if (conversation === undefined) {
220
315
  return {
@@ -227,34 +322,41 @@ export function createMemoryAdapter(options = {}) {
227
322
  const outcome = conversation.outcomes?.[name];
228
323
  if (outcome !== undefined)
229
324
  return outcome;
230
- if (name === 'conversation.send') {
231
- const operation = typeof input.operation_id === 'string' ? input.operation_id : null;
232
- const answered = operation === null ? undefined : sentTurns.get(operation);
233
- if (answered !== undefined)
234
- return { kind: 'action', result: { turn: answered } };
325
+ if (name === 'conversations/send') {
326
+ if (repeated !== undefined)
327
+ return repeated;
235
328
  issued += 1;
236
- const turn = `turn-${issued}`;
237
- unsealed.set(turn, named);
238
- if (operation !== null)
239
- sentTurns.set(operation, turn);
240
- return { kind: 'action', result: { turn } };
329
+ return first({ kind: 'action', result: { message_id: `turn-${issued}` } });
241
330
  }
242
- if (name === 'conversation.cancel') {
243
- const turn = typeof input.turn === 'string' ? input.turn : '';
244
- if (sealed.has(turn) || !unsealed.has(turn)) {
245
- return { kind: 'rejected', code: 'turn-sealed', fields: { turn }, retryable: false };
246
- }
247
- unsealed.delete(turn);
248
- return { kind: 'action', result: { turn, cancelled: true } };
249
- }
250
- if (name === 'conversation.delete')
331
+ if (name === 'conversations/delete')
251
332
  scripted.delete(named);
252
- return { kind: 'action', result: { conversation: named } };
333
+ return { kind: 'action', result: { conversation_id: named } };
334
+ }
335
+ function decided(request) {
336
+ const { request: asked, message, decision, } = (request.input ?? {});
337
+ return {
338
+ kind: 'action',
339
+ result: {
340
+ request: asked,
341
+ ...(message === undefined ? {} : { message }),
342
+ state: decision === 'approve' ? 'started' : 'declined',
343
+ },
344
+ };
253
345
  }
254
346
  function announceList() {
255
- const entries = [...scripted.values()].flatMap(({ conversation, listed }) => listed === undefined ? [] : [{ conversation, ...listed }]);
256
- for (const listener of listeners)
257
- listener({ kind: 'list', entries });
347
+ const entries = [...scripted.values()].flatMap(({ conversation, listed, messages = [] }) => listed === undefined
348
+ ? []
349
+ : [{ conversation, ...listed, newest: messages.at(-1)?.change ?? null }]);
350
+ for (const listener of listeners) {
351
+ listener({
352
+ kind: 'list',
353
+ agents: structuredClone(agents),
354
+ entries,
355
+ whole: true,
356
+ more: false,
357
+ cursor: null,
358
+ });
359
+ }
258
360
  }
259
361
  function discovery() {
260
362
  return {
@@ -266,8 +368,42 @@ export function createMemoryAdapter(options = {}) {
266
368
  ...(options.member === undefined ? {} : { member: options.member }),
267
369
  };
268
370
  }
371
+ function discovered() {
372
+ return resolveScript(scripts.discover, discovery, undefined).then((answer) => {
373
+ if (answer.kind === 'discovery')
374
+ for (const room of answer.rooms)
375
+ note(room.locator, room);
376
+ return answer;
377
+ });
378
+ }
379
+ function opened(notify) {
380
+ const opening = ++openings;
381
+ notify({ kind: 'opened' });
382
+ void discovered()
383
+ .catch(() => ({ kind: 'transport-uncertainty' }))
384
+ .then((answer) => {
385
+ if (opening !== openings)
386
+ return;
387
+ if (answer.kind !== 'discovery') {
388
+ openings += 1;
389
+ carried.clear();
390
+ const revoked = answer.kind === 'revoked-authorization';
391
+ notify({ kind: 'closed', revoked, lost: !revoked, authorityChanged: false });
392
+ return;
393
+ }
394
+ declaredRooms.clear();
395
+ for (const room of answer.rooms)
396
+ declaredRooms.add(room.locator);
397
+ notify({ kind: 'discovered', discovery: answer });
398
+ });
399
+ }
400
+ function emitAll(event) {
401
+ for (const observer of observers)
402
+ observer(event);
403
+ }
269
404
  return {
270
- ...(options.exhaustiveDiscovery === undefined ? {} : { exhaustiveDiscovery: true }),
405
+ ...(options.roomTypes === undefined ? {} : { roomTypes: options.roomTypes }),
406
+ ...(options.typedPaths === undefined ? {} : { typedPaths: options.typedPaths }),
271
407
  setRooms(next) {
272
408
  rooms = [...next];
273
409
  retain(rooms);
@@ -275,34 +411,41 @@ export function createMemoryAdapter(options = {}) {
275
411
  setConversations(next) {
276
412
  scriptConversations(next);
277
413
  },
414
+ setAgents(next) {
415
+ agents = structuredClone(next);
416
+ },
278
417
  open() {
418
+ carried.clear();
279
419
  announceList();
280
- for (const observer of observers)
281
- observer({ kind: 'opened' });
420
+ opened(emitAll);
282
421
  },
283
- close({ revoked = false, lost = !revoked } = {}) {
284
- for (const observer of observers)
285
- observer({ kind: 'closed', revoked, lost });
422
+ close({ revoked = false, lost = !revoked, authorityChanged = false } = {}) {
423
+ openings += 1;
424
+ carried.clear();
425
+ emitAll({ kind: 'closed', revoked, lost, authorityChanged });
286
426
  },
287
427
  expire(locators) {
288
428
  expiring = [...locators];
289
429
  },
290
- notifyRoomVersion({ locator, roomVersion }) {
291
- for (const observer of observers)
292
- observer({ kind: 'room-version', locator, roomVersion });
430
+ notifyRoomVersion({ locator }) {
431
+ carry(locator);
293
432
  },
294
- notifyAuthorityChanged(scope) {
295
- for (const observer of observers) {
296
- observer(scope === undefined
297
- ? { kind: 'authority-changed' }
298
- : { kind: 'authority-changed', scope });
299
- }
433
+ notifyAuthorityChanged(locators) {
434
+ const named = new Set(locators ?? [...declaredRooms, ...rooms.map((room) => room.locator)]);
435
+ const listed = rooms.filter((room) => named.has(room.locator));
436
+ const left = [...named].filter((locator) => !listed.some((room) => room.locator === locator));
437
+ for (const room of listed)
438
+ declaredRooms.add(room.locator);
439
+ for (const locator of left)
440
+ declaredRooms.delete(locator);
441
+ emitAll({
442
+ kind: 'authority-changed',
443
+ rooms: listed.map(declared),
444
+ left,
445
+ ...(options.member === undefined ? {} : { member: options.member }),
446
+ });
300
447
  },
301
448
  notifyConversation(event) {
302
- if (event.kind === 'accepted-message') {
303
- sealed.add(event.message.turn);
304
- unsealed.delete(event.message.turn);
305
- }
306
449
  for (const listener of listeners)
307
450
  listener(event);
308
451
  },
@@ -311,21 +454,28 @@ export function createMemoryAdapter(options = {}) {
311
454
  observer(mode);
312
455
  },
313
456
  heldRooms() {
314
- return held;
457
+ return [...carried.keys()].sort();
315
458
  },
316
459
  replicatedConversations() {
317
460
  return replicated;
318
461
  },
462
+ heldConversationCursor() {
463
+ return heldCursor;
464
+ },
319
465
  conversations: {
320
466
  replicate(next) {
321
467
  replicated = [...next];
322
468
  },
469
+ hold(cursor) {
470
+ heldCursor = cursor;
471
+ },
323
472
  observe(notify) {
324
473
  listeners.add(notify);
325
474
  return () => {
326
475
  listeners.delete(notify);
327
476
  };
328
477
  },
478
+ history: (request) => Promise.resolve(historiesOf(request)),
329
479
  },
330
480
  serviceMode: {
331
481
  observe(notify) {
@@ -337,44 +487,46 @@ export function createMemoryAdapter(options = {}) {
337
487
  },
338
488
  roomStream: {
339
489
  hold(asked) {
340
- held = asked.map((room) => room.locator);
341
- const expired = expiring.filter((locator) => held.includes(locator));
342
- expiring = [];
343
- const moved = asked.flatMap((room) => {
490
+ const named = asked.map((room) => room.locator);
491
+ const unknown = asked.flatMap((room) => {
344
492
  const current = rooms.find((entry) => entry.locator === room.locator);
493
+ const version = room.roomVersion;
345
494
  return current === undefined ||
346
- expired.includes(room.locator) ||
347
- current.roomVersion === room.roomVersion
495
+ (version !== null &&
496
+ (current.roomVersion === version || served.get(room.locator)?.has(version) === true))
348
497
  ? []
349
- : [{ locator: room.locator, roomVersion: current.roomVersion }];
498
+ : [room.locator];
350
499
  });
500
+ const expired = [
501
+ ...new Set([...expiring.filter((locator) => named.includes(locator)), ...unknown]),
502
+ ];
503
+ expiring = expiring.filter((locator) => !named.includes(locator));
351
504
  queueMicrotask(() => {
352
- for (const observer of observers) {
353
- for (const room of moved)
354
- observer({ kind: 'room-version', ...room });
355
- observer({ kind: 'opening', expired });
505
+ for (const room of asked) {
506
+ if (expired.includes(room.locator) || room.roomVersion === null)
507
+ carried.delete(room.locator);
508
+ else {
509
+ carried.set(room.locator, room.roomVersion);
510
+ carry(room.locator);
511
+ }
356
512
  }
513
+ emitAll({ kind: 'caught-up', expired });
357
514
  });
358
515
  },
359
- reopen() {
360
- queueMicrotask(() => {
361
- for (const observer of observers) {
362
- observer({ kind: 'closed', revoked: false, lost: false });
363
- }
364
- });
365
- },
366
- published() { },
367
516
  observe(notify) {
368
517
  observers.add(notify);
369
518
  queueMicrotask(() => {
370
519
  if (!observers.has(notify))
371
520
  return;
372
521
  if (options.unopened === true) {
373
- notify({ kind: 'closed', revoked: false, lost: true });
522
+ notify({ kind: 'closed', revoked: false, lost: true, authorityChanged: false });
374
523
  return;
375
524
  }
376
525
  announceList();
377
- notify({ kind: 'opened' });
526
+ opened((event) => {
527
+ if (observers.has(notify))
528
+ notify(event);
529
+ });
378
530
  });
379
531
  return () => {
380
532
  observers.delete(notify);
@@ -391,12 +543,7 @@ export function createMemoryAdapter(options = {}) {
391
543
  return resolveScript(scripts.authorize, () => ({}), undefined);
392
544
  },
393
545
  async discover(_authorization) {
394
- return resolveScript(scripts.discover, discovery, undefined).then((answer) => {
395
- if (answer.kind === 'discovery')
396
- for (const room of answer.rooms)
397
- note(room.locator, room);
398
- return answer;
399
- });
546
+ return discovered();
400
547
  },
401
548
  reached,
402
549
  follows(locator, roomVersion, next) {
@@ -453,7 +600,13 @@ export function createMemoryAdapter(options = {}) {
453
600
  retryable: false,
454
601
  affected: {},
455
602
  };
456
- }, request).then((answer) => note(request.locator, answer));
603
+ }, request).then((answer) => {
604
+ const destination = request.changeBatch.between?.destination.room;
605
+ if (answer.kind === 'accepted' && answer.destination !== undefined && destination) {
606
+ note(destination, answer.destination);
607
+ }
608
+ return note(request.locator, answer);
609
+ });
457
610
  },
458
611
  async history(_authorization, request) {
459
612
  return resolveScript(scripts.history, () => {
@@ -469,35 +622,45 @@ export function createMemoryAdapter(options = {}) {
469
622
  },
470
623
  async binary(_authorization, request) {
471
624
  return resolveScript(scripts.binary, () => {
472
- if (request.kind === 'reference') {
473
- return { kind: 'rejected', code: 'unscripted-binary', fields: {}, retryable: false };
474
- }
475
625
  const room = rooms.find((entry) => entry.locator === request.locator);
476
626
  if (room === undefined)
477
627
  return { kind: 'room-not-readable', locator: request.locator };
478
- const blob = room.blobs?.[request.path];
628
+ const blob = heldBlob(room, request.path);
479
629
  return blob === undefined
480
- ? { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false }
481
- : { kind: 'binary', blob };
630
+ ? { kind: 'rejected', code: 'not_found', fields: {}, retryable: false }
631
+ : { kind: 'binary', body: blob.stream(), mediaType: declaredType(blob) };
482
632
  }, request);
483
633
  },
484
634
  async link(_authorization, request) {
485
- return resolveScript(scripts.link, () => ({ kind: 'rejected', code: 'unscripted-link', fields: {}, retryable: false }), request);
635
+ return resolveScript(scripts.link, () => {
636
+ const room = rooms.find((entry) => entry.locator === request.locator);
637
+ if (room === undefined)
638
+ return { kind: 'room-not-readable', locator: request.locator };
639
+ const blob = heldBlob(room, request.path);
640
+ if (blob === undefined) {
641
+ return { kind: 'rejected', code: 'not_found', fields: {}, retryable: false };
642
+ }
643
+ const url = linked.get(blob) ?? URL.createObjectURL(blob);
644
+ linked.set(blob, url);
645
+ return { kind: 'link', url, name: lastName(request.path), mediaType: declaredType(blob) };
646
+ }, request);
486
647
  },
487
- referrerScope(referrer) {
488
- if (typeof referrer !== 'object' || referrer === null)
489
- return null;
490
- const { room, path, message } = referrer;
491
- if (typeof message === 'string')
492
- return { kind: 'conversations' };
493
- if (typeof room !== 'string')
494
- return null;
495
- return { kind: 'room', locator: room, ...(typeof path === 'string' ? { path } : {}) };
648
+ async attach(_authorization, request) {
649
+ return resolveScript(scripts.attach, () => {
650
+ const room = rooms.find((entry) => entry.locator === request.locator);
651
+ if (room === undefined)
652
+ return { kind: 'room-not-readable', locator: request.locator };
653
+ const path = freePath(room, request.name);
654
+ attached.set(`${room.locator}\u0000${path}`, request.blob);
655
+ return { kind: 'attached', path, revision: `attached-${attached.size}` };
656
+ }, request);
496
657
  },
497
658
  async action(_authorization, request) {
498
659
  return resolveScript(scripts.action, () => {
499
- if (request.name.startsWith('conversation.'))
660
+ if (request.name.startsWith('conversations/'))
500
661
  return conversationAction(request);
662
+ if (request.name === 'agent-functions/decide')
663
+ return decided(request);
501
664
  return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
502
665
  }, request).then((answer) => {
503
666
  if (answer.kind === 'action' && answer.at !== undefined)