@fastagent-sh/fastagent 0.24.4 → 0.25.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 (480) hide show
  1. package/README.md +53 -82
  2. package/dist/agent-api.d.ts +452 -0
  3. package/dist/agent-api.js +201 -0
  4. package/dist/answer-text.d.ts +8 -0
  5. package/dist/answer-text.js +18 -0
  6. package/dist/atomic-write.d.ts +2 -2
  7. package/dist/atomic-write.js +2 -2
  8. package/dist/authoring.d.ts +77 -0
  9. package/dist/authoring.js +238 -0
  10. package/dist/channel.d.ts +29 -15
  11. package/dist/channel.js +4 -1
  12. package/dist/channels/agentcore-protocol.d.ts +36 -50
  13. package/dist/channels/agentcore-protocol.js +3 -3
  14. package/dist/channels/agentcore-service.d.ts +8 -18
  15. package/dist/channels/agentcore-service.js +108 -127
  16. package/dist/channels/agentcore.d.ts +8 -24
  17. package/dist/channels/agentcore.js +32 -65
  18. package/dist/channels/body.d.ts +0 -16
  19. package/dist/channels/body.js +0 -25
  20. package/dist/channels/busy.js +6 -1
  21. package/dist/channels/context.d.ts +4 -0
  22. package/dist/channels/context.js +35 -0
  23. package/dist/channels/discover.d.ts +18 -20
  24. package/dist/channels/discover.js +41 -99
  25. package/dist/channels/feishu/feishu-api.d.ts +54 -4
  26. package/dist/channels/feishu/feishu-api.js +192 -149
  27. package/dist/channels/feishu/feishu.d.ts +3 -0
  28. package/dist/channels/feishu/feishu.js +117 -106
  29. package/dist/channels/feishu/history.d.ts +55 -0
  30. package/dist/channels/feishu/history.js +199 -0
  31. package/dist/channels/feishu/invoke-turn.d.ts +13 -11
  32. package/dist/channels/feishu/invoke-turn.js +9 -10
  33. package/dist/channels/feishu/model.d.ts +2 -1
  34. package/dist/channels/feishu/normalize.js +100 -0
  35. package/dist/channels/feishu/preview.d.ts +2 -2
  36. package/dist/channels/feishu/register-webhook.d.ts +1 -0
  37. package/dist/channels/feishu/register-webhook.js +3 -2
  38. package/dist/channels/feishu/scaffold/channel.ts +65 -46
  39. package/dist/channels/feishu/scaffold/feishu-send.ts +38 -33
  40. package/dist/channels/feishu/scaffold/feishu-threads.ts +25 -0
  41. package/dist/channels/feishu/setup-mode.d.ts +45 -25
  42. package/dist/channels/feishu/setup-mode.js +74 -23
  43. package/dist/channels/feishu/shared-api.d.ts +24 -6
  44. package/dist/channels/feishu/shared-api.js +30 -24
  45. package/dist/channels/kit/context-buffer.d.ts +11 -2
  46. package/dist/channels/kit/context-buffer.js +7 -4
  47. package/dist/channels/kit/delivery.d.ts +19 -3
  48. package/dist/channels/kit/delivery.js +74 -15
  49. package/dist/channels/kit/event-stream.js +2 -1
  50. package/dist/channels/kit/invoke-turn-kit.d.ts +41 -41
  51. package/dist/channels/kit/invoke-turn-kit.js +62 -71
  52. package/dist/channels/kit/place-history.d.ts +107 -0
  53. package/dist/channels/kit/place-history.js +182 -0
  54. package/dist/channels/kit/preview-kit.d.ts +9 -5
  55. package/dist/channels/kit/preview-kit.js +36 -15
  56. package/dist/channels/kit/room-threads.d.ts +46 -0
  57. package/dist/channels/kit/room-threads.js +81 -0
  58. package/dist/channels/kit/seen.js +1 -1
  59. package/dist/channels/kit/stop-command.d.ts +6 -3
  60. package/dist/channels/kit/stop-command.js +20 -18
  61. package/dist/channels/kit/thread-fork.d.ts +17 -0
  62. package/dist/channels/kit/thread-fork.js +43 -0
  63. package/dist/channels/kit/thread-participants.js +1 -1
  64. package/dist/channels/kit/transport.d.ts +5 -0
  65. package/dist/channels/kit/transport.js +5 -0
  66. package/dist/channels/kit/turn-runner.d.ts +10 -9
  67. package/dist/channels/kit/turn-runner.js +17 -19
  68. package/dist/channels/kit/turn-store.d.ts +5 -4
  69. package/dist/channels/kit/turn-store.js +5 -5
  70. package/dist/channels/lark/lark.d.ts +3 -0
  71. package/dist/channels/lark/lark.js +5 -0
  72. package/dist/channels/lark/onboard.d.ts +5 -3
  73. package/dist/channels/lark/onboard.js +14 -14
  74. package/dist/channels/lark/scaffold/channel.ts +67 -44
  75. package/dist/channels/lark/scaffold/lark-send.ts +38 -33
  76. package/dist/channels/lark/scaffold/lark-threads.ts +25 -0
  77. package/dist/channels/respond.d.ts +0 -4
  78. package/dist/channels/respond.js +1 -1
  79. package/dist/channels/router.d.ts +18 -0
  80. package/dist/channels/router.js +68 -0
  81. package/dist/channels/serve.d.ts +5 -70
  82. package/dist/channels/serve.js +105 -287
  83. package/dist/channels/slack/history.d.ts +42 -0
  84. package/dist/channels/slack/history.js +282 -0
  85. package/dist/channels/slack/invoke-turn.d.ts +12 -5
  86. package/dist/channels/slack/invoke-turn.js +7 -5
  87. package/dist/channels/slack/manifest.d.ts +1 -4
  88. package/dist/channels/slack/manifest.js +22 -10
  89. package/dist/channels/slack/model.d.ts +2 -1
  90. package/dist/channels/slack/onboard.d.ts +0 -2
  91. package/dist/channels/slack/onboard.js +2 -4
  92. package/dist/channels/slack/onboarding-state.d.ts +0 -2
  93. package/dist/channels/slack/onboarding-state.js +0 -1
  94. package/dist/channels/slack/parse.d.ts +0 -5
  95. package/dist/channels/slack/parse.js +1 -16
  96. package/dist/channels/slack/preview.d.ts +2 -3
  97. package/dist/channels/slack/preview.js +78 -52
  98. package/dist/channels/slack/register-webhook.d.ts +1 -0
  99. package/dist/channels/slack/register-webhook.js +6 -5
  100. package/dist/channels/slack/scaffold/channel.ts +23 -24
  101. package/dist/channels/slack/scaffold/slack-send.ts +50 -43
  102. package/dist/channels/slack/scaffold/slack-threads.ts +29 -0
  103. package/dist/channels/slack/setup-server.d.ts +19 -0
  104. package/dist/channels/slack/setup-server.js +113 -11
  105. package/dist/channels/slack/shared-api.d.ts +15 -4
  106. package/dist/channels/slack/shared-api.js +19 -14
  107. package/dist/channels/slack/slack-api.d.ts +61 -2
  108. package/dist/channels/slack/slack-api.js +28 -5
  109. package/dist/channels/slack/slack.js +97 -52
  110. package/dist/channels/slack/welcomed.js +1 -1
  111. package/dist/channels/telegram/context-buffer.d.ts +6 -1
  112. package/dist/channels/telegram/context-buffer.js +19 -0
  113. package/dist/channels/telegram/invoke-turn.d.ts +8 -4
  114. package/dist/channels/telegram/invoke-turn.js +7 -7
  115. package/dist/channels/telegram/parse.d.ts +7 -2
  116. package/dist/channels/telegram/parse.js +7 -0
  117. package/dist/channels/telegram/preview.d.ts +2 -2
  118. package/dist/channels/telegram/register-webhook.d.ts +1 -0
  119. package/dist/channels/telegram/register-webhook.js +3 -2
  120. package/dist/channels/telegram/scaffold/channel.ts +27 -28
  121. package/dist/channels/telegram/scaffold/telegram-send.ts +61 -108
  122. package/dist/channels/telegram/shared-api.d.ts +34 -0
  123. package/dist/channels/telegram/shared-api.js +79 -0
  124. package/dist/channels/telegram/telegram-api.d.ts +15 -5
  125. package/dist/channels/telegram/telegram-api.js +10 -6
  126. package/dist/channels/telegram/telegram.js +27 -21
  127. package/dist/channels/telegram/turn-store.js +1 -1
  128. package/dist/channels/{kit/turn-queue.d.ts → turn-queue.d.ts} +2 -2
  129. package/dist/channels/{kit/turn-queue.js → turn-queue.js} +10 -10
  130. package/dist/cli/add-feishu.d.ts +42 -12
  131. package/dist/cli/add-feishu.js +177 -124
  132. package/dist/cli/add-slack.d.ts +8 -3
  133. package/dist/cli/add-slack.js +115 -63
  134. package/dist/cli/auth-view.d.ts +10 -3
  135. package/dist/cli/auth-view.js +8 -6
  136. package/dist/cli/box-login.d.ts +17 -7
  137. package/dist/cli/box-login.js +46 -12
  138. package/dist/cli/commands/add.d.ts +15 -4
  139. package/dist/cli/commands/add.js +252 -143
  140. package/dist/cli/commands/auth.d.ts +6 -0
  141. package/dist/cli/commands/auth.js +50 -0
  142. package/dist/cli/commands/content.d.ts +6 -0
  143. package/dist/cli/commands/content.js +45 -0
  144. package/dist/cli/commands/deploy/agentcore.js +50 -77
  145. package/dist/cli/commands/deploy/docker.js +38 -39
  146. package/dist/cli/commands/deploy/fly.js +21 -18
  147. package/dist/cli/commands/deploy/host-login.d.ts +26 -0
  148. package/dist/cli/commands/deploy/host-login.js +90 -0
  149. package/dist/cli/commands/deploy/railway.js +21 -26
  150. package/dist/cli/commands/deploy/shared.d.ts +45 -17
  151. package/dist/cli/commands/deploy/shared.js +34 -15
  152. package/dist/cli/commands/deploy.d.ts +0 -4
  153. package/dist/cli/commands/deploy.js +237 -50
  154. package/dist/cli/commands/destroy.js +8 -6
  155. package/dist/cli/commands/dev.d.ts +0 -2
  156. package/dist/cli/commands/dev.js +20 -19
  157. package/dist/cli/commands/env.d.ts +12 -0
  158. package/dist/cli/commands/env.js +190 -0
  159. package/dist/cli/commands/info.js +95 -156
  160. package/dist/cli/commands/init.d.ts +2 -2
  161. package/dist/cli/commands/init.js +35 -33
  162. package/dist/cli/commands/invoke.d.ts +6 -0
  163. package/dist/cli/commands/invoke.js +131 -16
  164. package/dist/cli/commands/login.d.ts +31 -2
  165. package/dist/cli/commands/login.js +413 -64
  166. package/dist/cli/commands/logout.d.ts +4 -0
  167. package/dist/cli/commands/logout.js +53 -0
  168. package/dist/cli/commands/logs.js +8 -6
  169. package/dist/cli/commands/models.d.ts +2 -1
  170. package/dist/cli/commands/models.js +39 -37
  171. package/dist/cli/commands/schedules.d.ts +21 -0
  172. package/dist/cli/commands/schedules.js +143 -0
  173. package/dist/cli/commands/start.d.ts +11 -10
  174. package/dist/cli/commands/start.js +35 -62
  175. package/dist/cli/content-view.d.ts +9 -0
  176. package/dist/cli/content-view.js +26 -0
  177. package/dist/cli/fail.d.ts +9 -12
  178. package/dist/cli/fail.js +17 -14
  179. package/dist/cli/invoke-stream.d.ts +12 -3
  180. package/dist/cli/invoke-stream.js +85 -23
  181. package/dist/cli/kernel.d.ts +9 -2
  182. package/dist/cli/kernel.js +15 -6
  183. package/dist/cli/login-relay.d.ts +3 -2
  184. package/dist/cli/login-relay.js +18 -6
  185. package/dist/cli/models-view.d.ts +5 -1
  186. package/dist/cli/models-view.js +1 -1
  187. package/dist/cli/person.d.ts +10 -0
  188. package/dist/cli/person.js +23 -0
  189. package/dist/cli/program.js +421 -203
  190. package/dist/cli/serve.d.ts +13 -63
  191. package/dist/cli/serve.js +31 -121
  192. package/dist/cli/shared.d.ts +21 -48
  193. package/dist/cli/shared.js +68 -89
  194. package/dist/cli/ticket.d.ts +136 -0
  195. package/dist/cli/ticket.js +476 -0
  196. package/dist/client.d.ts +7 -0
  197. package/dist/client.js +2 -0
  198. package/dist/content/declare.d.ts +70 -0
  199. package/dist/content/declare.js +163 -0
  200. package/dist/content/file.d.ts +32 -0
  201. package/dist/content/file.js +119 -0
  202. package/dist/content/git.d.ts +41 -0
  203. package/dist/content/git.js +217 -0
  204. package/dist/content/mount.d.ts +2 -0
  205. package/dist/content/mount.js +15 -0
  206. package/dist/content/resolve.d.ts +52 -0
  207. package/dist/content/resolve.js +151 -0
  208. package/dist/content/source.d.ts +27 -0
  209. package/dist/content/source.js +53 -0
  210. package/dist/conversation-sessions.d.ts +26 -0
  211. package/dist/conversation-sessions.js +99 -0
  212. package/dist/declared-secrets.d.ts +19 -37
  213. package/dist/declared-secrets.js +16 -58
  214. package/dist/deploy/agentcore/destroy.d.ts +3 -3
  215. package/dist/deploy/agentcore/destroy.js +46 -28
  216. package/dist/deploy/agentcore/forwarder.js +105 -22
  217. package/dist/deploy/agentcore/logs.js +1 -1
  218. package/dist/deploy/agentcore/plan.d.ts +10 -24
  219. package/dist/deploy/agentcore/plan.js +31 -135
  220. package/dist/deploy/agentcore/run.d.ts +1 -1
  221. package/dist/deploy/agentcore/run.js +8 -5
  222. package/dist/deploy/agentcore/shell.d.ts +1 -1
  223. package/dist/deploy/agentcore/shell.js +5 -5
  224. package/dist/deploy/api.d.ts +34 -0
  225. package/dist/deploy/api.js +50 -0
  226. package/dist/deploy/box-shell.d.ts +6 -0
  227. package/dist/deploy/box-shell.js +7 -0
  228. package/dist/deploy/build-context.d.ts +7 -5
  229. package/dist/deploy/build-context.js +41 -35
  230. package/dist/deploy/channel-ingress.d.ts +6 -1
  231. package/dist/deploy/channel-ingress.js +18 -5
  232. package/dist/deploy/container.d.ts +22 -9
  233. package/dist/deploy/container.js +96 -55
  234. package/dist/deploy/docker/plan.d.ts +3 -2
  235. package/dist/deploy/docker/plan.js +13 -14
  236. package/dist/deploy/docker/run.d.ts +2 -2
  237. package/dist/deploy/docker/run.js +8 -4
  238. package/dist/deploy/fly/plan.d.ts +1 -1
  239. package/dist/deploy/fly/plan.js +12 -21
  240. package/dist/deploy/fly/run.d.ts +10 -6
  241. package/dist/deploy/fly/run.js +11 -6
  242. package/dist/deploy/hosts.d.ts +2 -1
  243. package/dist/deploy/hosts.js +2 -1
  244. package/dist/deploy/preflight.d.ts +21 -23
  245. package/dist/deploy/preflight.js +222 -201
  246. package/dist/deploy/railway/plan.d.ts +8 -6
  247. package/dist/deploy/railway/plan.js +15 -58
  248. package/dist/deploy/railway/run.d.ts +8 -3
  249. package/dist/deploy/railway/run.js +12 -8
  250. package/dist/deploy/residency.d.ts +5 -11
  251. package/dist/deploy/residency.js +0 -6
  252. package/dist/deploy/runner.d.ts +1 -1
  253. package/dist/deploy/runner.js +1 -1
  254. package/dist/deploy/secrets.d.ts +16 -2
  255. package/dist/deploy/secrets.js +33 -6
  256. package/dist/deploy/workspace.d.ts +11 -6
  257. package/dist/deploy/workspace.js +55 -38
  258. package/dist/dev-supervisor.d.ts +11 -2
  259. package/dist/dev-supervisor.js +51 -26
  260. package/dist/effect-port.d.ts +4 -4
  261. package/dist/effect-port.js +4 -4
  262. package/dist/environment/apt.d.ts +4 -0
  263. package/dist/environment/apt.js +32 -0
  264. package/dist/environment/declare.d.ts +59 -0
  265. package/dist/environment/declare.js +210 -0
  266. package/dist/environment/mise.d.ts +50 -0
  267. package/dist/environment/mise.js +268 -0
  268. package/dist/feishu.d.ts +2 -2
  269. package/dist/feishu.js +2 -2
  270. package/dist/git.d.ts +13 -0
  271. package/dist/git.js +55 -0
  272. package/dist/harnesses/models/catalog.d.ts +20 -0
  273. package/dist/harnesses/models/catalog.js +254 -0
  274. package/dist/{engines/pi/auth.d.ts → harnesses/models/credentials.d.ts} +3 -3
  275. package/dist/{engines/pi/auth.js → harnesses/models/credentials.js} +3 -3
  276. package/dist/harnesses/models/environment.d.ts +43 -0
  277. package/dist/harnesses/models/environment.js +82 -0
  278. package/dist/{engines/pi → harnesses/models}/login.d.ts +57 -26
  279. package/dist/{engines/pi → harnesses/models}/login.js +187 -79
  280. package/dist/harnesses/models/models.d.ts +83 -0
  281. package/dist/harnesses/models/models.js +158 -0
  282. package/dist/harnesses/pi-durable/agent.d.ts +42 -0
  283. package/dist/harnesses/pi-durable/agent.js +579 -0
  284. package/dist/harnesses/pi-durable/defaults.d.ts +28 -0
  285. package/dist/harnesses/pi-durable/defaults.js +26 -0
  286. package/dist/harnesses/pi-durable/define.d.ts +77 -0
  287. package/dist/harnesses/pi-durable/define.js +28 -0
  288. package/dist/harnesses/pi-durable/entries.d.ts +32 -0
  289. package/dist/harnesses/pi-durable/entries.js +126 -0
  290. package/dist/harnesses/pi-durable/events.d.ts +25 -0
  291. package/dist/harnesses/pi-durable/events.js +238 -0
  292. package/dist/harnesses/pi-durable/ids.d.ts +16 -0
  293. package/dist/harnesses/pi-durable/ids.js +55 -0
  294. package/dist/harnesses/pi-durable/messages.d.ts +41 -0
  295. package/dist/harnesses/pi-durable/messages.js +116 -0
  296. package/dist/harnesses/pi-durable/open.d.ts +88 -0
  297. package/dist/harnesses/pi-durable/open.js +329 -0
  298. package/dist/harnesses/pi-durable/reads.d.ts +30 -0
  299. package/dist/harnesses/pi-durable/reads.js +94 -0
  300. package/dist/harnesses/pi-durable/registry.d.ts +18 -0
  301. package/dist/harnesses/pi-durable/registry.js +56 -0
  302. package/dist/harnesses/pi-durable/release.d.ts +13 -0
  303. package/dist/harnesses/pi-durable/release.js +40 -0
  304. package/dist/harnesses/pi-durable/serve.d.ts +80 -0
  305. package/dist/harnesses/pi-durable/serve.js +156 -0
  306. package/dist/harnesses/pi-durable/sessions.d.ts +27 -0
  307. package/dist/harnesses/pi-durable/sessions.js +47 -0
  308. package/dist/harnesses/pi-durable/storage.d.ts +4 -0
  309. package/dist/harnesses/pi-durable/storage.js +49 -0
  310. package/dist/harnesses/pi-durable/stream.d.ts +20 -0
  311. package/dist/harnesses/pi-durable/stream.js +221 -0
  312. package/dist/harnesses/pi-durable/text.d.ts +30 -0
  313. package/dist/harnesses/pi-durable/text.js +292 -0
  314. package/dist/harnesses/pi-durable/wake.d.ts +4 -0
  315. package/dist/harnesses/pi-durable/wake.js +81 -0
  316. package/dist/http/client.d.ts +6 -0
  317. package/dist/http/client.js +256 -0
  318. package/dist/http/contract.d.ts +541 -0
  319. package/dist/http/contract.js +179 -0
  320. package/dist/http/server.d.ts +34 -0
  321. package/dist/http/server.js +194 -0
  322. package/dist/index.d.ts +17 -4
  323. package/dist/index.js +10 -5
  324. package/dist/lark.d.ts +2 -2
  325. package/dist/lark.js +2 -2
  326. package/dist/locked-file.d.ts +17 -0
  327. package/dist/{engines/pi/locked-file.js → locked-file.js} +16 -10
  328. package/dist/once.d.ts +6 -0
  329. package/dist/once.js +23 -0
  330. package/dist/paths.d.ts +36 -52
  331. package/dist/paths.js +66 -182
  332. package/dist/runtime.d.ts +25 -2
  333. package/dist/runtime.js +27 -0
  334. package/dist/scaffold/add-channel.d.ts +14 -27
  335. package/dist/scaffold/add-channel.js +82 -180
  336. package/dist/scaffold/init.d.ts +17 -18
  337. package/dist/scaffold/init.js +87 -99
  338. package/dist/scaffold/templates/SYSTEM.md +12 -0
  339. package/dist/scaffold/templates/env.example +4 -10
  340. package/dist/scaffold/templates/fastagent.config.ts +21 -33
  341. package/dist/scaffold/templates/gitignore +8 -1
  342. package/dist/scaffold/templates/skills/writing-great-skills/SKILL.md +1 -2
  343. package/dist/scaffold/templates.d.ts +9 -4
  344. package/dist/scaffold/templates.js +7 -5
  345. package/dist/scaffold/vendor-skill.d.ts +1 -4
  346. package/dist/scaffold/vendor-skill.js +5 -6
  347. package/dist/schedule/cron.d.ts +13 -0
  348. package/dist/schedule/cron.js +52 -0
  349. package/dist/schedule/eventbridge-cron.d.ts +17 -0
  350. package/dist/schedule/eventbridge-cron.js +88 -0
  351. package/dist/schedule/schedule.d.ts +23 -0
  352. package/dist/schedule/schedule.js +34 -0
  353. package/dist/schedule/scheduler.d.ts +34 -33
  354. package/dist/schedule/scheduler.js +251 -137
  355. package/dist/schedule/state.d.ts +4 -14
  356. package/dist/schedule/state.js +7 -7
  357. package/dist/schedule/wake-alarm.d.ts +22 -2
  358. package/dist/schedule/wake-alarm.js +66 -20
  359. package/dist/schedule/wakeups.d.ts +16 -15
  360. package/dist/schedule/wakeups.js +47 -45
  361. package/dist/service.d.ts +56 -169
  362. package/dist/service.js +91 -187
  363. package/dist/serving-command.d.ts +10 -0
  364. package/dist/serving-command.js +16 -0
  365. package/dist/slack.d.ts +1 -1
  366. package/dist/slack.js +1 -1
  367. package/dist/{channels/kit/state.js → state-file.js} +6 -6
  368. package/dist/telegram.d.ts +1 -0
  369. package/dist/telegram.js +1 -0
  370. package/dist/tunnel.d.ts +3 -0
  371. package/dist/tunnel.js +12 -4
  372. package/dist/value-file.d.ts +21 -0
  373. package/dist/value-file.js +108 -0
  374. package/dist/version.d.ts +5 -0
  375. package/dist/version.js +14 -1
  376. package/package.json +18 -28
  377. package/dist/agent.d.ts +0 -106
  378. package/dist/agent.js +0 -21
  379. package/dist/channels/control.d.ts +0 -31
  380. package/dist/channels/control.js +0 -329
  381. package/dist/channels/define-channel.d.ts +0 -39
  382. package/dist/channels/define-channel.js +0 -9
  383. package/dist/channels/feishu/context-buffer.d.ts +0 -35
  384. package/dist/channels/feishu/context-buffer.js +0 -65
  385. package/dist/channels/feishu/scaffold/channel.websocket.ts +0 -31
  386. package/dist/channels/http.d.ts +0 -23
  387. package/dist/channels/http.js +0 -57
  388. package/dist/channels/lark/scaffold/channel.websocket.ts +0 -31
  389. package/dist/channels/slack/context-buffer.d.ts +0 -23
  390. package/dist/channels/slack/context-buffer.js +0 -37
  391. package/dist/channels/sse.d.ts +0 -4
  392. package/dist/channels/sse.js +0 -66
  393. package/dist/cli/commands/chat.d.ts +0 -3
  394. package/dist/cli/commands/chat.js +0 -14
  395. package/dist/cli/commands/routine-run.d.ts +0 -6
  396. package/dist/cli/commands/routine-run.js +0 -46
  397. package/dist/cli/commands/routine.d.ts +0 -25
  398. package/dist/cli/commands/routine.js +0 -122
  399. package/dist/cli/commands/tool.d.ts +0 -1
  400. package/dist/cli/commands/tool.js +0 -57
  401. package/dist/collect.d.ts +0 -63
  402. package/dist/collect.js +0 -90
  403. package/dist/core.d.ts +0 -13
  404. package/dist/core.js +0 -15
  405. package/dist/engines/pi/agent-models.d.ts +0 -83
  406. package/dist/engines/pi/agent-models.js +0 -120
  407. package/dist/engines/pi/agent-session-factory.d.ts +0 -121
  408. package/dist/engines/pi/agent-session-factory.js +0 -535
  409. package/dist/engines/pi/chat.d.ts +0 -3
  410. package/dist/engines/pi/chat.js +0 -8
  411. package/dist/engines/pi/config.d.ts +0 -71
  412. package/dist/engines/pi/config.js +0 -199
  413. package/dist/engines/pi/create.d.ts +0 -170
  414. package/dist/engines/pi/create.js +0 -343
  415. package/dist/engines/pi/definition.d.ts +0 -74
  416. package/dist/engines/pi/definition.js +0 -236
  417. package/dist/engines/pi/entry-images.d.ts +0 -14
  418. package/dist/engines/pi/entry-images.js +0 -23
  419. package/dist/engines/pi/invoke-session.d.ts +0 -18
  420. package/dist/engines/pi/invoke-session.js +0 -403
  421. package/dist/engines/pi/locked-file.d.ts +0 -9
  422. package/dist/engines/pi/machine.d.ts +0 -53
  423. package/dist/engines/pi/machine.js +0 -137
  424. package/dist/engines/pi/models.d.ts +0 -200
  425. package/dist/engines/pi/models.js +0 -533
  426. package/dist/engines/pi/open.d.ts +0 -180
  427. package/dist/engines/pi/open.js +0 -270
  428. package/dist/engines/pi/openai-account-models.d.ts +0 -35
  429. package/dist/engines/pi/openai-account-models.js +0 -116
  430. package/dist/engines/pi/report.d.ts +0 -18
  431. package/dist/engines/pi/report.js +0 -59
  432. package/dist/engines/pi/retry-event.d.ts +0 -6
  433. package/dist/engines/pi/retry-event.js +0 -15
  434. package/dist/engines/pi/service.d.ts +0 -9
  435. package/dist/engines/pi/service.js +0 -14
  436. package/dist/engines/pi/session-builder.d.ts +0 -13
  437. package/dist/engines/pi/session-builder.js +0 -117
  438. package/dist/engines/pi/session-control.d.ts +0 -77
  439. package/dist/engines/pi/session-control.js +0 -908
  440. package/dist/engines/pi/session-effects.d.ts +0 -14
  441. package/dist/engines/pi/session-effects.js +0 -30
  442. package/dist/engines/pi/session-inheritance.d.ts +0 -21
  443. package/dist/engines/pi/session-inheritance.js +0 -204
  444. package/dist/engines/pi/session-markers.d.ts +0 -49
  445. package/dist/engines/pi/session-markers.js +0 -60
  446. package/dist/engines/pi/session-settings.d.ts +0 -67
  447. package/dist/engines/pi/session-settings.js +0 -119
  448. package/dist/engines/pi/session-store.d.ts +0 -69
  449. package/dist/engines/pi/session-store.js +0 -430
  450. package/dist/engines/pi/tool-context.d.ts +0 -45
  451. package/dist/engines/pi/tool-context.js +0 -31
  452. package/dist/engines/pi/tool.d.ts +0 -99
  453. package/dist/engines/pi/tool.js +0 -118
  454. package/dist/engines/pi/turn-kit.d.ts +0 -92
  455. package/dist/engines/pi/turn-kit.js +0 -288
  456. package/dist/engines/pi/wake-tool.d.ts +0 -9
  457. package/dist/engines/pi/wake-tool.js +0 -92
  458. package/dist/loader.d.ts +0 -41
  459. package/dist/loader.js +0 -116
  460. package/dist/node.d.ts +0 -3
  461. package/dist/node.js +0 -4
  462. package/dist/observe.d.ts +0 -6
  463. package/dist/observe.js +0 -47
  464. package/dist/pi.d.ts +0 -25
  465. package/dist/pi.js +0 -15
  466. package/dist/scaffold/templates/APPEND_SYSTEM.md +0 -12
  467. package/dist/scaffold/templates/tools/fetch-url.ts +0 -25
  468. package/dist/schedule/discover.d.ts +0 -17
  469. package/dist/schedule/discover.js +0 -61
  470. package/dist/schedule/routine.d.ts +0 -43
  471. package/dist/schedule/routine.js +0 -32
  472. package/dist/schedule/run.d.ts +0 -55
  473. package/dist/schedule/run.js +0 -146
  474. package/dist/secrets-gate.d.ts +0 -32
  475. package/dist/secrets-gate.js +0 -33
  476. package/dist/session-remote.d.ts +0 -47
  477. package/dist/session-remote.js +0 -460
  478. package/dist/session.d.ts +0 -466
  479. package/dist/session.js +0 -57
  480. /package/dist/{channels/kit/state.d.ts → state-file.d.ts} +0 -0
package/dist/loader.js DELETED
@@ -1,116 +0,0 @@
1
- var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
- if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
- return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
- return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
- });
6
- }
7
- return path;
8
- };
9
- import { readdir } from "node:fs/promises";
10
- import { basename, extname, join } from "node:path";
11
- import { pathToFileURL } from "node:url";
12
- import { log } from "./log.js";
13
- const MODULE_EXTS = new Set([".ts", ".js", ".mjs"]);
14
- /** Whether `name` is an importable agent module (a discovery candidate, not a type declaration). */
15
- function isModuleFile(name) {
16
- return MODULE_EXTS.has(extname(name)) && !name.endsWith(".d.ts");
17
- }
18
- /** The name a module is known by: its basename without the extension. */
19
- function moduleName(fileName) {
20
- return basename(fileName, extname(fileName));
21
- }
22
- /**
23
- * WHAT A CODE-INPUT DIRECTORY DECLARES — the single answer to "which files here are modules", without importing any of
24
- * them. Internal: the loading functions below are its only consumers.
25
- */
26
- async function moduleInventory(subDir) {
27
- let dirents;
28
- try {
29
- dirents = await readdir(subDir, { withFileTypes: true });
30
- }
31
- catch (error) {
32
- const code = error.code;
33
- if (code === "ENOENT" || code === "not_found")
34
- return [];
35
- throw new Error(`cannot read ${subDir}: ${error.message}`);
36
- }
37
- const sub = basename(subDir);
38
- const entries = [];
39
- // Sorted by the NAME a consumer sees, so none of them re-sorts and none can disagree about order.
40
- const byName = (a, b) => moduleName(a.name).localeCompare(moduleName(b.name)) || a.name.localeCompare(b.name);
41
- for (const dirent of dirents.sort(byName)) {
42
- if (!isModuleFile(dirent.name))
43
- continue;
44
- const label = `${sub}/${dirent.name}`;
45
- if (dirent.isFile()) {
46
- entries.push({ name: moduleName(dirent.name), label, file: join(subDir, dirent.name) });
47
- }
48
- else if (dirent.isSymbolicLink()) {
49
- log.warn(`[fastagent] ${label} is a symlink — code inputs must be real files inside the agent dir — not loaded`);
50
- }
51
- else if (dirent.isDirectory()) {
52
- log.warn(`[fastagent] ${label} is a directory, not a file — not loaded`);
53
- }
54
- else {
55
- log.warn(`[fastagent] ${label} is not a regular file — not loaded`);
56
- }
57
- }
58
- return entries;
59
- }
60
- /** A module the loader skipped, said once, the same way for tools, channels and routines. */
61
- export function reportModuleLoadFailures(failures) {
62
- for (const f of failures)
63
- log.warn(`[fastagent] ${f.label} failed to load, skipping it — ${f.message}`);
64
- }
65
- /**
66
- * THE REFUSAL every path that is about to RUN the agent shares: an enabled file under `tools/`, `channels/` or
67
- * `routines/` is a declaration, so one that cannot load means the agent is missing something its author said it
68
- * has. Starting anyway announces a ready service over an absent capability — a schedule that never fires, a tool the
69
- * model simply never gets — with nothing but one warning to find it by. Every failure is reported before this
70
- * throws, so a boot fixes all of them at once rather than one per restart.
71
- *
72
- * Inspecting a definition (`info`, `fastagent tool`) is NOT this path: it must survive a broken file in order to
73
- * report it.
74
- */
75
- export function refuseBrokenDeclarations(failures) {
76
- if (failures.length === 0)
77
- return;
78
- reportModuleLoadFailures(failures);
79
- // The reasons are repeated from the warnings above because this message is all an embedder catching the rejection
80
- // has, and all a deployment running at FASTAGENT_LOG_LEVEL=error sees.
81
- throw new Error(`failed to load: ${failures.map((f) => `${f.label} (${f.message})`).join("; ")} — fix it, or rename an ` +
82
- `intentionally disabled file to *.disabled`);
83
- }
84
- /** Import every module the directory declares ({@link moduleInventory}). */
85
- export async function loadModuleDir(subDir) {
86
- const entries = await moduleInventory(subDir);
87
- const modules = [];
88
- const failures = [];
89
- for (const { name, label, file } of entries) {
90
- try {
91
- const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(file).href)));
92
- modules.push({ name, label, file, mod });
93
- }
94
- catch (error) {
95
- failures.push({
96
- label,
97
- file,
98
- message: `${error.message}${moduleLoadHint(error)}`,
99
- });
100
- }
101
- }
102
- return { modules, failures };
103
- }
104
- /**
105
- * A hint for the two common dynamic-import failures — an uninstalled dependency or a non-ESM package — and empty
106
- * otherwise, so an unrelated error is reported on its own.
107
- */
108
- export function moduleLoadHint(error) {
109
- if (error.code === "ERR_MODULE_NOT_FOUND" || /Cannot find (package|module)/.test(error.message)) {
110
- return "\n (a dependency is not installed — run `npm install` in the agent dir)";
111
- }
112
- if (/import statement outside a module|Unexpected token 'export'|ERR_REQUIRE_ESM/.test(error.message)) {
113
- return '\n (the agent dir must be ESM — set "type": "module" in package.json)';
114
- }
115
- return "";
116
- }
package/dist/node.d.ts DELETED
@@ -1,3 +0,0 @@
1
- /** Binding a Fetch handler to a Node HTTP server. */
2
- export { nodeListener, serveNode } from "./channels/serve.ts";
3
- export { mountAgentService, type AgentService, type HttpSurface, type MountableAgent, type MountAgentServiceOptions, } from "./service.ts";
package/dist/node.js DELETED
@@ -1,4 +0,0 @@
1
- /** Binding a Fetch handler to a Node HTTP server. */
2
- export { nodeListener, serveNode } from "./channels/serve.js";
3
- // The assembly: a MountableAgent becomes a mounted service.
4
- export { mountAgentService, } from "./service.js";
package/dist/observe.d.ts DELETED
@@ -1,6 +0,0 @@
1
- /**
2
- * The turn trace: wrap an Agent to tee each turn's loop — prompt, reasoning, tool calls (name + args) with results,
3
- * reply, terminal — to the log at DEBUG level.
4
- */
5
- import type { Agent } from "./agent.ts";
6
- export declare function logAgentLoop(agent: Agent, sink?: (line: string) => void): Agent;
package/dist/observe.js DELETED
@@ -1,47 +0,0 @@
1
- import { log } from "./log.js";
2
- const PREVIEW = 200;
3
- /** One line, whitespace-collapsed, truncated — a log stays scannable. */
4
- function oneLine(s) {
5
- const t = s.replace(/\s+/g, " ").trim();
6
- return t.length > PREVIEW ? `${t.slice(0, PREVIEW - 1)}…` : t;
7
- }
8
- const preview = (v) => oneLine(typeof v === "string" ? v : JSON.stringify(v));
9
- export function logAgentLoop(agent, sink = (line) => log.debug(line)) {
10
- return {
11
- async *invoke(scope, prompt) {
12
- const s = scope.session;
13
- sink(`[agent] ▶ turn session=${s} ← ${oneLine(prompt.text)}`);
14
- const toolName = new Map(); // tool_ended carries no name — remember it from tool_started
15
- let thinking = "";
16
- let reply = "";
17
- for await (const e of agent.invoke(scope, prompt)) {
18
- if (e.type === "text") {
19
- reply += e.delta;
20
- }
21
- else if (e.type === "thinking") {
22
- thinking += e.delta;
23
- }
24
- else if (e.type === "tool_started") {
25
- toolName.set(e.id, e.name);
26
- sink(`[agent] tool → ${e.name}(${preview(e.args)})`);
27
- }
28
- else if (e.type === "tool_ended") {
29
- sink(`[agent] tool ${e.isError ? "✗" : "✓"} ${toolName.get(e.id) ?? e.id} → ${preview(e.content)}`);
30
- }
31
- else if (e.type === "retrying") {
32
- sink(`[agent] retrying (${e.attempt}/${e.maxAttempts} in ${e.delayMs}ms): ${oneLine(e.reason)}`);
33
- }
34
- else if (e.type === "completed") {
35
- if (thinking.trim() !== "")
36
- sink(`[agent] thinking: ${oneLine(thinking)}`);
37
- sink(`[agent] reply: ${oneLine(reply) || "(empty)"}`);
38
- sink(`[agent] ■ completed session=${s}`);
39
- }
40
- else if (e.type === "failed") {
41
- sink(`[agent] ■ failed session=${s}: ${e.details} (retryable=${e.retryable})`);
42
- }
43
- yield e;
44
- }
45
- },
46
- };
47
- }
package/dist/pi.d.ts DELETED
@@ -1,25 +0,0 @@
1
- export { createPiAgent, createPiAgentFromDefinition, type CreatePiAgentFromDefinitionOptions, type CreatePiAgentOptions, } from "./engines/pi/create.ts";
2
- export { defineTool, type DefineToolOptions, type FastagentTool, type MountedTool, type ToolCollision, type ToolContext, } from "./engines/pi/tool.ts";
3
- export type { ReadonlySessionManager, ToolActivation } from "./engines/pi/tool-context.ts";
4
- export { z } from "zod";
5
- export type { AgentTool, ExecutionEnv, Skill, SkillDiagnostic } from "@earendil-works/pi-agent-core";
6
- /** A conversation record, as the tool runtime and the control plane hold it. */
7
- export type { SessionManager, SessionEntry as PiSessionEntry } from "@earendil-works/pi-coding-agent";
8
- export { availableModelsFromDir, createPiAgentFromDir, type CreatePiAgentFromDirOptions, refreshMachineModelCatalog, refreshModelCatalog, } from "./engines/pi/open.ts";
9
- export type { DefinitionDiagnostic, DefinitionFile, DefinitionPrompt, DefinitionShadow, LoadedDefinition, SkillCollision, } from "./engines/pi/definition.ts";
10
- export { defineConfig, listModels, resolveModel, type FastagentConfig, } from "./engines/pi/config.ts";
11
- export type { SessionObserver } from "./engines/pi/turn-kit.ts";
12
- export { inProcessLease, type Lease, type Release } from "./engines/pi/turn-kit.ts";
13
- export { createPiSessionControl, type CreatePiSessionControlOptions, } from "./engines/pi/session-control.ts";
14
- export { piInMemorySessionRecordStore, piSessionRecordStore, type PiSessionRecordStore, } from "./engines/pi/session-store.ts";
15
- export type { SessionInheritance } from "./engines/pi/session-inheritance.ts";
16
- export { GLOBAL_AUTH_PATH, fastagentCredentialStore, type FastagentAuthOptions } from "./engines/pi/auth.ts";
17
- export { createPiModels, type CreatePiModelsOptions } from "./engines/pi/agent-models.ts";
18
- export { probeAuthSource } from "./engines/pi/models.ts";
19
- export { login, loginOptions, LoginCancelled, type LoginMethod, type LoginOption, type LoginRequest, type LoginResult, } from "./engines/pi/login.ts";
20
- /** pi-ai's sign-in types, and the `CredentialStore` a caller supplies as `credentialStore` (with what it holds). */
21
- export type { AuthEvent, AuthInteraction, AuthPrompt, Credential, CredentialStore } from "@earendil-works/pi-ai";
22
- export type { Models } from "@earendil-works/pi-ai";
23
- export type { Provider, ProviderAuth } from "@earendil-works/pi-ai";
24
- export type { Model } from "@earendil-works/pi-ai";
25
- export { createAgentService, type CreateAgentServiceOptions } from "./engines/pi/service.ts";
package/dist/pi.js DELETED
@@ -1,15 +0,0 @@
1
- // The pi reference implementation: assembly, agent discovery, tools, config, models, auth, and state ports.
2
- export { createPiAgent, createPiAgentFromDefinition, } from "./engines/pi/create.js";
3
- export { defineTool, } from "./engines/pi/tool.js";
4
- export { z } from "zod";
5
- export { availableModelsFromDir, createPiAgentFromDir, refreshMachineModelCatalog, refreshModelCatalog, } from "./engines/pi/open.js";
6
- export { defineConfig, listModels, resolveModel, } from "./engines/pi/config.js";
7
- export { inProcessLease } from "./engines/pi/turn-kit.js";
8
- export { createPiSessionControl, } from "./engines/pi/session-control.js";
9
- export { piInMemorySessionRecordStore, piSessionRecordStore, } from "./engines/pi/session-store.js";
10
- export { GLOBAL_AUTH_PATH, fastagentCredentialStore } from "./engines/pi/auth.js";
11
- export { createPiModels } from "./engines/pi/agent-models.js";
12
- export { probeAuthSource } from "./engines/pi/models.js";
13
- export { login, loginOptions, LoginCancelled, } from "./engines/pi/login.js";
14
- // The product's one-call assembly: a directory becomes a live service.
15
- export { createAgentService } from "./engines/pi/service.js";
@@ -1,12 +0,0 @@
1
- # Standing instructions
2
-
3
- These instructions are added to your system prompt on every turn. This file, `APPEND_SYSTEM.md`, is re-read every turn along with the rest of your definition (`skills/` — capabilities you load when a task calls for them; `prompts/` — prompt templates; `tools/` — code tools your author added, in the same directory as this file). An edit to any of them takes effect on your next message, no restart.
4
-
5
- Your definition is this directory: `APPEND_SYSTEM.md`, `skills/`, `tools/`, and the config beside them. Your WORKSPACE is the directory you were started in — the project you work on. It may be this same directory, or the one containing it; `fastagent info` prints both. Use only the tools actually listed in your system prompt. If the workspace has an `AGENTS.md`, it is project context — follow it without assuming a file tool is available.
6
-
7
- When your mounted tools allow it, you can improve yourself. When a task reveals something durable — a repeatable process, a standing preference, a hard-won fact — write it into your definition instead of losing it:
8
-
9
- - A repeatable process or capability → a new skill beside this file: `skills/<name>/SKILL.md`. Read `skills/writing-great-skills/SKILL.md` first; it is the guide to authoring skills well.
10
- - A standing instruction or fact → edit this file.
11
-
12
- Keep both lean: include only what changes your behavior, and delete what no longer earns its place.
@@ -1,25 +0,0 @@
1
- import { defineTool, z } from "@fastagent-sh/fastagent";
2
-
3
- // A code tool: filename (fetch-url.ts) is the tool name. tools/ is auto-discovered,
4
- // so it needs no registration in fastagent.config. Test it without a model:
5
- // fastagent tool fetch-url '{"url":"https://example.com"}'
6
- const MAX_TEXT = 20_000; // keep a huge page from flooding the model's context
7
-
8
- export default defineTool({
9
- description: "Fetch a web page and return its readable text (HTML stripped, truncated).",
10
- input: z.object({ url: z.url({ protocol: /^https?$/ }).describe("The http(s) URL to fetch") }),
11
- async execute({ url }) {
12
- const res = await fetch(url, { redirect: "follow", signal: AbortSignal.timeout(15_000) });
13
- if (!res.ok) throw new Error(`GET ${url} failed: ${res.status} ${res.statusText}`);
14
- const html = await res.text();
15
- // ponytail: naive tag strip — fine for articles and docs; swap in a readability library if it falls short.
16
- const entities: Record<string, string> = { amp: "&", lt: "<", gt: ">", quot: '"', "#39": "'", nbsp: " " };
17
- const text = html
18
- .replace(/<(script|style)\b[\s\S]*?<\/\1>/gi, " ")
19
- .replace(/<[^>]+>/g, " ")
20
- .replace(/&(amp|lt|gt|quot|#39|nbsp);/g, (_, e) => entities[e] ?? " ")
21
- .replace(/\s+/g, " ")
22
- .trim();
23
- return { url: res.url, text: text.slice(0, MAX_TEXT), truncated: text.length > MAX_TEXT };
24
- },
25
- });
@@ -1,17 +0,0 @@
1
- import { type ModuleLoadFailure } from "../loader.ts";
2
- import { type DeclaredSecret } from "../declared-secrets.ts";
3
- import type { LoadedRoutine } from "./routine.ts";
4
- /**
5
- * Discover routines in `<dir>/routines/`: each file default-exports a `defineRoutine({...})`, named from its
6
- * filename.
7
- */
8
- export declare function loadRoutines(dir: string): Promise<{
9
- routines: LoadedRoutine[];
10
- /** What each loaded routine declared it needs, BY ROUTINE NAME and attributed to its file. Per
11
- * routine because a caller that runs exactly ONE of them (`fastagent routine run`) must not be stopped
12
- * by a sibling's credential, and because two routines declaring the same variable would
13
- * otherwise blame whichever file was read first. The clock flattens it (it runs all of them).
14
- * Data, not a check — only a serving path asserts it (src/declared-secrets.ts). */
15
- secrets: Map<string, DeclaredSecret[]>;
16
- failures: ModuleLoadFailure[];
17
- }>;
@@ -1,61 +0,0 @@
1
- /**
2
- * Routine discovery: an agent declares its named units of work by dropping files in `routines/`, mirroring
3
- * `tools/` and `channels/`.
4
- */
5
- import { join } from "node:path";
6
- import { loadModuleDir } from "../loader.js";
7
- import { readSecretDeclaration } from "../declared-secrets.js";
8
- import { assertInsideAgentDir } from "../paths.js";
9
- import { cronError } from "./cron.js";
10
- import { isSafeScheduleName } from "./state.js";
11
- /**
12
- * Discover routines in `<dir>/routines/`: each file default-exports a `defineRoutine({...})`, named from its
13
- * filename.
14
- */
15
- export async function loadRoutines(dir) {
16
- await assertInsideAgentDir(dir, "routines");
17
- const { modules, failures } = await loadModuleDir(join(dir, "routines"));
18
- const byName = new Map();
19
- const secrets = new Map();
20
- for (const { name, label, file, mod } of modules) {
21
- try {
22
- const r = mod.default;
23
- if (!r || typeof r.prompt !== "string") {
24
- throw new Error(`${label} must default-export defineRoutine({ prompt, cron? })`);
25
- }
26
- const declaration = readSecretDeclaration(r, label);
27
- if (declaration.error !== undefined)
28
- throw new Error(declaration.error);
29
- // NO CRON IS NOT AN ERROR: the routine is then reachable by name only (`POST /run`, the CLI, a scheduler
30
- // that calls the route). A `tz` without one is, though — it would read as a time this routine does not have.
31
- if (r.cron !== undefined && typeof r.cron !== "string")
32
- throw new Error(`${label}: "cron" must be a string`);
33
- if (r.cron === undefined && r.tz !== undefined) {
34
- throw new Error(`${label}: "tz" means nothing without "cron" — remove it, or give this routine a cron`);
35
- }
36
- if (r.cron !== undefined) {
37
- const err = cronError(r.cron, r.tz);
38
- if (err)
39
- throw new Error(`${label}: invalid cron/tz — ${err}`);
40
- }
41
- // The name becomes a path segment (the fired-slot claims live under `claims/<name>/`), so anything that could
42
- // leave that directory is refused here — where the author sees which file is wrong — rather than deeper.
43
- if (!isSafeScheduleName(name)) {
44
- throw new Error(`${label}: a routine name cannot be ".", ".." or contain a path separator`);
45
- }
46
- if (byName.has(name))
47
- throw new Error(`${label}: duplicate routine name "${name}" — kept the first`);
48
- byName.set(name, {
49
- name,
50
- prompt: r.prompt,
51
- ...(r.cron !== undefined ? { cron: r.cron } : {}),
52
- ...(r.tz !== undefined ? { tz: r.tz } : {}),
53
- });
54
- secrets.set(name, declaration.secrets);
55
- }
56
- catch (error) {
57
- failures.push({ label, file, message: error.message });
58
- }
59
- }
60
- return { routines: [...byName.values()], secrets, failures };
61
- }
@@ -1,43 +0,0 @@
1
- /**
2
- * WHICH conversation a routine's turns belong to: all of them, so a routine shares one continuing conversation —
3
- * and without depending on engine session storage. The ONE spelling of it: the clock invokes through it,
4
- * `fastagent routine run` reproduces a run with it, `POST /run` reports it as where to look, and
5
- * `routine history` prints the command that opens it.
6
- */
7
- export declare function routineSession(name: string): string;
8
- /** A named unit of work the definition owns. With a `cron`, a clock fires it; without one, only its name reaches it. */
9
- export interface Routine {
10
- /**
11
- * 5-field cron expression (`minute hour day-of-month month day-of-week`), or absent.
12
- *
13
- * ABSENT IS A REAL CHOICE, not an omission: the routine is then reachable only by name — `POST /run`, the CLI, a
14
- * platform scheduler that calls the route. A time is one way to ask for work, not what the work is.
15
- */
16
- cron?: string;
17
- /** IANA timezone for the cron (default "UTC"). Meaningless without `cron`. */
18
- tz?: string;
19
- /** The turn's text = the routine's instruction. */
20
- prompt: string;
21
- /** Env vars this routine declared — carried by `deploy`, asserted before the clock starts. */
22
- secrets?: readonly string[];
23
- }
24
- /** What an author writes. `prompt` may be built FROM the declared secrets, which is the only reason a
25
- * routine file ever read the environment (a channel id, a target inbox). */
26
- export interface DefineRoutineOptions<S extends readonly string[]> {
27
- cron?: string;
28
- tz?: string;
29
- prompt: string | ((secrets: Record<S[number], string>) => string);
30
- /**
31
- * Env vars this routine needs (`["SLACK_DIGEST_CHANNEL"]`), typed into the `prompt` builder.
32
- * `deploy` carries them and the clock refuses to start while one is unset, naming this file
33
- * (see src/declared-secrets.ts) — the guarantees a bare `process.env` read cannot have.
34
- */
35
- secrets?: S;
36
- }
37
- /** Type + completion for a routine file, and the ONE place a prompt builder is resolved (at load:
38
- * what the loader stores is always a string, so every consumer sees one shape). */
39
- export declare function defineRoutine<const S extends readonly string[] = readonly []>(routine: DefineRoutineOptions<S>): Routine;
40
- /** A loaded routine: its authored fields plus the name derived from its filename (authoritative). */
41
- export interface LoadedRoutine extends Routine {
42
- name: string;
43
- }
@@ -1,32 +0,0 @@
1
- /**
2
- * Routine authoring: `defineRoutine`.
3
- *
4
- * A ROUTINE IS THE UNIT OF WORK, and the only named one in the system: a prompt the definition owns, addressed by
5
- * name. `cron` is a FIELD of it, not a second concept — with one, a clock fires it; without one, it is reached by
6
- * name alone (`POST /run`).
7
- *
8
- * WHAT IT IS NOT: a wake-up. The agent can schedule work for itself too (the `wake` tool, schedule/wakeups.ts), and
9
- * conceptually that is the same idea — work to be done later. Every operational difference between them follows
10
- * from ONE root: a routine is written in the DEFINITION (versioned, reviewed, shipped with the image, addressable
11
- * by name) and a wake-up is written into the STATE by a running agent (minted id, cancellable, aimed back at the
12
- * conversation it came from, erased by the next release if it were a definition file). Code and data.
13
- *
14
- * A `prompt` may be a function of the file's declared `secrets` — the only reason such a file ever read the
15
- * environment (src/declared-secrets.ts).
16
- */
17
- import { secretValues } from "../declared-secrets.js";
18
- /**
19
- * WHICH conversation a routine's turns belong to: all of them, so a routine shares one continuing conversation —
20
- * and without depending on engine session storage. The ONE spelling of it: the clock invokes through it,
21
- * `fastagent routine run` reproduces a run with it, `POST /run` reports it as where to look, and
22
- * `routine history` prints the command that opens it.
23
- */
24
- export function routineSession(name) {
25
- return `routine:${name}`;
26
- }
27
- /** Type + completion for a routine file, and the ONE place a prompt builder is resolved (at load:
28
- * what the loader stores is always a string, so every consumer sees one shape). */
29
- export function defineRoutine(routine) {
30
- const { prompt, ...rest } = routine;
31
- return { ...rest, prompt: typeof prompt === "function" ? prompt(secretValues(routine.secrets)) : prompt };
32
- }
@@ -1,55 +0,0 @@
1
- import type { Agent } from "../agent.ts";
2
- import { type LoadedRoutine } from "./routine.ts";
3
- /**
4
- * The 404 for a name this deployment does not declare — drift: a caller outliving the thing it calls. The names are
5
- * listed so an operator can see whether it is a typo or a stale job without shelling in. The caller's name is CLIPPED
6
- * before it goes back out: listing this deployment's own names is deliberate, quoting an unauthenticated caller's
7
- * 4 KiB of body is not (`refuseNonJsonBody` states the same rule for the same table).
8
- */
9
- export declare function unknownRoutine(name: string, routines: readonly LoadedRoutine[]): Response;
10
- /** The reply shape both doors answer with — one for the route, one for a host that has no route (AgentCore). */
11
- export interface RoutineRunReply {
12
- name: string;
13
- /** WHERE TO LOOK: the turn's output lives in this session's journal (`fastagent routine history`, `/control/*`). */
14
- session: string;
15
- ran: boolean;
16
- /** Present when `ran: false` — today, the previous turn still holding this routine's one session. */
17
- reason?: string;
18
- /** Present when the turn RAN and did not finish. */
19
- failed?: string;
20
- ms: number;
21
- }
22
- /**
23
- * Run one routine and say what happened. THE one implementation, because there are two doors and only one
24
- * contract: `POST /run` on any host that publishes routes, and AgentCore's IAM-gated `routine-run` envelope on the
25
- * host that publishes none. A second copy is how the two would come to answer differently.
26
- */
27
- export declare function runRoutineByName(agent: Agent, routine: LoadedRoutine): Promise<RoutineRunReply>;
28
- /**
29
- * Build the handler for `GET /routines` — what a caller may ask for by name.
30
- *
31
- * DISCOVERY, because the alternative was a 404. The names were already public: `POST /run` lists them when a caller
32
- * gets one wrong, which is deliberate (an operator has to tell a typo from a stale caller) — so the only thing this
33
- * adds is not having to guess wrong first. "Expose a declared prompt as an API" is half a sentence without it.
34
- *
35
- * NAMES AND SCHEDULES, NEVER PROMPTS. What a routine SAYS is the definition's content; handing it to an
36
- * unauthenticated caller would publish the agent's behaviour, which is the one thing keeping the prompt out of the
37
- * request body was for. `cron` is here because it answers "will this run on its own, or is my clock the only one?",
38
- * which is a caller's question, not the definition's secret.
39
- *
40
- * Mounted exactly where `POST /run` is: it describes that route, so listing names a caller cannot use would be a
41
- * catalogue of nothing.
42
- */
43
- export declare function createRoutineListHandler(options: {
44
- routines: readonly LoadedRoutine[];
45
- }): ((req: Request) => Promise<Response>) | undefined;
46
- /**
47
- * Build the handler for `POST /run`, bound to what this serve loaded.
48
- *
49
- * `undefined` when the definition declares nothing runnable: a route that can only ever answer 404 is not a route,
50
- * and the startup report names what is actually mounted.
51
- */
52
- export declare function createRunHandler(options: {
53
- agent: Agent;
54
- routines: readonly LoadedRoutine[];
55
- }): ((req: Request) => Promise<Response>) | undefined;
@@ -1,146 +0,0 @@
1
- /**
2
- * `POST /run` — **an API**: run a unit of work this definition declares, by name.
3
- *
4
- * NOT A TIME TRIGGER, and the difference is the whole design. Occurrence semantics — a slot, a claim, a fire
5
- * history, an overlap policy — exist exactly where fastagent OWNS the clock: the resident loop in `dev`/`start`,
6
- * and AgentCore, where `deploy` writes the EventBridge rule, injects the instant and relays it through an ingress
7
- * secret (channels/agentcore.ts). Both of those know which occurrence a run is for because they produced it.
8
- *
9
- * This route is the other case: somebody else's clock, CI job, button or script. It cannot be told which occurrence
10
- * it means, and pretending otherwise was measurably worse than admitting it. The attempt cost four rounds — an
11
- * instant dated ahead poisoned the claim gate permanently, one off the grid minted a claim no occurrence would ever
12
- * match, an old one replayed history a turn at a time, and the grid arithmetic all three needed was ~6ms of
13
- * synchronous CPU per request on an anonymous route. A platform cron drifting a few minutes then lost an occurrence
14
- * outright (Railway documents "a few minutes" of variance; measured: 3 fires, 2 turns).
15
- *
16
- * So the contract is the one an API has:
17
- *
18
- * - the body names WHAT to run and nothing else — the prompt stays in the definition, which is the whole reason
19
- * this exists beside `POST /invoke`, whose caller brings its own text and therefore its own behaviour
20
- * - the reply says what happened and WHERE TO LOOK (the session the turn ran in). Retry policy is the caller's,
21
- * because only the caller knows whether its work tolerates running twice
22
- * - it is exactly as exposed as `POST /invoke`: unauthenticated, full tool authority, `http.invoke: false` and a
23
- * gateway in front are the answers. The framework authenticates nothing (docs/design/session-control.md §14)
24
- *
25
- * AND NO IDEMPOTENCY KEY. A key would deduplicate the CALL, not the WORK: a turn that sent one message and then died
26
- * would answer a keyed retry with "already ran" — safety exactly where it is absent, which is the same reason a failed
27
- * fire is not retried (schedule/scheduler.ts). What makes a retry safe is idempotent WORK, which only the author can
28
- * arrange.
29
- *
30
- * NAME IN THE BODY, not the path. A declared name is a filename (`每日简报`, `my schedule` are both legal), and a
31
- * path segment would mean percent-encoding it — the cost the control plane pays for session ids and this route has
32
- * no reason to. It also keeps the shape of `POST /invoke`, whose scope rides in the body for the same reason.
33
- */
34
- import * as Effect from "effect/Effect";
35
- import { readBodyCapped, refuseNonJsonBody } from "../channels/body.js";
36
- import { text } from "../channels/respond.js";
37
- import { routineSession } from "./routine.js";
38
- import { runTurn } from "./scheduler.js";
39
- /** A trigger body is a name; the cap only has to admit that. */
40
- const MAX_RUN_BODY_BYTES = 4 * 1024;
41
- /**
42
- * How much of a caller's `name` a 404 will quote back — the ONE thing this route echoes, because telling a typo
43
- * from a stale caller needs the name and nothing else does. Long enough to recognise one, short enough not to be a
44
- * page.
45
- */
46
- const MAX_ECHOED_NAME = 64;
47
- /**
48
- * The 404 for a name this deployment does not declare — drift: a caller outliving the thing it calls. The names are
49
- * listed so an operator can see whether it is a typo or a stale job without shelling in. The caller's name is CLIPPED
50
- * before it goes back out: listing this deployment's own names is deliberate, quoting an unauthenticated caller's
51
- * 4 KiB of body is not (`refuseNonJsonBody` states the same rule for the same table).
52
- */
53
- export function unknownRoutine(name, routines) {
54
- return text(`no declared work named "${name.slice(0, MAX_ECHOED_NAME)}" (this deployment has: ${routines
55
- .map((r) => r.name)
56
- .join(", ")})\n`, 404);
57
- }
58
- /** The Effect boundary, in one place: the turn runs, and its outcome is what the caller reads. */
59
- const runOnce = (agent, routine) => Effect.runPromise(runTurn(agent, routine.name, routineSession(routine.name), routine.prompt));
60
- /**
61
- * Run one routine and say what happened. THE one implementation, because there are two doors and only one
62
- * contract: `POST /run` on any host that publishes routes, and AgentCore's IAM-gated `routine-run` envelope on the
63
- * host that publishes none. A second copy is how the two would come to answer differently.
64
- */
65
- export async function runRoutineByName(agent, routine) {
66
- const session = routineSession(routine.name);
67
- const { busy, failed, ms } = await runOnce(agent, routine);
68
- // BUSY IS NOT A FAILURE and it is the one "did not run" this has: a declared unit of work has ONE session, so a
69
- // call arriving while the previous turn holds it is refused by that session. Reported as itself, with what the
70
- // caller needs in order to decide — try later — rather than as an error it would retry blindly.
71
- if (busy) {
72
- return {
73
- name: routine.name,
74
- session,
75
- ran: false,
76
- reason: `the previous turn of "${routine.name}" is still running`,
77
- ms,
78
- };
79
- }
80
- return { name: routine.name, session, ran: true, ...(failed !== undefined ? { failed } : {}), ms };
81
- }
82
- /**
83
- * Build the handler for `GET /routines` — what a caller may ask for by name.
84
- *
85
- * DISCOVERY, because the alternative was a 404. The names were already public: `POST /run` lists them when a caller
86
- * gets one wrong, which is deliberate (an operator has to tell a typo from a stale caller) — so the only thing this
87
- * adds is not having to guess wrong first. "Expose a declared prompt as an API" is half a sentence without it.
88
- *
89
- * NAMES AND SCHEDULES, NEVER PROMPTS. What a routine SAYS is the definition's content; handing it to an
90
- * unauthenticated caller would publish the agent's behaviour, which is the one thing keeping the prompt out of the
91
- * request body was for. `cron` is here because it answers "will this run on its own, or is my clock the only one?",
92
- * which is a caller's question, not the definition's secret.
93
- *
94
- * Mounted exactly where `POST /run` is: it describes that route, so listing names a caller cannot use would be a
95
- * catalogue of nothing.
96
- */
97
- export function createRoutineListHandler(options) {
98
- const { routines } = options;
99
- if (routines.length === 0)
100
- return undefined;
101
- const body = routines.map((r) => ({
102
- name: r.name,
103
- ...(r.cron !== undefined ? { cron: r.cron } : {}),
104
- ...(r.tz !== undefined ? { tz: r.tz } : {}),
105
- }));
106
- // NO METHOD CHECK. The router dispatches `GET /routines` here and nothing else, so the only thing such a check
107
- // could reach is HEAD — which `channels/serve.ts` deliberately answers with the GET route, the same way
108
- // `GET /health` is HEAD-probeable. Checking would break that and buy nothing.
109
- return async () => Response.json(body);
110
- }
111
- /**
112
- * Build the handler for `POST /run`, bound to what this serve loaded.
113
- *
114
- * `undefined` when the definition declares nothing runnable: a route that can only ever answer 404 is not a route,
115
- * and the startup report names what is actually mounted.
116
- */
117
- export function createRunHandler(options) {
118
- const { agent, routines } = options;
119
- if (routines.length === 0)
120
- return undefined;
121
- return async (req) => {
122
- if (req.method !== "POST")
123
- return text("POST only\n", 405);
124
- const wrongType = refuseNonJsonBody(req);
125
- if (wrongType)
126
- return wrongType;
127
- const body = await readBodyCapped(req, MAX_RUN_BODY_BYTES);
128
- if ("tooLarge" in body)
129
- return text("body too large\n", 413);
130
- let payload;
131
- try {
132
- payload = JSON.parse(body.text);
133
- }
134
- catch {
135
- return text("invalid json\n", 400);
136
- }
137
- const { name } = (payload ?? {});
138
- if (typeof name !== "string" || name === "") {
139
- return text('need { "name": string } — e.g. {"name":"daily"}\n', 400);
140
- }
141
- const routine = routines.find((r) => r.name === name);
142
- if (!routine)
143
- return unknownRoutine(name, routines);
144
- return Response.json(await runRoutineByName(agent, routine));
145
- };
146
- }