@dxos/assistant-toolkit 0.9.1-staging.ee54ba693a → 0.11.0

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 (397) hide show
  1. package/dist/lib/chunk-Chat.mjs +144 -0
  2. package/dist/lib/chunk-Chat.mjs.map +1 -0
  3. package/dist/lib/chunk-Memory.mjs +19 -0
  4. package/dist/lib/chunk-Memory.mjs.map +1 -0
  5. package/dist/lib/{neutral/agent-rules-KWCBKJ5W.mjs → chunk-agent-rules.mjs} +8 -15
  6. package/dist/lib/chunk-agent-rules.mjs.map +1 -0
  7. package/dist/lib/chunk-agent.mjs +45 -0
  8. package/dist/lib/chunk-agent.mjs.map +1 -0
  9. package/dist/lib/chunk-artifact-add.mjs +31 -0
  10. package/dist/lib/chunk-artifact-add.mjs.map +1 -0
  11. package/dist/lib/chunk-artifact-list.mjs +23 -0
  12. package/dist/lib/chunk-artifact-list.mjs.map +1 -0
  13. package/dist/lib/chunk-context-add.mjs +16 -0
  14. package/dist/lib/chunk-context-add.mjs.map +1 -0
  15. package/dist/lib/chunk-context-remove.mjs +16 -0
  16. package/dist/lib/chunk-context-remove.mjs.map +1 -0
  17. package/dist/lib/chunk-create-agent.mjs +23 -0
  18. package/dist/lib/chunk-create-agent.mjs.map +1 -0
  19. package/dist/lib/chunk-definitions.mjs +52 -0
  20. package/dist/lib/chunk-definitions.mjs.map +1 -0
  21. package/dist/lib/chunk-definitions2.mjs +56 -0
  22. package/dist/lib/chunk-definitions2.mjs.map +1 -0
  23. package/dist/lib/chunk-definitions3.mjs +24 -0
  24. package/dist/lib/chunk-definitions3.mjs.map +1 -0
  25. package/dist/lib/chunk-delete.mjs +14 -0
  26. package/dist/lib/chunk-delete.mjs.map +1 -0
  27. package/dist/lib/chunk-enable-skills.mjs +39 -0
  28. package/dist/lib/chunk-enable-skills.mjs.map +1 -0
  29. package/dist/lib/chunk-fetch-messages.mjs +113 -0
  30. package/dist/lib/chunk-fetch-messages.mjs.map +1 -0
  31. package/dist/lib/chunk-fetch.mjs +20 -0
  32. package/dist/lib/chunk-fetch.mjs.map +1 -0
  33. package/dist/lib/chunk-get-context.mjs +55 -0
  34. package/dist/lib/chunk-get-context.mjs.map +1 -0
  35. package/dist/lib/chunk-get-current-date.mjs +17 -0
  36. package/dist/lib/chunk-get-current-date.mjs.map +1 -0
  37. package/dist/lib/chunk-load.mjs +13 -0
  38. package/dist/lib/chunk-load.mjs.map +1 -0
  39. package/dist/lib/chunk-object-create.mjs +42 -0
  40. package/dist/lib/chunk-object-create.mjs.map +1 -0
  41. package/dist/lib/chunk-object-delete.mjs +14 -0
  42. package/dist/lib/chunk-object-delete.mjs.map +1 -0
  43. package/dist/lib/chunk-object-update.mjs +19 -0
  44. package/dist/lib/chunk-object-update.mjs.map +1 -0
  45. package/dist/lib/chunk-operations.mjs +714 -0
  46. package/dist/lib/chunk-operations.mjs.map +1 -0
  47. package/dist/lib/chunk-plan-reminder.mjs +80 -0
  48. package/dist/lib/chunk-plan-reminder.mjs.map +1 -0
  49. package/dist/lib/chunk-query-skills.mjs +12 -0
  50. package/dist/lib/chunk-query-skills.mjs.map +1 -0
  51. package/dist/lib/chunk-query.mjs +36 -0
  52. package/dist/lib/chunk-query.mjs.map +1 -0
  53. package/dist/lib/chunk-query2.mjs +18 -0
  54. package/dist/lib/chunk-query2.mjs.map +1 -0
  55. package/dist/lib/chunk-relation-create.mjs +41 -0
  56. package/dist/lib/chunk-relation-create.mjs.map +1 -0
  57. package/dist/lib/chunk-relation-delete.mjs +14 -0
  58. package/dist/lib/chunk-relation-delete.mjs.map +1 -0
  59. package/dist/lib/chunk-relay.mjs +76 -0
  60. package/dist/lib/chunk-relay.mjs.map +1 -0
  61. package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
  62. package/dist/lib/chunk-run-instructions.mjs +145 -0
  63. package/dist/lib/chunk-run-instructions.mjs.map +1 -0
  64. package/dist/lib/chunk-save.mjs +17 -0
  65. package/dist/lib/chunk-save.mjs.map +1 -0
  66. package/dist/lib/chunk-schema-add.mjs +19 -0
  67. package/dist/lib/chunk-schema-add.mjs.map +1 -0
  68. package/dist/lib/chunk-schema-list.mjs +29 -0
  69. package/dist/lib/chunk-schema-list.mjs.map +1 -0
  70. package/dist/lib/chunk-set-alarm.mjs +55 -0
  71. package/dist/lib/chunk-set-alarm.mjs.map +1 -0
  72. package/dist/lib/chunk-sync-automation.mjs +130 -0
  73. package/dist/lib/chunk-sync-automation.mjs.map +1 -0
  74. package/dist/lib/chunk-sync-issues.mjs +127 -0
  75. package/dist/lib/chunk-sync-issues.mjs.map +1 -0
  76. package/dist/lib/chunk-sync.mjs +91 -0
  77. package/dist/lib/chunk-sync.mjs.map +1 -0
  78. package/dist/lib/chunk-tag-add.mjs +14 -0
  79. package/dist/lib/chunk-tag-add.mjs.map +1 -0
  80. package/dist/lib/chunk-tag-remove.mjs +14 -0
  81. package/dist/lib/chunk-tag-remove.mjs.map +1 -0
  82. package/dist/lib/chunk-types.mjs +198 -0
  83. package/dist/lib/chunk-types.mjs.map +1 -0
  84. package/dist/lib/chunk-update-tasks.mjs +34 -0
  85. package/dist/lib/chunk-update-tasks.mjs.map +1 -0
  86. package/dist/lib/index.mjs +614 -0
  87. package/dist/lib/index.mjs.map +1 -0
  88. package/dist/lib/testing.mjs +102 -0
  89. package/dist/lib/testing.mjs.map +1 -0
  90. package/dist/types/src/skills/agent/operations/definitions.d.ts +16 -46
  91. package/dist/types/src/skills/agent/operations/definitions.d.ts.map +1 -1
  92. package/dist/types/src/skills/agent/operations/get-context.test.d.ts +2 -0
  93. package/dist/types/src/skills/agent/operations/get-context.test.d.ts.map +1 -0
  94. package/dist/types/src/skills/agent/operations/index.d.ts.map +1 -1
  95. package/dist/types/src/skills/agent/operations/relay.d.ts +11 -0
  96. package/dist/types/src/skills/agent/operations/relay.d.ts.map +1 -0
  97. package/dist/types/src/skills/agent/operations/relay.test.d.ts +2 -0
  98. package/dist/types/src/skills/agent/operations/relay.test.d.ts.map +1 -0
  99. package/dist/types/src/skills/agent/skill.d.ts.map +1 -1
  100. package/dist/types/src/skills/agent-wizard/operations/definitions.d.ts +4 -1
  101. package/dist/types/src/skills/agent-wizard/operations/definitions.d.ts.map +1 -1
  102. package/dist/types/src/skills/agent-wizard/operations/sync-automation.d.ts +26 -0
  103. package/dist/types/src/skills/agent-wizard/operations/sync-automation.d.ts.map +1 -0
  104. package/dist/types/src/skills/agent-wizard/operations/sync-automation.test.d.ts +2 -0
  105. package/dist/types/src/skills/agent-wizard/operations/sync-automation.test.d.ts.map +1 -0
  106. package/dist/types/src/skills/agent-wizard/skill.d.ts.map +1 -1
  107. package/dist/types/src/skills/database/operations/context-add.test.d.ts +2 -0
  108. package/dist/types/src/skills/database/operations/context-add.test.d.ts.map +1 -0
  109. package/dist/types/src/skills/database/operations/context-remove.test.d.ts +2 -0
  110. package/dist/types/src/skills/database/operations/context-remove.test.d.ts.map +1 -0
  111. package/dist/types/src/skills/database/operations/definitions.d.ts +7 -2
  112. package/dist/types/src/skills/database/operations/definitions.d.ts.map +1 -1
  113. package/dist/types/src/skills/database/operations/load.test.d.ts +2 -0
  114. package/dist/types/src/skills/database/operations/load.test.d.ts.map +1 -0
  115. package/dist/types/src/skills/database/operations/object-create.d.ts +4 -1
  116. package/dist/types/src/skills/database/operations/object-create.d.ts.map +1 -1
  117. package/dist/types/src/skills/database/operations/object-create.test.d.ts +2 -0
  118. package/dist/types/src/skills/database/operations/object-create.test.d.ts.map +1 -0
  119. package/dist/types/src/skills/database/operations/object-delete.test.d.ts +2 -0
  120. package/dist/types/src/skills/database/operations/object-delete.test.d.ts.map +1 -0
  121. package/dist/types/src/skills/database/operations/object-update.test.d.ts +2 -0
  122. package/dist/types/src/skills/database/operations/object-update.test.d.ts.map +1 -0
  123. package/dist/types/src/skills/database/operations/query.test.d.ts +2 -0
  124. package/dist/types/src/skills/database/operations/query.test.d.ts.map +1 -0
  125. package/dist/types/src/skills/database/operations/relation-create.test.d.ts +2 -0
  126. package/dist/types/src/skills/database/operations/relation-create.test.d.ts.map +1 -0
  127. package/dist/types/src/skills/database/operations/schema-add.d.ts +3 -1
  128. package/dist/types/src/skills/database/operations/schema-add.test.d.ts +2 -0
  129. package/dist/types/src/skills/database/operations/schema-add.test.d.ts.map +1 -0
  130. package/dist/types/src/skills/database/operations/schema-list.test.d.ts +2 -0
  131. package/dist/types/src/skills/database/operations/schema-list.test.d.ts.map +1 -0
  132. package/dist/types/src/skills/database/operations/tag-add.test.d.ts +2 -0
  133. package/dist/types/src/skills/database/operations/tag-add.test.d.ts.map +1 -0
  134. package/dist/types/src/skills/database/operations/tag-remove.test.d.ts +2 -0
  135. package/dist/types/src/skills/database/operations/tag-remove.test.d.ts.map +1 -0
  136. package/dist/types/src/skills/delegation/operations/delegate-task.d.ts +6 -5
  137. package/dist/types/src/skills/delegation/operations/delegate-task.d.ts.map +1 -1
  138. package/dist/types/src/skills/index.d.ts +1 -0
  139. package/dist/types/src/skills/index.d.ts.map +1 -1
  140. package/dist/types/src/skills/linear/operations/sync-issues.d.ts.map +1 -1
  141. package/dist/types/src/skills/memory/operations/delete.test.d.ts +2 -0
  142. package/dist/types/src/skills/memory/operations/delete.test.d.ts.map +1 -0
  143. package/dist/types/src/skills/memory/operations/query.test.d.ts +2 -0
  144. package/dist/types/src/skills/memory/operations/query.test.d.ts.map +1 -0
  145. package/dist/types/src/skills/memory/operations/save.test.d.ts +2 -0
  146. package/dist/types/src/skills/memory/operations/save.test.d.ts.map +1 -0
  147. package/dist/types/src/skills/planning/operations/definitions.d.ts +1 -3
  148. package/dist/types/src/skills/planning/operations/definitions.d.ts.map +1 -1
  149. package/dist/types/src/skills/planning/operations/plan-reminder.d.ts +7 -6
  150. package/dist/types/src/skills/planning/operations/plan-reminder.d.ts.map +1 -1
  151. package/dist/types/src/skills/planning/operations/plan-reminder.test.d.ts +2 -0
  152. package/dist/types/src/skills/planning/operations/plan-reminder.test.d.ts.map +1 -0
  153. package/dist/types/src/skills/planning/operations/update-tasks.d.ts +3 -1
  154. package/dist/types/src/skills/planning/operations/update-tasks.d.ts.map +1 -1
  155. package/dist/types/src/skills/project/index.d.ts +3 -0
  156. package/dist/types/src/skills/project/index.d.ts.map +1 -0
  157. package/dist/types/src/skills/project/operations/artifact-add.d.ts +5 -0
  158. package/dist/types/src/skills/project/operations/artifact-add.d.ts.map +1 -0
  159. package/dist/types/src/skills/project/operations/artifact-list.d.ts +5 -0
  160. package/dist/types/src/skills/project/operations/artifact-list.d.ts.map +1 -0
  161. package/dist/types/src/skills/project/operations/definitions.d.ts +23 -0
  162. package/dist/types/src/skills/project/operations/definitions.d.ts.map +1 -0
  163. package/dist/types/src/skills/project/operations/index.d.ts +4 -0
  164. package/dist/types/src/skills/project/operations/index.d.ts.map +1 -0
  165. package/dist/types/src/skills/project/skill.d.ts +4 -0
  166. package/dist/types/src/skills/project/skill.d.ts.map +1 -0
  167. package/dist/types/src/skills/project/skill.test.d.ts.map +1 -0
  168. package/dist/types/src/skills/skill-manager/skill.d.ts.map +1 -1
  169. package/dist/types/src/supervisor/delegation-strategy.d.ts +5 -5
  170. package/dist/types/src/supervisor/delegation-strategy.d.ts.map +1 -1
  171. package/dist/types/src/supervisor/delegation-strategy.test.d.ts +2 -0
  172. package/dist/types/src/supervisor/delegation-strategy.test.d.ts.map +1 -0
  173. package/dist/types/src/sync/sync.test.d.ts +2 -0
  174. package/dist/types/src/sync/sync.test.d.ts.map +1 -0
  175. package/dist/types/src/testing/index.d.ts +1 -0
  176. package/dist/types/src/testing/index.d.ts.map +1 -1
  177. package/dist/types/src/testing/operations.d.ts +7 -0
  178. package/dist/types/src/testing/operations.d.ts.map +1 -0
  179. package/dist/types/src/types/Agent.d.ts +28 -31
  180. package/dist/types/src/types/Agent.d.ts.map +1 -1
  181. package/dist/types/src/types/Chat.d.ts +28 -14
  182. package/dist/types/src/types/Chat.d.ts.map +1 -1
  183. package/dist/types/src/types/Chat.test.d.ts +2 -0
  184. package/dist/types/src/types/Chat.test.d.ts.map +1 -0
  185. package/dist/types/src/types/index.d.ts +1 -2
  186. package/dist/types/src/types/index.d.ts.map +1 -1
  187. package/dist/types/tsconfig.tsbuildinfo +1 -1
  188. package/package.json +30 -29
  189. package/src/operations/run-instructions.test.ts +26 -34
  190. package/src/operations/skill-resolution.test.ts +6 -1
  191. package/src/skills/agent/operations/definitions.ts +18 -62
  192. package/src/skills/agent/operations/get-context.test.ts +81 -0
  193. package/src/skills/agent/operations/get-context.ts +9 -36
  194. package/src/skills/agent/operations/index.ts +1 -3
  195. package/src/skills/agent/operations/relay.test.ts +63 -0
  196. package/src/skills/agent/operations/relay.ts +124 -0
  197. package/src/skills/agent/skill.ts +3 -15
  198. package/src/skills/agent-wizard/operations/create-agent.ts +3 -3
  199. package/src/skills/agent-wizard/operations/definitions.ts +19 -4
  200. package/src/skills/agent-wizard/operations/index.ts +1 -1
  201. package/src/skills/agent-wizard/operations/sync-automation.test.ts +103 -0
  202. package/src/skills/agent-wizard/operations/sync-automation.ts +205 -0
  203. package/src/skills/agent-wizard/skill.ts +9 -10
  204. package/src/skills/alarm/skill.test.ts +2 -2
  205. package/src/skills/browser/skill.test.ts +4 -4
  206. package/src/skills/database/operations/context-add.test.ts +46 -0
  207. package/src/skills/database/operations/context-remove.test.ts +46 -0
  208. package/src/skills/database/operations/definitions.ts +23 -7
  209. package/src/skills/database/operations/load.test.ts +38 -0
  210. package/src/skills/database/operations/object-create.test.ts +116 -0
  211. package/src/skills/database/operations/object-create.ts +13 -2
  212. package/src/skills/database/operations/object-delete.test.ts +37 -0
  213. package/src/skills/database/operations/object-update.test.ts +39 -0
  214. package/src/skills/database/operations/query.test.ts +128 -0
  215. package/src/skills/database/operations/relation-create.test.ts +46 -0
  216. package/src/skills/database/operations/schema-add.test.ts +79 -0
  217. package/src/skills/database/operations/schema-list.test.ts +42 -0
  218. package/src/skills/database/operations/tag-add.test.ts +41 -0
  219. package/src/skills/database/operations/tag-remove.test.ts +43 -0
  220. package/src/skills/delegation/operations/delegate-task.test.ts +51 -36
  221. package/src/skills/delegation/operations/delegate-task.ts +31 -48
  222. package/src/skills/discord/operations/fetch-messages.test.ts +2 -2
  223. package/src/skills/github/operations/fetch-prs.ts +1 -1
  224. package/src/skills/index.ts +1 -0
  225. package/src/skills/linear/operations/linear.test.ts +1 -1
  226. package/src/skills/linear/operations/sync-issues.ts +6 -23
  227. package/src/skills/memory/operations/delete.test.ts +37 -0
  228. package/src/skills/memory/operations/query.test.ts +76 -0
  229. package/src/skills/memory/operations/save.test.ts +43 -0
  230. package/src/skills/planning/operations/definitions.ts +9 -6
  231. package/src/skills/planning/operations/plan-reminder.test.ts +123 -0
  232. package/src/skills/planning/operations/plan-reminder.ts +49 -31
  233. package/src/skills/planning/operations/update-tasks.md +23 -22
  234. package/src/skills/planning/operations/update-tasks.test.ts +31 -17
  235. package/src/skills/planning/operations/update-tasks.ts +17 -25
  236. package/src/skills/project/index.ts +6 -0
  237. package/src/skills/project/operations/artifact-add.ts +47 -0
  238. package/src/skills/project/operations/artifact-list.ts +41 -0
  239. package/src/skills/project/operations/definitions.ts +63 -0
  240. package/src/skills/project/operations/index.ts +12 -0
  241. package/src/skills/project/skill.test.ts +78 -0
  242. package/src/skills/project/skill.ts +42 -0
  243. package/src/skills/skill-manager/operations/definitions.ts +1 -1
  244. package/src/skills/skill-manager/skill.test.ts +1 -1
  245. package/src/skills/skill-manager/skill.ts +7 -5
  246. package/src/skills/websearch/skill.test.ts +2 -2
  247. package/src/supervisor/delegation-strategy.test.ts +129 -0
  248. package/src/supervisor/delegation-strategy.ts +92 -56
  249. package/src/sync/sync.test.ts +95 -0
  250. package/src/sync/sync.ts +5 -3
  251. package/src/testing/index.ts +1 -0
  252. package/src/testing/operations.ts +65 -0
  253. package/src/types/Agent.test.ts +36 -66
  254. package/src/types/Agent.ts +108 -137
  255. package/src/types/Chat.test.ts +234 -0
  256. package/src/types/Chat.ts +80 -26
  257. package/src/types/index.ts +1 -2
  258. package/dist/lib/neutral/add-artifact-5JNUYLCA.mjs +0 -24
  259. package/dist/lib/neutral/add-artifact-5JNUYLCA.mjs.map +0 -7
  260. package/dist/lib/neutral/agent-BFAYIBJI.mjs +0 -65
  261. package/dist/lib/neutral/agent-BFAYIBJI.mjs.map +0 -7
  262. package/dist/lib/neutral/agent-rules-KWCBKJ5W.mjs.map +0 -7
  263. package/dist/lib/neutral/chunk-3KA66YBF.mjs +0 -62
  264. package/dist/lib/neutral/chunk-3KA66YBF.mjs.map +0 -7
  265. package/dist/lib/neutral/chunk-6SGNFL6I.mjs +0 -85
  266. package/dist/lib/neutral/chunk-6SGNFL6I.mjs.map +0 -7
  267. package/dist/lib/neutral/chunk-BDTGFPM7.mjs +0 -113
  268. package/dist/lib/neutral/chunk-BDTGFPM7.mjs.map +0 -7
  269. package/dist/lib/neutral/chunk-EPQCDGIV.mjs +0 -27
  270. package/dist/lib/neutral/chunk-EPQCDGIV.mjs.map +0 -7
  271. package/dist/lib/neutral/chunk-H4W22FFJ.mjs +0 -232
  272. package/dist/lib/neutral/chunk-H4W22FFJ.mjs.map +0 -7
  273. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
  274. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
  275. package/dist/lib/neutral/chunk-JBTXZQ5G.mjs +0 -60
  276. package/dist/lib/neutral/chunk-JBTXZQ5G.mjs.map +0 -7
  277. package/dist/lib/neutral/chunk-JKOOA5OS.mjs +0 -97
  278. package/dist/lib/neutral/chunk-JKOOA5OS.mjs.map +0 -7
  279. package/dist/lib/neutral/chunk-JTEBE7KA.mjs +0 -66
  280. package/dist/lib/neutral/chunk-JTEBE7KA.mjs.map +0 -7
  281. package/dist/lib/neutral/chunk-KLFXJ2Z3.mjs +0 -36
  282. package/dist/lib/neutral/chunk-KLFXJ2Z3.mjs.map +0 -7
  283. package/dist/lib/neutral/chunk-LBA5UOLF.mjs +0 -87
  284. package/dist/lib/neutral/chunk-LBA5UOLF.mjs.map +0 -7
  285. package/dist/lib/neutral/chunk-LL3MOQUZ.mjs +0 -120
  286. package/dist/lib/neutral/chunk-LL3MOQUZ.mjs.map +0 -7
  287. package/dist/lib/neutral/chunk-MFVIGJBW.mjs +0 -68
  288. package/dist/lib/neutral/chunk-MFVIGJBW.mjs.map +0 -7
  289. package/dist/lib/neutral/chunk-PBARVBNJ.mjs +0 -86
  290. package/dist/lib/neutral/chunk-PBARVBNJ.mjs.map +0 -7
  291. package/dist/lib/neutral/chunk-VJ5QBYM5.mjs +0 -61
  292. package/dist/lib/neutral/chunk-VJ5QBYM5.mjs.map +0 -7
  293. package/dist/lib/neutral/chunk-YQSQRSXG.mjs +0 -367
  294. package/dist/lib/neutral/chunk-YQSQRSXG.mjs.map +0 -7
  295. package/dist/lib/neutral/chunk-Z2HFOZXK.mjs +0 -191
  296. package/dist/lib/neutral/chunk-Z2HFOZXK.mjs.map +0 -7
  297. package/dist/lib/neutral/context-add-DZTPB3FK.mjs +0 -22
  298. package/dist/lib/neutral/context-add-DZTPB3FK.mjs.map +0 -7
  299. package/dist/lib/neutral/context-remove-XSBOM4VJ.mjs +0 -22
  300. package/dist/lib/neutral/context-remove-XSBOM4VJ.mjs.map +0 -7
  301. package/dist/lib/neutral/create-agent-5WTOFIEK.mjs +0 -35
  302. package/dist/lib/neutral/create-agent-5WTOFIEK.mjs.map +0 -7
  303. package/dist/lib/neutral/definitions-VRR5OGXI.mjs +0 -17
  304. package/dist/lib/neutral/definitions-VRR5OGXI.mjs.map +0 -7
  305. package/dist/lib/neutral/delegate-task-UX64NK4M.mjs +0 -13
  306. package/dist/lib/neutral/delegate-task-UX64NK4M.mjs.map +0 -7
  307. package/dist/lib/neutral/delete-IU7HPU3K.mjs +0 -19
  308. package/dist/lib/neutral/delete-IU7HPU3K.mjs.map +0 -7
  309. package/dist/lib/neutral/enable-skills-FHEJXQVB.mjs +0 -47
  310. package/dist/lib/neutral/enable-skills-FHEJXQVB.mjs.map +0 -7
  311. package/dist/lib/neutral/fetch-5LY25EBR.mjs +0 -24
  312. package/dist/lib/neutral/fetch-5LY25EBR.mjs.map +0 -7
  313. package/dist/lib/neutral/fetch-messages-CQMDI36G.mjs +0 -139
  314. package/dist/lib/neutral/fetch-messages-CQMDI36G.mjs.map +0 -7
  315. package/dist/lib/neutral/get-context-Q4YY6DRV.mjs +0 -77
  316. package/dist/lib/neutral/get-context-Q4YY6DRV.mjs.map +0 -7
  317. package/dist/lib/neutral/get-current-date-JR5F7ZS3.mjs +0 -17
  318. package/dist/lib/neutral/get-current-date-JR5F7ZS3.mjs.map +0 -7
  319. package/dist/lib/neutral/index.mjs +0 -875
  320. package/dist/lib/neutral/index.mjs.map +0 -7
  321. package/dist/lib/neutral/load-S6HC5TGX.mjs +0 -17
  322. package/dist/lib/neutral/load-S6HC5TGX.mjs.map +0 -7
  323. package/dist/lib/neutral/meta.json +0 -1
  324. package/dist/lib/neutral/object-create-PVDQ62CG.mjs +0 -32
  325. package/dist/lib/neutral/object-create-PVDQ62CG.mjs.map +0 -7
  326. package/dist/lib/neutral/object-delete-3CSL6XI6.mjs +0 -18
  327. package/dist/lib/neutral/object-delete-3CSL6XI6.mjs.map +0 -7
  328. package/dist/lib/neutral/object-update-NIGMZINM.mjs +0 -28
  329. package/dist/lib/neutral/object-update-NIGMZINM.mjs.map +0 -7
  330. package/dist/lib/neutral/plan-reminder-N4X6JPBI.mjs +0 -88
  331. package/dist/lib/neutral/plan-reminder-N4X6JPBI.mjs.map +0 -7
  332. package/dist/lib/neutral/qualifier-5CIRZYX5.mjs +0 -91
  333. package/dist/lib/neutral/qualifier-5CIRZYX5.mjs.map +0 -7
  334. package/dist/lib/neutral/query-K4R7UHLU.mjs +0 -32
  335. package/dist/lib/neutral/query-K4R7UHLU.mjs.map +0 -7
  336. package/dist/lib/neutral/query-NCTCRYTD.mjs +0 -59
  337. package/dist/lib/neutral/query-NCTCRYTD.mjs.map +0 -7
  338. package/dist/lib/neutral/query-skills-7GQFSU4V.mjs +0 -17
  339. package/dist/lib/neutral/query-skills-7GQFSU4V.mjs.map +0 -7
  340. package/dist/lib/neutral/relation-create-QKXHTL7G.mjs +0 -34
  341. package/dist/lib/neutral/relation-create-QKXHTL7G.mjs.map +0 -7
  342. package/dist/lib/neutral/relation-delete-PDIWT2JX.mjs +0 -18
  343. package/dist/lib/neutral/relation-delete-PDIWT2JX.mjs.map +0 -7
  344. package/dist/lib/neutral/run-instructions-72ASH5EZ.mjs +0 -165
  345. package/dist/lib/neutral/run-instructions-72ASH5EZ.mjs.map +0 -7
  346. package/dist/lib/neutral/save-UYVRA4RS.mjs +0 -23
  347. package/dist/lib/neutral/save-UYVRA4RS.mjs.map +0 -7
  348. package/dist/lib/neutral/schema-add-5NOK2RWE.mjs +0 -25
  349. package/dist/lib/neutral/schema-add-5NOK2RWE.mjs.map +0 -7
  350. package/dist/lib/neutral/schema-list-BZUR5KMX.mjs +0 -37
  351. package/dist/lib/neutral/schema-list-BZUR5KMX.mjs.map +0 -7
  352. package/dist/lib/neutral/set-alarm-BD3NEYSU.mjs +0 -65
  353. package/dist/lib/neutral/set-alarm-BD3NEYSU.mjs.map +0 -7
  354. package/dist/lib/neutral/sync-issues-O76MCMD3.mjs +0 -166
  355. package/dist/lib/neutral/sync-issues-O76MCMD3.mjs.map +0 -7
  356. package/dist/lib/neutral/sync-triggers-YBTLPCUB.mjs +0 -138
  357. package/dist/lib/neutral/sync-triggers-YBTLPCUB.mjs.map +0 -7
  358. package/dist/lib/neutral/tag-add-L5WNOBYY.mjs +0 -18
  359. package/dist/lib/neutral/tag-add-L5WNOBYY.mjs.map +0 -7
  360. package/dist/lib/neutral/tag-remove-WV5RPE5W.mjs +0 -18
  361. package/dist/lib/neutral/tag-remove-WV5RPE5W.mjs.map +0 -7
  362. package/dist/lib/neutral/testing/index.mjs +0 -65
  363. package/dist/lib/neutral/testing/index.mjs.map +0 -7
  364. package/dist/lib/neutral/update-tasks-HX4ILWOU.mjs +0 -46
  365. package/dist/lib/neutral/update-tasks-HX4ILWOU.mjs.map +0 -7
  366. package/dist/types/src/skills/agent/operations/add-artifact.d.ts +0 -4
  367. package/dist/types/src/skills/agent/operations/add-artifact.d.ts.map +0 -1
  368. package/dist/types/src/skills/agent/operations/agent.d.ts +0 -4
  369. package/dist/types/src/skills/agent/operations/agent.d.ts.map +0 -1
  370. package/dist/types/src/skills/agent/operations/qualifier.d.ts +0 -5
  371. package/dist/types/src/skills/agent/operations/qualifier.d.ts.map +0 -1
  372. package/dist/types/src/skills/agent/skill.test.d.ts.map +0 -1
  373. package/dist/types/src/skills/agent-wizard/operations/sync-triggers.d.ts +0 -8
  374. package/dist/types/src/skills/agent-wizard/operations/sync-triggers.d.ts.map +0 -1
  375. package/dist/types/src/skills/database/skill.test.d.ts +0 -2
  376. package/dist/types/src/skills/database/skill.test.d.ts.map +0 -1
  377. package/dist/types/src/skills/memory/skill.test.d.ts +0 -2
  378. package/dist/types/src/skills/memory/skill.test.d.ts.map +0 -1
  379. package/dist/types/src/skills/planning/skill.test.d.ts +0 -2
  380. package/dist/types/src/skills/planning/skill.test.d.ts.map +0 -1
  381. package/dist/types/src/types/Plan.d.ts +0 -80
  382. package/dist/types/src/types/Plan.d.ts.map +0 -1
  383. package/src/operations/run-instructions.conversations.json +0 -1
  384. package/src/skills/agent/operations/add-artifact.ts +0 -20
  385. package/src/skills/agent/operations/agent.ts +0 -69
  386. package/src/skills/agent/operations/qualifier.ts +0 -97
  387. package/src/skills/agent/skill.conversations.json +0 -1
  388. package/src/skills/agent/skill.test.ts +0 -728
  389. package/src/skills/agent-wizard/operations/sync-triggers.ts +0 -169
  390. package/src/skills/database/skill.conversations.json +0 -1
  391. package/src/skills/database/skill.test.ts +0 -531
  392. package/src/skills/memory/skill.conversations.json +0 -1
  393. package/src/skills/memory/skill.test.ts +0 -138
  394. package/src/skills/planning/skill.conversations.json +0 -1
  395. package/src/skills/planning/skill.test.ts +0 -123
  396. package/src/types/Plan.ts +0 -123
  397. /package/dist/types/src/skills/{agent → project}/skill.test.d.ts +0 -0
@@ -8,106 +8,99 @@ import * as Effect from 'effect/Effect';
8
8
  import * as Schema from 'effect/Schema';
9
9
 
10
10
  import { AiContext, Harness } from '@dxos/assistant';
11
- import { type Skill } from '@dxos/compute';
12
- import { Annotation, Database, DXN, Feed, Filter, Format, Obj, Ref, Relation, Type } from '@dxos/echo';
13
- import { FormInputAnnotation } from '@dxos/echo/Annotation';
11
+ import { Instructions, type Skill } from '@dxos/compute';
12
+ import { Annotation, Database, DXN, Feed, Filter, Obj, Query, Ref, Relation, Type } from '@dxos/echo';
14
13
  import { type EntityNotFoundError } from '@dxos/echo/Err';
15
14
  import { EffectEx } from '@dxos/effect';
16
- import { invariant } from '@dxos/invariant';
17
- import { EID, type EntityId } from '@dxos/keys';
18
- import { Text } from '@dxos/schema';
15
+ import { IdentityDid } from '@dxos/keys';
19
16
 
20
17
  import { HarnessContextError } from '../errors';
21
18
  import * as Chat from './Chat';
22
19
 
23
20
  /**
24
- * Agent schema definition.
21
+ * An agent identity: a personality (attribution DID) plus its preset payload (instructions with
22
+ * text, skills, objects, and commands). Owns no conversation state — a chat is linked to the agent
23
+ * it runs as by a `CompanionTo` relation, and durable work products live on a Project
24
+ * (plugin-projects DESIGN.md, "Agent ↔ Project convergence").
25
25
  */
26
- export class Agent extends Type.makeObject<Agent>(DXN.make('org.dxos.type.agent', '0.1.0'))(
26
+ export class Agent extends Type.makeObject<Agent>(DXN.make('org.dxos.type.agent', '0.2.0'))(
27
27
  Schema.Struct({
28
28
  name: Schema.optional(Schema.String),
29
29
 
30
30
  /**
31
- * When false, agent triggers are disabled after sync-triggers runs.
31
+ * Stable identity DID for the agent, used to attribute content it authors (e.g. suggestion
32
+ * branches) as its own author — distinct from any human or other agent. Provisioned
33
+ * externally, never minted by {@link makeInitialized} (see the note there); the slot a real
34
+ * HALO identity DID takes once agents get first-class identities. Optional because nothing
35
+ * populates it yet.
32
36
  */
33
- enabled: Schema.optional(Schema.Boolean).annotations({
34
- title: 'Enabled',
35
- description: 'Master switch for agent automation; propagated to all triggers on sync.',
37
+ did: Schema.optional(IdentityDid).annotations({
38
+ title: 'DID',
39
+ description: "The agent's identity DID; attributes content the agent authors.",
36
40
  }),
37
41
 
38
42
  /**
39
- * Instructions for the agent.
40
- */
41
- instructions: Ref.Ref(Text.Text).pipe(
42
- Format.FormatAnnotation.set(Format.TypeFormat.Markdown),
43
- Schema.annotations({ title: 'Instructions' }),
44
- ),
45
-
46
- /**
47
- * Primary chat for the agent.
43
+ * Master switch for the agent's automation (propagated onto its compiled routine triggers).
48
44
  */
49
- // TODO(dmaretskyi): Multiple chats; RB: branching hierarchy.
50
- chat: Schema.optional(Ref.Ref(Chat.Chat).pipe(FormInputAnnotation.set(false))),
51
-
52
- // TODO(burdon): Currently Memory.Memory objects are global to the space; make them artifacts?
53
- artifacts: Schema.Array(
54
- Schema.Struct({
55
- // TODO(dmaretskyi): Consider gettings names from the artifact itself using Obj.getLabel.
56
- name: Schema.String,
57
- // TODO(burdon): Rename object.
58
- data: Ref.Ref(Obj.Unknown),
59
- }),
60
- ).pipe(FormInputAnnotation.set(false)),
61
-
62
- /**
63
- * References to objects with a canonical queue property.
64
- * Schema must have the QueueAnnotation.
65
- */
66
- // Change to trigger.
67
- // TODO(dmaretskyi): Turn into an array of objects when form-data
68
- subscriptions: Schema.Array(Ref.Ref(Obj.Unknown)).pipe(FormInputAnnotation.set(false)),
69
-
70
- /**
71
- * Cron expression for a timer trigger that invokes the agent worker on a schedule.
72
- * The timer trigger bypasses the qualifier and goes straight to the agent worker.
73
- */
74
- // Change to trigger.
75
- cron: Schema.optional(Schema.String).annotations({
76
- title: 'Cron',
77
- description: 'Cron expression for a timer trigger that invokes the agent on a schedule.',
45
+ enabled: Schema.optional(Schema.Boolean).annotations({
46
+ title: 'Enabled',
47
+ description: 'Master switch for agent automation; propagated to all triggers on sync.',
78
48
  }),
79
49
 
80
50
  /**
81
- * Input feed for subscriptions.
82
- * @deprecated Subscriptions will write directly to the agent.
51
+ * Instructions for the agent — the preset payload (text, skills, objects, commands) a chat
52
+ * receives when the agent is applied to it.
83
53
  */
84
- feed: Schema.optional(Ref.Ref(Feed.Feed).pipe(FormInputAnnotation.set(false))),
85
-
86
- /**
87
- * Allow the agent to filter events.
88
- * Related events will be added to the input queue of the agent.
89
- * It is recommended to enable this.
90
- * @deprecated
91
- */
92
- filterEvents: Schema.optional(Schema.Boolean).annotations({
93
- title: 'Filter events',
94
- description: 'Allow the agent to filter events.',
95
- }),
54
+ instructions: Ref.Ref(Instructions.Instructions).pipe(Schema.annotations({ title: 'Instructions' })),
96
55
  }).pipe(
97
56
  Annotation.LabelAnnotation.set(['name']),
98
57
  Annotation.IconAnnotation.set({ icon: 'ph--drone--regular', hue: 'sky' }),
99
58
  ),
100
59
  ) {}
101
60
 
102
- export type MakeProps = Omit<Obj.MakeProps<typeof Agent>, 'instructions' | 'artifacts' | 'subscriptions' | 'chat'> &
103
- Partial<Pick<Obj.MakeProps<typeof Agent>, 'artifacts' | 'subscriptions'>> & {
104
- instructions: string;
105
- skills?: Ref.Ref<Skill.Skill>[];
106
- contextObjects?: Ref.Ref<Obj.Any>[];
107
- };
61
+ /**
62
+ * Resolves the agent's instructions and their markdown text.
63
+ */
64
+ export const loadInstructions = (
65
+ agent: Agent,
66
+ ): Effect.Effect<{ text: string; instructions: Instructions.Instructions }, EntityNotFoundError, Database.Service> =>
67
+ Effect.gen(function* () {
68
+ const instructions = yield* Database.load(agent.instructions);
69
+ const text = yield* Database.load(instructions.text).pipe(
70
+ Effect.map((doc) => doc.content),
71
+ Effect.catchTag('EntityNotFoundError', () => Effect.succeed('')),
72
+ );
73
+ return { text, instructions };
74
+ });
75
+
76
+ /**
77
+ * Resolves the agent's primary chat (the agent holds no chat ref).
78
+ */
79
+ export const loadChat = (agent: Agent): Effect.Effect<Chat.Chat | undefined, never, Database.Service> =>
80
+ Effect.gen(function* () {
81
+ const chats = yield* Database.query(Query.select(Filter.id(agent.id)).targetOf(Chat.CompanionTo).source()).run;
82
+ const [chat] = chats.filter(Obj.instanceOf(Chat.Chat));
83
+ return chat;
84
+ }).pipe(Effect.orDie);
108
85
 
109
86
  /**
110
- * Creates a fully initialized Agent with chat, queue, and context bindings.
87
+ * Resolves the agent a chat runs as, if any. Plain (agentless) chats yield `undefined`.
88
+ * Companion targets are untyped, so the agent is the one target of that type.
89
+ */
90
+ export const loadForChat = (chat: Chat.Chat): Effect.Effect<Agent | undefined, never, Database.Service> =>
91
+ Effect.gen(function* () {
92
+ const targets = yield* Database.query(Query.select(Filter.id(chat.id)).sourceOf(Chat.CompanionTo).target()).run;
93
+ return targets.find(Obj.instanceOf(Agent));
94
+ }).pipe(Effect.orDie);
95
+
96
+ export type MakeProps = Omit<Obj.MakeProps<typeof Agent>, 'instructions'> & {
97
+ instructions: string;
98
+ skills?: Ref.Ref<Skill.Skill>[];
99
+ contextObjects?: Ref.Ref<Obj.Any>[];
100
+ };
101
+
102
+ /**
103
+ * Creates a fully initialized Agent with its first chat and context bindings.
111
104
  *
112
105
  * @param props - Agent properties including spec, skills, and context objects.
113
106
  * @param skill - The skill to use for the agent context.
@@ -120,21 +113,6 @@ export const makeInitialized = (
120
113
  ): Effect.Effect<Agent, never, Database.Service> =>
121
114
  Effect.gen(function* () {
122
115
  const { skills: propsSkills, contextObjects, ...agentProps } = props;
123
- const agent = yield* Database.add(
124
- Obj.make(Agent, {
125
- ...agentProps,
126
- instructions: Ref.make(Text.make({ content: props.instructions })),
127
- artifacts: props.artifacts ?? [],
128
- subscriptions: props.subscriptions ?? [],
129
- filterEvents: props.filterEvents ?? true,
130
- enabled: props.enabled ?? true,
131
- }),
132
- );
133
- const feed = yield* Database.add(Feed.make());
134
- const runtime = yield* Effect.runtime<Database.Service>();
135
- const contextBinder = new AiContext.Binder({ feed, runtime });
136
- // TODO(dmaretskyi): Skill registry.
137
- const agentSkill = yield* Database.add(Obj.clone(skill, { deep: 'all' }));
138
116
 
139
117
  // Persist any inline (transient) skills so their refs are resolvable from feed bindings later.
140
118
  // Refs created with Ref.make(obj) carry an inline target, but when stored in ECHO and read back
@@ -147,10 +125,35 @@ export const makeInitialized = (
147
125
  ),
148
126
  );
149
127
 
128
+ // The typed Instructions is the agent's preset payload: text plus skill set.
129
+ const instructions = yield* Database.add(
130
+ Instructions.make({ text: props.instructions, skills: persistedPropsSkills }),
131
+ );
132
+ const agent = yield* Database.add(
133
+ Obj.make(Agent, {
134
+ // `did` (if provided) flows through via agentProps. Not auto-minted here: `IdentityDid.random()`
135
+ // uses uncontrolled `randomBytes`, which would make agent creation non-deterministic and break
136
+ // memoized-LLM tests. Minting is deferred to the runtime-identity provision (see agent-identity
137
+ // spec), where it can be deterministic or a real HALO DID.
138
+ ...agentProps,
139
+ instructions: Ref.make(instructions),
140
+ enabled: props.enabled ?? true,
141
+ }),
142
+ );
143
+ Obj.setParent(instructions, agent);
144
+ const feed = yield* Database.add(Feed.make());
145
+ const runtime = yield* Effect.runtime<Database.Service>();
146
+ const contextBinder = yield* EffectEx.acquireReleaseResource(() => new AiContext.Binder({ feed, runtime }));
147
+ // TODO(dmaretskyi): Skill registry.
148
+ const agentSkill = yield* Database.add(Obj.clone(skill, { deep: 'all' }));
149
+
150
150
  const chat = yield* Database.add(
151
151
  Chat.make({
152
152
  [Obj.Parent]: agent,
153
153
  feed: Ref.make(feed),
154
+ // Steered through the chat's own channel: instructions render into the system prompt.
155
+ // Identity/attribution comes from the CompanionTo relation below.
156
+ instructions: Ref.make(instructions),
154
157
  }),
155
158
  );
156
159
  Obj.setParent(feed, chat);
@@ -167,17 +170,11 @@ export const makeInitialized = (
167
170
  }),
168
171
  );
169
172
 
170
- const inputFeed = yield* Database.add(Feed.make());
171
- Obj.update(agent, (agent) => {
172
- agent.chat = Ref.make(chat);
173
- agent.feed = Ref.make(inputFeed);
174
- });
175
-
176
173
  return agent;
177
- });
174
+ }).pipe(Effect.scoped);
178
175
 
179
176
  /**
180
- * Resets the agent chat history by rebuilding the chat context.
177
+ * Resets the agent's chat history by rebuilding the chat context.
181
178
  * Preserves the existing skills and objects from the current chat context.
182
179
  *
183
180
  * @param agent - The agent whose chat history should be reset. Must have an existing chat.
@@ -185,12 +182,12 @@ export const makeInitialized = (
185
182
  */
186
183
  export const resetChatHistory = (agent: Agent): Effect.Effect<void, EntityNotFoundError, Database.Service> =>
187
184
  Effect.gen(function* () {
188
- invariant(agent.chat, 'Agent must have an existing chat to reset.');
185
+ const existingChat = yield* loadChat(agent);
186
+ if (!existingChat) {
187
+ return yield* Effect.dieMessage('Agent must have an existing chat to reset.');
188
+ }
189
189
 
190
- const existingFeed = yield* agent.chat.pipe(Database.load).pipe(
191
- Effect.map((_) => _.feed),
192
- Effect.flatMap(Database.load),
193
- );
190
+ const existingFeed = yield* Database.load(existingChat.feed);
194
191
  const runtime = yield* Effect.runtime<Database.Service>();
195
192
  const existingContextBinder = yield* EffectEx.acquireReleaseResource(
196
193
  () =>
@@ -206,12 +203,13 @@ export const resetChatHistory = (agent: Agent): Effect.Effect<void, EntityNotFou
206
203
  .map((object) => Ref.make(object));
207
204
 
208
205
  const feed = yield* Database.add(Feed.make());
209
- const contextBinder = new AiContext.Binder({ feed, runtime });
206
+ const contextBinder = yield* EffectEx.acquireReleaseResource(() => new AiContext.Binder({ feed, runtime }));
210
207
 
211
208
  const chat = yield* Database.add(
212
209
  Chat.make({
213
210
  [Obj.Parent]: agent,
214
211
  feed: Ref.make(feed),
212
+ instructions: agent.instructions,
215
213
  }),
216
214
  );
217
215
  Obj.setParent(feed, chat);
@@ -221,10 +219,17 @@ export const resetChatHistory = (agent: Agent): Effect.Effect<void, EntityNotFou
221
219
  objects: [...objects, Ref.make(chat)],
222
220
  }),
223
221
  );
224
- Obj.update(agent, (agent) => {
225
- agent.chat = Ref.make(chat);
226
- });
227
222
 
223
+ // Retire the old companion link; the new chat becomes the primary.
224
+ const relations = yield* Database.query(Query.select(Filter.id(agent.id)).targetOf(Chat.CompanionTo)).run.pipe(
225
+ Effect.orDie,
226
+ );
227
+ for (const relation of relations) {
228
+ // Compare by id: the two query paths may resolve distinct proxy instances for the same chat.
229
+ if (Relation.getSource(relation).id === existingChat.id) {
230
+ yield* Database.remove(relation);
231
+ }
232
+ }
228
233
  yield* Database.add(
229
234
  Relation.make(Chat.CompanionTo, {
230
235
  [Relation.Source]: chat,
@@ -246,37 +251,3 @@ export const getFromChatContext: Effect.Effect<
246
251
  const agent = agents[0];
247
252
  return agent;
248
253
  });
249
-
250
- /**
251
- * Adds an object to the agent's artifacts (context), resolving it by id within the agent's space.
252
- *
253
- * Accepts whatever reference a tool returned — a bare entity id (e.g. `01J…`) or a full ECHO URI
254
- * (`echo:/…`, `echo://…`). LLMs frequently strip a returned URI down to the bare id, which is not
255
- * a resolvable URI on its own; resolving by entity id within the space tolerates both forms.
256
- *
257
- * Returns the fully-qualified {@link Ref.Ref} that was stored (also usable for an inline message
258
- * reference block).
259
- */
260
- export const addArtifact = (
261
- agent: Agent,
262
- { name, id }: { name: string; id: string },
263
- ): Effect.Effect<Ref.Ref<Obj.Unknown>, Error, Database.Service> =>
264
- Effect.gen(function* () {
265
- // Untyped, LLM-provided reference: normalize to the entity id, falling back to the raw value
266
- // (a bare id is already an entity id) — a genuine external-data boundary.
267
- const parsed = EID.tryParse(id);
268
- const entityId = ((parsed ? EID.getEntityId(parsed) : undefined) ?? id) as EntityId;
269
-
270
- // Store a FULLY-QUALIFIED ref (`echo://<space>/<id>`), not a local `echo:/<id>` one: the artifact
271
- // is created by a separate tool/process invocation, and a space-less local ref does not resolve
272
- // when the agent is later read from a different db view (e.g. the UI). It is not resolved here —
273
- // it resolves lazily when read, by which point the artifact is persisted.
274
- const { db } = yield* Database.Service;
275
- const ref = db.makeRef<Obj.Unknown>(EID.make({ spaceId: db.spaceId, entityId }));
276
-
277
- Obj.update(agent, (agent) => {
278
- agent.artifacts.push({ name, data: ref });
279
- });
280
- yield* Database.flush();
281
- return ref;
282
- });
@@ -0,0 +1,234 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { describe, expect, it } from '@effect/vitest';
6
+ import * as Effect from 'effect/Effect';
7
+
8
+ import { AssistantTestLayer } from '@dxos/agent-runtime/testing';
9
+ import { Instructions } from '@dxos/compute';
10
+ import { Database, Feed, Filter, Obj, Ref, Relation, Type } from '@dxos/echo';
11
+ import { TestHelpers } from '@dxos/effect/testing';
12
+ import { EntityId } from '@dxos/keys';
13
+ import { FeedProtocol } from '@dxos/protocols';
14
+ import { Text } from '@dxos/schema';
15
+ import { Message, Outline } from '@dxos/types';
16
+
17
+ import { Chat } from '../types';
18
+
19
+ EntityId.dangerouslyDisableRandomness();
20
+
21
+ const TestLayer = AssistantTestLayer({
22
+ types: [
23
+ Chat.Chat,
24
+ Chat.CompanionTo,
25
+ Outline.Outline,
26
+ Feed.Feed,
27
+ Text.Text,
28
+ Instructions.Instructions,
29
+ Message.Message,
30
+ ],
31
+ disableLlmMemoization: true,
32
+ });
33
+
34
+ const makeChat = Effect.gen(function* () {
35
+ const feed = yield* Database.add(Feed.make());
36
+ const chat = yield* Database.add(Chat.make({ name: 'Test', feed: Ref.make(feed) }));
37
+ yield* Database.flush();
38
+ return chat;
39
+ });
40
+
41
+ describe('Chat', () => {
42
+ it.effect(
43
+ 'is a standalone type carrying no agent reference',
44
+ Effect.fnUntraced(
45
+ function* (_) {
46
+ const chat = yield* makeChat;
47
+
48
+ expect(Type.getTypename(Chat.Chat)).toBe('org.dxos.type.assistant.chat');
49
+ expect(Type.getVersion(Chat.Chat)).toBe('0.1.0');
50
+ expect(chat.name).toBe('Test');
51
+
52
+ // Asserted on the schema, not the instance: `in` reports false for any declared-but-unset
53
+ // optional field. The agent a chat runs as is reached through CompanionTo, never a field —
54
+ // that field was the edge that made Agent and Chat mutually dependent.
55
+ expect(Object.keys(Chat.Chat.fields).sort()).toEqual(['feed', 'instructions', 'name', 'outline', 'viewType']);
56
+ },
57
+ Effect.provide(TestLayer),
58
+ TestHelpers.provideTestContext,
59
+ ),
60
+ );
61
+
62
+ it.effect(
63
+ 'ensureOutline attaches an outline lazily and returns the same one thereafter',
64
+ Effect.fnUntraced(
65
+ function* (_) {
66
+ const chat = yield* makeChat;
67
+ expect(chat.outline).toBeUndefined();
68
+
69
+ const outline = yield* Chat.ensureOutline(chat);
70
+ expect(chat.outline?.uri).toBe(Ref.make(outline).uri);
71
+
72
+ // Second call reuses the attached outline rather than replacing it.
73
+ const again = yield* Chat.ensureOutline(chat);
74
+ expect(again.id).toBe(outline.id);
75
+ },
76
+ Effect.provide(TestLayer),
77
+ TestHelpers.provideTestContext,
78
+ ),
79
+ );
80
+
81
+ it.effect(
82
+ 'CompanionTo links a chat to an arbitrary companion object',
83
+ Effect.fnUntraced(
84
+ function* (_) {
85
+ const chat = yield* makeChat;
86
+ const companion = yield* Database.add(Instructions.make({ text: 'Steer.' }));
87
+ const relation = yield* Database.add(
88
+ Relation.make(Chat.CompanionTo, {
89
+ [Relation.Source]: chat,
90
+ [Relation.Target]: companion,
91
+ }),
92
+ );
93
+ yield* Database.flush();
94
+
95
+ expect(Relation.getSource(relation).id).toBe(chat.id);
96
+ expect(Relation.getTarget(relation).id).toBe(companion.id);
97
+ expect(Obj.instanceOf(Chat.Chat, Relation.getSource(relation))).toBe(true);
98
+ },
99
+ Effect.provide(TestLayer),
100
+ TestHelpers.provideTestContext,
101
+ ),
102
+ );
103
+
104
+ //
105
+ // Rewind (soft fork).
106
+ //
107
+
108
+ describe('rewind', () => {
109
+ it.effect(
110
+ 'continuing from an earlier message leaves the turns after it unreachable',
111
+ Effect.fnUntraced(
112
+ function* (_) {
113
+ const chat = yield* makeChat;
114
+ const feed = yield* Database.load(chat.feed);
115
+
116
+ const first = message('first question');
117
+ const answer = message('first answer', 'assistant');
118
+ const abandoned = message('abandoned question');
119
+ const abandonedAnswer = message('abandoned answer', 'assistant');
120
+ yield* Feed.append(feed, [first, answer, abandoned, abandonedAnswer]);
121
+
122
+ // Rewind to `answer`: the retry names it as its lineage parent rather than the feed's tip.
123
+ const retry = message('better question');
124
+ yield* Feed.append(feed, [retry], { parent: answer });
125
+ yield* Database.flush();
126
+
127
+ const history = Feed.history(yield* readFeed(feed));
128
+ expect(history.items.map((item) => item.id)).toEqual([first.id, answer.id, retry.id]);
129
+ expect(history.shallow).toBe(false);
130
+
131
+ // The abandoned turns are still in the log — a rewind hides, it does not delete.
132
+ const all = yield* readFeed(feed);
133
+ expect(all.map((item) => item.id)).toContain(abandoned.id);
134
+ expect(all.map((item) => item.id)).toContain(abandonedAnswer.id);
135
+ },
136
+ Effect.provide(TestLayer),
137
+ TestHelpers.provideTestContext,
138
+ ),
139
+ );
140
+
141
+ it.effect(
142
+ 'rewinding twice makes the most recent branch the live one',
143
+ Effect.fnUntraced(
144
+ function* (_) {
145
+ const chat = yield* makeChat;
146
+ const feed = yield* Database.load(chat.feed);
147
+
148
+ const first = message('first question');
149
+ const answer = message('first answer', 'assistant');
150
+ const second = message('second question');
151
+ yield* Feed.append(feed, [first, answer, second]);
152
+
153
+ const retryA = message('retry A');
154
+ yield* Feed.append(feed, [retryA], { parent: answer });
155
+ const retryB = message('retry B');
156
+ yield* Feed.append(feed, [retryB], { parent: second });
157
+ yield* Database.flush();
158
+
159
+ // Latest-wins: retryB's branch is live, so retryA drops out.
160
+ const history = Feed.history(yield* readFeed(feed));
161
+ expect(history.items.map((item) => item.id)).toEqual([first.id, answer.id, second.id, retryB.id]);
162
+ },
163
+ Effect.provide(TestLayer),
164
+ TestHelpers.provideTestContext,
165
+ ),
166
+ );
167
+
168
+ it.effect(
169
+ 'a pending rewind round-trips on the feed',
170
+ Effect.fnUntraced(
171
+ function* (_) {
172
+ const chat = yield* makeChat;
173
+ const feed = yield* Database.load(chat.feed);
174
+ expect(feed.rewindFrom).toBeUndefined();
175
+
176
+ // On the feed, not the chat: the agent appends the continuation out-of-process and resolves
177
+ // the feed, never the chat, so this is the only place both sides can see it. Stores the first
178
+ // *discarded* message, so rewinding to the very first turn needs no sentinel.
179
+ const messageId = EntityId.random();
180
+ Obj.update(feed, (feed) => {
181
+ feed.rewindFrom = messageId;
182
+ });
183
+ yield* Database.flush();
184
+ expect(feed.rewindFrom).toBe(messageId);
185
+
186
+ Obj.update(feed, (feed) => {
187
+ feed.rewindFrom = undefined;
188
+ });
189
+ yield* Database.flush();
190
+ expect(feed.rewindFrom).toBeUndefined();
191
+ },
192
+ Effect.provide(TestLayer),
193
+ TestHelpers.provideTestContext,
194
+ ),
195
+ );
196
+
197
+ it.effect(
198
+ 'a feed that was never rewound reads back whole',
199
+ Effect.fnUntraced(
200
+ function* (_) {
201
+ const chat = yield* makeChat;
202
+ const feed = yield* Database.load(chat.feed);
203
+
204
+ const messages = [message('one'), message('two', 'assistant'), message('three')];
205
+ yield* Feed.append(feed, messages);
206
+ yield* Database.flush();
207
+
208
+ const history = Feed.history(yield* readFeed(feed));
209
+ expect(history.items.map((item) => item.id)).toEqual(messages.map((item) => item.id));
210
+ expect(history.shallow).toBe(false);
211
+ },
212
+ Effect.provide(TestLayer),
213
+ TestHelpers.provideTestContext,
214
+ ),
215
+ );
216
+ });
217
+ });
218
+
219
+ let clock = 0;
220
+
221
+ const message = (text: string, sender: 'user' | 'assistant' = 'user') =>
222
+ Message.make({ created: new Date(clock++).toISOString(), sender, blocks: [{ _tag: 'text', text }] });
223
+
224
+ /**
225
+ * Reads a feed's messages in append order — `Feed.history` walks lineage positionally, and a query
226
+ * returns an unordered set.
227
+ */
228
+ const readFeed = (feed: Feed.Feed) =>
229
+ Effect.gen(function* () {
230
+ const messages = yield* Feed.query(feed, Filter.type(Message.Message)).run;
231
+ const position = (item: Message.Message) =>
232
+ Number(Obj.getKeys(item, FeedProtocol.KEY_QUEUE_POSITION).at(0)?.id ?? Number.POSITIVE_INFINITY);
233
+ return [...messages].sort((a, b) => position(a) - position(b));
234
+ });