@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
@@ -0,0 +1,124 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as LanguageModel from '@effect/ai/LanguageModel';
6
+ import * as Prompt from '@effect/ai/Prompt';
7
+ import * as Effect from 'effect/Effect';
8
+ import * as Schema from 'effect/Schema';
9
+
10
+ import { AiService } from '@dxos/ai';
11
+ import { Operation } from '@dxos/compute';
12
+ import { getSession } from '@dxos/compute/AgentService';
13
+ import { Database, Obj } from '@dxos/echo';
14
+ import { log } from '@dxos/log';
15
+ import { trim } from '@dxos/util';
16
+
17
+ import { Agent, Chat } from '../../../types';
18
+ import { Relay } from './definitions';
19
+
20
+ /**
21
+ * The relay pattern (plugin-projects PLAN.md phase C): one trigger per subscribed feed runs this
22
+ * relay, which qualifies the event with a cheap model and, when relevant, forwards it onto the
23
+ * chat's durable session (the process input queue) — multiplexing and filtering in one construct,
24
+ * with no intermediate staging feed.
25
+ */
26
+ const handler: Operation.WithHandler<typeof Relay> = Relay.pipe(
27
+ Operation.withHandler(
28
+ Effect.fnUntraced(
29
+ function* ({ chat: chatRef, event, prompt, qualify }) {
30
+ if (!event && !prompt) {
31
+ return yield* Effect.die(new Error('Relay requires an event or a prompt.'));
32
+ }
33
+ const chat = yield* Database.load(chatRef).pipe(
34
+ Effect.catchTag('EntityNotFoundError', () => Effect.die(new Error('Unable to load relay chat.'))),
35
+ );
36
+
37
+ if (event && (qualify ?? true)) {
38
+ // Fail open (matching the prompt's "if unsure, return true"): a malformed model reply
39
+ // forwards the event rather than silently dropping it.
40
+ const relevant = yield* qualifyEvent(chat, event).pipe(
41
+ Effect.retry({ times: 1 }),
42
+ Effect.catchAll((error) =>
43
+ Effect.sync(() => {
44
+ log.warn('relay qualification failed; forwarding event', { error });
45
+ return true;
46
+ }),
47
+ ),
48
+ );
49
+ if (!relevant) {
50
+ return;
51
+ }
52
+ }
53
+
54
+ const feed = yield* Database.load(chat.feed).pipe(
55
+ Effect.catchTag('EntityNotFoundError', () => Effect.die(new Error('Unable to load relay chat feed.'))),
56
+ );
57
+ // The durable session recovers steering from its spawn annotation; passing the ref here
58
+ // keeps the reuse identity honest (a repointed ref respawns the process).
59
+ const session = yield* getSession(feed, { instructions: chat.instructions });
60
+ const content = prompt ?? JSON.stringify(event);
61
+ yield* session.submitPrompt([{ _tag: 'text', text: content, disposition: 'synthetic' }]);
62
+ },
63
+ Effect.provide(AiService.model('com.anthropic.model.claude-sonnet-4-6.default')),
64
+ ),
65
+ ),
66
+ Operation.opaqueHandler,
67
+ );
68
+
69
+ /** Cheap-model relevance check, ported from the retired Qualifier's prompt (chat-centric per phase B). */
70
+ const qualifyEvent = (chat: Chat.Chat, event: unknown) =>
71
+ Effect.gen(function* () {
72
+ const agent = yield* Agent.loadForChat(chat);
73
+ const instructions = chat.instructions
74
+ ? yield* Database.load(chat.instructions).pipe(Effect.orElseSucceed(() => undefined))
75
+ : undefined;
76
+ const instructionsText = instructions
77
+ ? yield* Database.load(instructions.text).pipe(
78
+ Effect.map((doc) => doc.content),
79
+ Effect.catchTag('EntityNotFoundError', () => Effect.succeed('')),
80
+ )
81
+ : '';
82
+ const checklistText = yield* Chat.formatChecklist(chat);
83
+
84
+ const { value } = yield* Effect.scoped(
85
+ LanguageModel.generateObject({
86
+ schema: Schema.Struct({
87
+ isRelevant: Schema.Boolean,
88
+ }),
89
+ prompt: Prompt.fromMessages([
90
+ Prompt.systemMessage({
91
+ content: trim`
92
+ You are a qualifying agent that determines if the event is relevant to the agent.
93
+ Respond with true if the event is relevant to the agent, false otherwise.
94
+ If you are not sure, return true.
95
+ The qualified events will be forwarded to the larger agent that will process them.
96
+ <agent id="${agent ? Obj.getURI(agent) : 'unknown'}" name="${agent?.name ?? ''}">
97
+ <instructions>
98
+ ${instructionsText}
99
+ </instructions>
100
+ <checklist>
101
+ ${checklistText}
102
+ </checklist>
103
+ </agent>
104
+ `,
105
+ }),
106
+ Prompt.userMessage({
107
+ content: [
108
+ Prompt.makePart('text', {
109
+ text: trim`
110
+ <event>
111
+ ${JSON.stringify(event, null, 2)}
112
+ </event>
113
+ `,
114
+ }),
115
+ ],
116
+ }),
117
+ ]),
118
+ }),
119
+ );
120
+
121
+ return value.isRelevant;
122
+ });
123
+
124
+ export default handler;
@@ -5,8 +5,6 @@
5
5
  import { Skill, Template } from '@dxos/compute';
6
6
  import { trim } from '@dxos/util';
7
7
 
8
- import { AddArtifact } from './operations/definitions';
9
-
10
8
  const SKILL_KEY = 'org.dxos.skill.agent';
11
9
 
12
10
  /**
@@ -21,10 +19,9 @@ const make = () =>
21
19
  source: trim`
22
20
  You work on an agent. Each agent has instructions - the goal of the agent.
23
21
  The agent plan shows the current progress of the agent.
24
- Agent has a number of associated artifacts you can read/write.
25
- You can edit them if necessary.
26
-
27
- IMPORTANT: When creating a new artifact, always add it to the agent using the add-artifact function.
22
+ Durable work products belong to the agent's project: when you create an object the agent
23
+ should keep, file it into the project's artifacts (the add-artifact tool of the Project
24
+ skill) rather than leaving it loose in the space.
28
25
 
29
26
  {{#with agent}}
30
27
  <agent id="{{id}}" name="{{name}}">
@@ -34,14 +31,6 @@ const make = () =>
34
31
  <plan>
35
32
  {{plan}}
36
33
  </plan>
37
-
38
- <artifacts>
39
- {{#each artifacts}}
40
- <artifact type="{{type}}" dxn="{{dxn}}">
41
- {{name}}
42
- </artifact>
43
- {{/each}}
44
- </artifacts>
45
34
  </agent>
46
35
  {{/with}}
47
36
  `,
@@ -53,7 +42,6 @@ const make = () =>
53
42
  },
54
43
  ],
55
44
  }),
56
- tools: Skill.toolDefinitions({ operations: [AddArtifact] }),
57
45
  });
58
46
 
59
47
  const skill: Skill.Definition = {
@@ -9,7 +9,7 @@ import { Obj, Ref } from '@dxos/echo';
9
9
 
10
10
  import { Agent } from '../../../types';
11
11
  import { AgentSkill } from '../../agent';
12
- import { CreateAgent, SyncTriggers } from './definitions';
12
+ import { CreateAgent, SyncAutomation } from './definitions';
13
13
 
14
14
  export default CreateAgent.pipe(
15
15
  Operation.withHandler(
@@ -19,11 +19,11 @@ export default CreateAgent.pipe(
19
19
  name,
20
20
  instructions,
21
21
  skills: yield* Effect.forEach(skills, (key) => Skill.upsert(key).pipe(Effect.map(Ref.make), Effect.orDie)),
22
- subscriptions,
23
22
  },
24
23
  Obj.clone(AgentSkill.make()),
25
24
  );
26
- yield* Operation.invoke(SyncTriggers, { agent: Ref.make(agent) });
25
+ // Subscriptions compile straight to Routines (the agent stores no automation fields).
26
+ yield* Operation.invoke(SyncAutomation, { agent: Ref.make(agent), subscriptions });
27
27
  return agent;
28
28
  }),
29
29
  ),
@@ -48,18 +48,33 @@ export const CreateAgent = Operation.make({
48
48
  services: [Registry.Service, Database.Service],
49
49
  });
50
50
 
51
- export const SyncTriggers = Operation.make({
51
+ export const SyncAutomation = Operation.make({
52
52
  meta: {
53
53
  key: DXN.make('org.dxos.function.agent.syncTriggers'),
54
- name: 'Sync triggers',
54
+ name: 'Sync automation',
55
55
  description:
56
- 'Synchronizes triggers with the agent: subscriptions, cron, filter-events, and enabled (copied to every trigger). Call after editing those fields.',
56
+ 'Compiles the agent automation config (subscriptions, optional cron) into Routines that relay events onto the agent session. Recreates everything, so call with the FULL desired config after any change; enabled is copied from the agent onto every trigger.',
57
57
  icon: 'ph--arrows-clockwise--regular',
58
58
  },
59
59
  input: Schema.Struct({
60
60
  agent: Ref.Ref(Agent.Agent).annotations({
61
- description: 'The agent whose triggers should be synced.',
61
+ description: 'The agent whose automation should be synced.',
62
62
  }),
63
+ subscriptions: Schema.optional(
64
+ Schema.Array(Ref.Ref(Obj.Unknown)).annotations({
65
+ description: 'The objects to subscribe to (e.g. mailboxes); each compiles to a feed-triggered routine.',
66
+ }),
67
+ ),
68
+ cron: Schema.optional(
69
+ Schema.String.annotations({
70
+ description: 'Cron expression for a scheduled wake routine.',
71
+ }),
72
+ ),
73
+ qualify: Schema.optional(
74
+ Schema.Boolean.annotations({
75
+ description: 'Run the cheap-model relevance filter on subscription events (default true).',
76
+ }),
77
+ ),
63
78
  }),
64
79
  output: Schema.Void,
65
80
  services: [Database.Service],
@@ -9,5 +9,5 @@ export * as AgentWizardOperations from './definitions';
9
9
  export const AgentWizardHandlers = OperationHandlerSet.lazy(
10
10
  () => import('./create-agent'),
11
11
  () => import('./agent-rules'),
12
- () => import('./sync-triggers'),
12
+ () => import('./sync-automation'),
13
13
  );
@@ -0,0 +1,103 @@
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 { Operation, Routine, Trigger } from '@dxos/compute';
9
+ import { Database, Filter, Obj, Query, Ref } from '@dxos/echo';
10
+ import { TestHelpers } from '@dxos/effect/testing';
11
+ import { invariant } from '@dxos/invariant';
12
+ import { EntityId } from '@dxos/keys';
13
+
14
+ import { OperationTestLayer } from '../../../testing';
15
+ import { Agent } from '../../../types';
16
+ import { Relay } from '../../agent/operations/definitions';
17
+ import AgentSkillDef from '../../agent/skill';
18
+ import { AgentWizardOperations } from '../index';
19
+
20
+ EntityId.dangerouslyDisableRandomness();
21
+
22
+ describe('SyncAutomation', () => {
23
+ const skill = AgentSkillDef.make();
24
+
25
+ it.effect(
26
+ 'cron creates a timer routine that relays into the agent session',
27
+ Effect.fnUntraced(
28
+ function* (_) {
29
+ const cron = '*/5 * * * *';
30
+ const agent = yield* Agent.makeInitialized(
31
+ { name: 'Scheduled agent', instructions: 'A scheduled agent that runs on a timer.' },
32
+ skill,
33
+ );
34
+ yield* Database.flush();
35
+
36
+ yield* Operation.invoke(AgentWizardOperations.SyncAutomation, { agent: Ref.make(agent), cron });
37
+
38
+ const triggers = yield* Database.query(
39
+ Query.select(Filter.type(Trigger.Trigger)).debugLabel('assistant-toolkit.sync-automation.timer'),
40
+ ).run;
41
+ const timerTriggers = triggers.filter(
42
+ (trigger) => trigger.spec?.kind === 'timer' && trigger.spec.cron === cron,
43
+ );
44
+ expect(timerTriggers).toHaveLength(1);
45
+
46
+ const timerTrigger = timerTriggers[0];
47
+ expect(timerTrigger.enabled).toBe(true);
48
+
49
+ // The timer routine relays a synthetic wake prompt into the agent's durable session.
50
+ invariant(timerTrigger.runnable);
51
+ const operation = yield* Database.load(timerTrigger.runnable);
52
+ invariant(Obj.instanceOf(Operation.PersistentOperation, operation));
53
+ expect(Obj.getMeta(operation).key).toBe(Relay.meta.key);
54
+
55
+ // The trigger is wrapped in a user-facing Routine aggregate.
56
+ const routines = yield* Database.query(
57
+ Query.select(Filter.type(Routine.Routine)).debugLabel('assistant-toolkit.sync-automation.timer-routine'),
58
+ ).run;
59
+ expect(routines).toHaveLength(1);
60
+ expect(routines[0].triggers.map((ref) => ref.uri)).toContain(Ref.make(timerTrigger).uri);
61
+ },
62
+ Effect.provide(OperationTestLayer),
63
+ TestHelpers.provideTestContext,
64
+ ),
65
+ );
66
+
67
+ it.effect(
68
+ 'copies enabled from the agent onto every trigger',
69
+ Effect.fnUntraced(
70
+ function* (_) {
71
+ const cron = '0 9 * * *';
72
+ const agent = yield* Agent.makeInitialized(
73
+ { name: 'Toggle agent', instructions: 'Test enabled propagation.', enabled: false },
74
+ skill,
75
+ );
76
+ yield* Database.flush();
77
+
78
+ yield* Operation.invoke(AgentWizardOperations.SyncAutomation, { agent: Ref.make(agent), cron });
79
+
80
+ const triggers = yield* Database.query(
81
+ Query.select(Filter.type(Trigger.Trigger)).debugLabel('assistant-toolkit.sync-automation.toggle'),
82
+ ).run;
83
+ // `every` is vacuously true on an empty array; assert the triggers exist first.
84
+ expect(triggers.length).toBeGreaterThan(0);
85
+ expect(triggers.every((trigger) => trigger.enabled === false)).toBe(true);
86
+
87
+ Obj.update(agent, (agent) => {
88
+ agent.enabled = true;
89
+ });
90
+ yield* Database.flush();
91
+ yield* Operation.invoke(AgentWizardOperations.SyncAutomation, { agent: Ref.make(agent), cron });
92
+
93
+ const triggersAfter = yield* Database.query(
94
+ Query.select(Filter.type(Trigger.Trigger)).debugLabel('assistant-toolkit.sync-automation.after'),
95
+ ).run;
96
+ expect(triggersAfter).toHaveLength(triggers.length);
97
+ expect(triggersAfter.every((trigger) => trigger.enabled === true)).toBe(true);
98
+ },
99
+ Effect.provide(OperationTestLayer),
100
+ TestHelpers.provideTestContext,
101
+ ),
102
+ );
103
+ });
@@ -0,0 +1,205 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Option from 'effect/Option';
7
+
8
+ import { Operation, Routine, Trigger } from '@dxos/compute';
9
+ import { Database, Feed, Filter, Obj, Ref, Type } from '@dxos/echo';
10
+ import { FeedAnnotation } from '@dxos/schema';
11
+
12
+ import { Agent } from '../../../types';
13
+ import { SyncAutomation } from './definitions';
14
+
15
+ export default SyncAutomation.pipe(
16
+ Operation.withHandler(
17
+ Effect.fn(function* ({ agent: agentRef, subscriptions, cron, qualify }) {
18
+ const agent = yield* Database.load(agentRef);
19
+ yield* syncAgentAutomation(agent, { subscriptions, cron, qualify: qualify ?? true });
20
+ }),
21
+ ),
22
+ );
23
+
24
+ /**
25
+ * Foreign key {@link AGENT_TRIGGER_EXTENSION_KEY} => <agent id : EntityId>.
26
+ */
27
+ const AGENT_TRIGGER_EXTENSION_KEY = 'org.dxos.extension.AgentTrigger';
28
+
29
+ /**
30
+ * Foreign key {@link AGENT_TRIGGER_TARGET_EXTENSION_KEY} => <dxn string of subscription target>.
31
+ */
32
+ const AGENT_TRIGGER_TARGET_EXTENSION_KEY = 'org.dxos.extension.AgentTriggerTarget';
33
+
34
+ /** Reads a feed-annotated object's `feed` ref without assuming its schema shape. */
35
+ const getFeedRef = (obj: Obj.Unknown): Ref.Ref<Obj.Unknown> | undefined => {
36
+ if (!('feed' in obj)) {
37
+ return undefined;
38
+ }
39
+ const candidate = obj.feed;
40
+ // The target is type-checked after loading (`Obj.instanceOf(Feed.Feed, …)`), so the ref stays untyped here.
41
+ return Ref.isRef(candidate) ? candidate : undefined;
42
+ };
43
+
44
+ /** Checks if an object's schema has the FeedAnnotation. */
45
+ const hasFeedAnnotation = (obj: Obj.Unknown): boolean => {
46
+ const type = Obj.getType(obj);
47
+ if (!type) {
48
+ return false;
49
+ }
50
+ const annotation = FeedAnnotation.get(Type.getSchema(type));
51
+ return Option.isSome(annotation) && annotation.value === true;
52
+ };
53
+
54
+ export type AutomationConfig = {
55
+ /** Omitted (vs empty) leaves existing subscription routines untouched. */
56
+ subscriptions?: readonly Ref.Ref<Obj.Unknown>[];
57
+ /** Omitted leaves an existing schedule routine untouched; empty string removes it. */
58
+ cron?: string;
59
+ /** Run the cheap-model relevance check before forwarding subscription events. */
60
+ qualify: boolean;
61
+ };
62
+
63
+ /** A schedule routine's target key is `timer:<cron>`; subscription keys are the target's URI. */
64
+ const isTimerKey = (id: string | undefined): boolean => id?.startsWith('timer:') ?? false;
65
+
66
+ const targetKeyOf = (entity: Obj.Unknown): string | undefined =>
67
+ Obj.getMeta(entity).keys.find((key) => key.source === AGENT_TRIGGER_TARGET_EXTENSION_KEY)?.id;
68
+
69
+ /**
70
+ * Compiles the agent's automation config into Routines whose triggers run the Relay: the relay
71
+ * qualifies each event with a cheap model and forwards relevant ones onto the chat's durable
72
+ * session. Re-running deletes and recreates the categories present in the config.
73
+ */
74
+ export const syncAgentAutomation = (
75
+ agent: Agent.Agent,
76
+ config: AutomationConfig,
77
+ ): Effect.Effect<void, never, Database.Service> =>
78
+ Effect.gen(function* () {
79
+ // Resolve the chat before the destructive phase: a transient resolution gap must not wipe
80
+ // existing automation without recreating it.
81
+ const chat = yield* Agent.loadChat(agent);
82
+ if (!chat) {
83
+ return;
84
+ }
85
+ const chatRef = Ref.make(chat);
86
+
87
+ const triggers = yield* Database.query(
88
+ Filter.foreignKeys(Trigger.Trigger, [{ source: AGENT_TRIGGER_EXTENSION_KEY, id: agent.id }]),
89
+ ).run;
90
+ const routines = yield* Database.query(
91
+ Filter.foreignKeys(Routine.Routine, [{ source: AGENT_TRIGGER_EXTENSION_KEY, id: agent.id }]),
92
+ ).run;
93
+
94
+ // Reconcile per category: only the categories present in the config are recreated, so a
95
+ // subscriptions-only update (e.g. a UI toggle) cannot silently drop the schedule routine.
96
+ // Recreation keeps operation, concurrency, and enabled in sync when the config changes.
97
+ const shouldRemove = (entity: Obj.Unknown): boolean => {
98
+ const timer = isTimerKey(targetKeyOf(entity));
99
+ return timer ? config.cron !== undefined : config.subscriptions !== undefined;
100
+ };
101
+ for (const trigger of triggers.filter(shouldRemove)) {
102
+ yield* Database.remove(trigger);
103
+ }
104
+ for (const routine of routines.filter(shouldRemove)) {
105
+ yield* Database.remove(routine);
106
+ }
107
+
108
+ const triggersEnabled = agent.enabled ?? true;
109
+
110
+ // Lazy import to avoid circular dependency issues.
111
+ const { Relay } = yield* Effect.promise(() => import('../../agent/operations/definitions'));
112
+
113
+ const makeRoutine = (options: {
114
+ name: string;
115
+ targetKey: string;
116
+ spec: Trigger.Trigger['spec'];
117
+ input: Record<string, unknown>;
118
+ concurrency?: number;
119
+ }): Effect.Effect<void, never, Database.Service> =>
120
+ Effect.gen(function* () {
121
+ const keys = [
122
+ { source: AGENT_TRIGGER_EXTENSION_KEY, id: agent.id },
123
+ { source: AGENT_TRIGGER_TARGET_EXTENSION_KEY, id: options.targetKey },
124
+ ];
125
+ const runnable = yield* Database.add(Operation.serialize(Relay));
126
+ const trigger = yield* Database.add(
127
+ Trigger.make({
128
+ [Obj.Parent]: agent,
129
+ [Obj.Meta]: { keys },
130
+ enabled: triggersEnabled,
131
+ spec: options.spec,
132
+ runnable: Ref.make(runnable),
133
+ input: options.input,
134
+ ...(options.concurrency !== undefined ? { concurrency: options.concurrency } : {}),
135
+ }),
136
+ );
137
+ // The Routine is the user-facing aggregate (action + trigger), shared with projects.
138
+ yield* Database.add(
139
+ Obj.make(Routine.Routine, {
140
+ [Obj.Parent]: agent,
141
+ [Obj.Meta]: { keys },
142
+ name: options.name,
143
+ spec: { kind: 'runnable', runnable: Ref.make(runnable) },
144
+ triggers: [Ref.make(trigger)],
145
+ }),
146
+ );
147
+ });
148
+
149
+ for (const subscription of config.subscriptions ?? []) {
150
+ const targetOption = yield* Database.load(subscription).pipe(
151
+ Effect.map(Option.some),
152
+ Effect.catchTag('EntityNotFoundError', () => Effect.succeed(Option.none())),
153
+ );
154
+ if (Option.isNone(targetOption)) {
155
+ continue;
156
+ }
157
+ const target = targetOption.value;
158
+
159
+ let feedObj: Feed.Feed | undefined;
160
+ if (Obj.instanceOf(Feed.Feed, target)) {
161
+ feedObj = target;
162
+ } else if (hasFeedAnnotation(target)) {
163
+ const feedRef = getFeedRef(target);
164
+ feedObj = feedRef
165
+ ? Option.getOrUndefined(
166
+ yield* Database.load(feedRef).pipe(
167
+ Effect.map(Option.some),
168
+ Effect.catchTag('EntityNotFoundError', () => Effect.succeed(Option.none())),
169
+ ),
170
+ )
171
+ : undefined;
172
+ }
173
+
174
+ if (!feedObj || !Obj.instanceOf(Feed.Feed, feedObj) || !Feed.getFeedUri(feedObj)) {
175
+ continue;
176
+ }
177
+
178
+ yield* makeRoutine({
179
+ name: `${agent.name ?? 'Agent'} — ${Obj.getLabel(target) ?? 'subscription'}`,
180
+ targetKey: subscription.uri,
181
+ spec: Trigger.specFeed(feedObj),
182
+ input: {
183
+ chat: chatRef,
184
+ event: '{{event}}',
185
+ ...(config.qualify ? {} : { qualify: false }),
186
+ },
187
+ concurrency: config.qualify ? 5 : undefined,
188
+ });
189
+ }
190
+
191
+ // Timer wake: a synthetic prompt through the same relay path (no event, so no qualification).
192
+ if (config.cron) {
193
+ yield* makeRoutine({
194
+ name: `${agent.name ?? 'Agent'} — schedule`,
195
+ targetKey: `timer:${config.cron}`,
196
+ spec: Trigger.specTimer(config.cron),
197
+ input: {
198
+ chat: chatRef,
199
+ prompt: 'Scheduled wake: continue your instructions and review outstanding work.',
200
+ },
201
+ });
202
+ }
203
+
204
+ yield* Database.flush();
205
+ });
@@ -5,7 +5,7 @@
5
5
  import { Skill, Template } from '@dxos/compute';
6
6
  import { trim } from '@dxos/util';
7
7
 
8
- import { AgentRules, CreateAgent, SyncTriggers } from './operations/definitions';
8
+ import { AgentRules, CreateAgent, SyncAutomation } from './operations/definitions';
9
9
 
10
10
  const SKILL_KEY = 'org.dxos.skill.agentWizard';
11
11
 
@@ -17,7 +17,7 @@ const make = () =>
17
17
  Skill.make({
18
18
  key: SKILL_KEY,
19
19
  name: 'Agent Wizard',
20
- description: 'Help the user create a new agent (subscriptions, optional cron timer, sync-triggers after edits).',
20
+ description: 'Help the user create a new agent (subscriptions and optional cron compile to routines).',
21
21
  agentCanEnable: true,
22
22
  instructions: Template.make({
23
23
  source: trim`
@@ -26,22 +26,21 @@ const make = () =>
26
26
  Agents are goal oriented and autonomously driven.
27
27
  Each agent has instructions - the goal of the agent.
28
28
  The instructions also typically describe what actions to perform in reaction to events (emails).
29
- The agent has a number of associated artifacts to work with.
30
- Agents can subscribe to emails.
29
+ Agents can subscribe to emails, and durable work products belong to a project's artifacts.
31
30
 
32
- Agents have a \`cron\` field: when set, the agent runs on a timer on that schedule (standard cron syntax).
33
- Use \`cron\` when the user wants the agent to run periodically (e.g. "every morning", "once a day", "every 5 minutes").
34
- Examples: \`0 9 * * *\` for daily at 09:00, or \`*/5 * * * *\` for every 5 minutes.
35
- Timer triggers bypass the qualifier and invoke the agent worker directly on the schedule.
31
+ Automation (subscriptions and an optional cron schedule) is compiled into routines, not stored
32
+ on the agent: pass subscriptions when creating the agent, and use the sync-automation tool with
33
+ the FULL desired config to change automation later (a cron expression schedules periodic wakes,
34
+ e.g. \`0 9 * * *\` for daily at 09:00; \`enabled\` on the agent is applied to every trigger).
36
35
 
37
36
  The agent itself is an ECHO object and can be edited like any other object using the database skill.
38
37
  You can edit the agent's instructions, name, and other properties directly.
39
- If you edit the agent's \`enabled\` field, \`filterEvents\` field, subscriptions array, or \`cron\` field, you MUST call the sync-triggers function afterward to synchronize the triggers (\`enabled\` is applied to all triggers).
38
+ If you edit the agent's \`enabled\` field, you MUST call sync-automation afterward so triggers pick it up.
40
39
 
41
40
  IMPORTANT: Before attempting to create an agent call the [agent-rules] tool to get the rules for creating an agent.
42
41
  `,
43
42
  }),
44
- tools: Skill.toolDefinitions({ operations: [AgentRules, CreateAgent, SyncTriggers] }),
43
+ tools: Skill.toolDefinitions({ operations: [AgentRules, CreateAgent, SyncAutomation] }),
45
44
  });
46
45
 
47
46
  const skill: Skill.Definition = {
@@ -6,11 +6,11 @@ import { describe, it } from '@effect/vitest';
6
6
  import * as Effect from 'effect/Effect';
7
7
  import * as Either from 'effect/Either';
8
8
 
9
+ import { AgentService } from '@dxos/agent-runtime';
10
+ import { AssistantTestLayer } from '@dxos/agent-runtime/testing';
9
11
  import { Operation, Skill } from '@dxos/compute';
10
12
  import { Feed, Obj } from '@dxos/echo';
11
13
  import { TestHelpers } from '@dxos/effect/testing';
12
- import { AgentService } from '@dxos/functions-runtime';
13
- import { AssistantTestLayer } from '@dxos/functions-runtime/testing';
14
14
  import { EntityId } from '@dxos/keys';
15
15
  import { Organization } from '@dxos/types';
16
16
 
@@ -5,19 +5,19 @@
5
5
  import { describe, it } from '@effect/vitest';
6
6
  import * as Effect from 'effect/Effect';
7
7
 
8
+ import { AgentService } from '@dxos/agent-runtime';
9
+ import { AssistantTestLayerWithTriggers } from '@dxos/agent-runtime/testing';
8
10
  import { MemoizedAiService } from '@dxos/ai/testing';
11
+ import { WithProperties } from '@dxos/app-toolkit/testing';
9
12
  import { SpaceProperties } from '@dxos/client-protocol';
10
13
  import { OperationHandlerSet, Skill } from '@dxos/compute';
11
14
  import { Collection, Database, Feed, Query } from '@dxos/echo';
12
15
  import { TestHelpers } from '@dxos/effect/testing';
13
- import { AgentService } from '@dxos/functions-runtime';
14
- import { AssistantTestLayerWithTriggers } from '@dxos/functions-runtime/testing';
15
16
  import { EntityId } from '@dxos/keys';
16
17
  import { log } from '@dxos/log';
17
18
  import { MarkdownSkill } from '@dxos/plugin-markdown';
18
19
  import { Markdown } from '@dxos/plugin-markdown';
19
20
  import { MarkdownOperationHandlerSet } from '@dxos/plugin-markdown/plugin';
20
- import { WithProperties } from '@dxos/plugin-markdown/testing';
21
21
  import { Person } from '@dxos/types';
22
22
 
23
23
  import { DatabaseHandlers, DatabaseSkill } from '../database';
@@ -34,7 +34,7 @@ const TestLayer = AssistantTestLayerWithTriggers({
34
34
  });
35
35
 
36
36
  // NOTE: Not run by default since it acceses internet.
37
- describe('Browser', { tags: ['llm'] }, () => {
37
+ describe('Browser', { tags: ['manual'] }, () => {
38
38
  it.effect(
39
39
  'scrape effect blog',
40
40
  Effect.fnUntraced(