@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
@@ -1,5 +1,4 @@
1
1
  /** `fastagent deploy agentcore` — the AWS Bedrock AgentCore deploy PLAN, computed from the resolved definition. */
2
- import { createHash } from "node:crypto";
3
2
  import { readFileSync } from "node:fs";
4
3
  import { MAX_WEBHOOK_BODY_BYTES } from "../../channels/agentcore-limits.js";
5
4
  import { SECRETS_DIRNAME } from "../../paths.js";
@@ -28,6 +27,13 @@ export const FORWARDER_FILE = "lambda/index.js";
28
27
  export function wakeAlarmPrefix(name) {
29
28
  return `fa-${name}-wk-`;
30
29
  }
30
+ /**
31
+ * Where the forwarder puts the recurring schedule for each `schedules/` file. Set at runtime by the container (the
32
+ * set follows edits), so like the wake alarms it is no stack resource, and this prefix is the handle on them.
33
+ */
34
+ export function recurringSchedulePrefix(name) {
35
+ return `fa-${name}-sc-`;
36
+ }
31
37
  /** Account-suffixed artifact bucket for S3's global namespace. */
32
38
  export function deploymentBucketName(name, account) {
33
39
  return `fa-${name}-${account}`;
@@ -56,9 +62,9 @@ export const GENERATED_TEMPLATE_MARKER = "# Generated by `fastagent deploy agent
56
62
  export function isGeneratedAgentcoreTemplate(content) {
57
63
  return content.startsWith(GENERATED_TEMPLATE_MARKER);
58
64
  }
59
- /** Deployment base name from the workspace basename — the ONE mapping used to find its stack later. */
60
- export function agentcoreName(workspaceBasename) {
61
- return (workspaceBasename
65
+ /** Deployment base name from the agent directory's name — the ONE mapping used to find its stack later. */
66
+ export function agentcoreName(agentDirName) {
67
+ return (agentDirName
62
68
  .toLowerCase()
63
69
  .replace(/[^a-z0-9-]+/g, "-")
64
70
  .replace(/^-+|-+$/g, "") || "agent");
@@ -105,81 +111,12 @@ export function runtimeLogGroupPrefix(runtimeOrName) {
105
111
  export function forwarderLogGroup(name) {
106
112
  return `/aws/lambda/${forwarderFunctionName(name)}`;
107
113
  }
108
- /** The ONE fixed ingress session id (webhooks + routine fires). */
114
+ /** The `invoke-agent-runtime` payload IAM may send: a probe, answered `{"ok":true}` once the definition opened. */
115
+ export const PROBE_PAYLOAD = JSON.stringify({ kind: "probe" });
116
+ /** The ONE fixed ingress session id (webhooks + schedule fires). */
109
117
  export function ingressSessionId(name) {
110
118
  return `fastagent-ingress-${name}`.padEnd(33, "0").slice(0, 128);
111
119
  }
112
- /** Remap ONE day-of-week field from standard cron numbering (0–7, 0/7 = Sunday) to EventBridge's (1–7, 1 = Sunday). */
113
- function mapDowField(dow) {
114
- const items = [];
115
- for (const item of dow.split(",")) {
116
- const slash = item.split("/");
117
- if (slash.length > 2 || slash.some((part) => part === "")) {
118
- return { error: `malformed day-of-week token "${item}"` };
119
- }
120
- const [body, step] = slash;
121
- if (step !== undefined && !/^\d+$/.test(step))
122
- return { error: `malformed day-of-week step "${item}"` };
123
- let mapped;
124
- if (body === "*") {
125
- mapped = "*";
126
- }
127
- else {
128
- const endpoints = body.split("-");
129
- if (endpoints.length > 2 || endpoints.some((part) => part === "")) {
130
- return { error: `malformed day-of-week token "${item}"` };
131
- }
132
- const remapped = endpoints.map((p) => (/^\d+$/.test(p) ? String((Number(p) % 7) + 1) : p));
133
- if (remapped.length === 2 &&
134
- remapped.every((p) => /^\d+$/.test(p)) &&
135
- Number(remapped[0]) > Number(remapped[1])) {
136
- return {
137
- error: `day-of-week range "${body}" wraps across the week under EventBridge numbering (1 = Sunday) — ` +
138
- `split it into an explicit list`,
139
- };
140
- }
141
- mapped = remapped.join("-");
142
- }
143
- items.push(step !== undefined ? `${mapped}/${step}` : mapped);
144
- }
145
- return { value: items.join(",") };
146
- }
147
- /** Translate a 5-field cron into EventBridge Scheduler's `cron(m h dom mon dow *)`, or say why it can't be. */
148
- export function toEventBridgeCron(cron) {
149
- const fields = cron.trim().split(/\s+/);
150
- if (fields.length !== 5) {
151
- return { error: `EventBridge supports 5-field cron only (got ${fields.length} fields)` };
152
- }
153
- const [min, hour, dom, mon, dow] = fields;
154
- if (/[L#]/i.test(dow) || /[L#]/i.test(dom)) {
155
- return { error: "L/# day forms don't translate to EventBridge numbering — set this schedule up manually" };
156
- }
157
- // `?` FIRST, and not as a synonym for `*`.
158
- if (dom === "?" || dow === "?") {
159
- return { expression: `cron(${min} ${hour} * ${mon} ? *)` };
160
- }
161
- if (dom !== "*" && dow !== "*") {
162
- return {
163
- error: "restricting BOTH day-of-month and day-of-week (cron OR semantics) is not expressible in EventBridge",
164
- };
165
- }
166
- if (dow === "*") {
167
- return { expression: `cron(${min} ${hour} ${dom} ${mon} ? *)` };
168
- }
169
- const mapped = mapDowField(dow);
170
- if ("error" in mapped)
171
- return mapped;
172
- return { expression: `cron(${min} ${hour} ? ${mon} ${mapped.value} *)` };
173
- }
174
- /** CFN logical id fragment from a schedule name (alphanumeric only, capitalized). */
175
- function logicalId(name) {
176
- const slug = name.replace(/[^a-zA-Z0-9]+/g, "");
177
- return slug.charAt(0).toUpperCase() + slug.slice(1) || "Schedule";
178
- }
179
- /** YAML single-quoted scalar (the one escape: `'` doubles). */
180
- function yamlSingleQuote(value) {
181
- return `'${value.replace(/'/g, "''")}'`;
182
- }
183
120
  /**
184
121
  * The forwarder Lambda source — `forwarder.js` beside this file, the ONE text both the deployment package and the
185
122
  * readable `lambda/index.js` artifact are generated from.
@@ -187,16 +124,8 @@ function yamlSingleQuote(value) {
187
124
  export function forwarderSource() {
188
125
  return readFileSync(new URL("./forwarder.js", import.meta.url), "utf8");
189
126
  }
190
- /** The EventBridge physical name for a schedule. */
191
- export function scheduleResourceName(agent, schedule) {
192
- const prefix = `fa-${agent}-`;
193
- const hash = createHash("sha256").update(schedule).digest("hex").slice(0, 8);
194
- const safe = schedule.replace(/[^0-9A-Za-z\-_.]+/g, "-").replace(/^-+|-+$/g, "");
195
- const room = Math.max(0, 64 - prefix.length - hash.length - 1);
196
- return `${prefix}${safe.slice(0, room)}-${hash}`;
197
- }
198
127
  /** The CloudFormation template — the whole topology in one stack. */
199
- function template(input, translated, topology) {
128
+ function template(input, topology) {
200
129
  const runtimeName = toRuntimeName(input.name);
201
130
  const idleTimeout = input.idleTimeoutSeconds ?? DEFAULT_IDLE_TIMEOUT_SECONDS;
202
131
  const forwarderFnArn = `!Sub arn:aws:lambda:\${AWS::Region}:\${AWS::AccountId}:function:fastagent-${input.name}-forwarder`;
@@ -296,17 +225,9 @@ function template(input, translated, topology) {
296
225
  ` EnvironmentVariables:`,
297
226
  ...envLines,
298
227
  ];
299
- lines.push(``, ` ForwarderRole:`, ` Type: AWS::IAM::Role`, ` Properties:`, ` AssumeRolePolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Principal: { Service: lambda.amazonaws.com }`, ` Action: sts:AssumeRole`, ` ManagedPolicyArns: [arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]`, ` Policies:`, ` - PolicyName: invoke-runtime`, ` PolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Action: bedrock-agentcore:InvokeAgentRuntime`, ` Resource:`, ` - !GetAtt Runtime.AgentRuntimeArn`, ` - !Sub "\${Runtime.AgentRuntimeArn}/*"`, ` - Effect: Allow # wake alarms: mirror pending wake-ups into one-shot schedules`, ` Action: [scheduler:CreateSchedule, scheduler:UpdateSchedule]`, ` Resource: !Sub arn:aws:scheduler:\${AWS::Region}:\${AWS::AccountId}:schedule/default/${wakeAlarmPrefix(input.name)}*`, ` - Effect: Allow # hand the poke schedules their invoke role`, ` Action: iam:PassRole`, ` Resource: !GetAtt WakeSchedulerRole.Arn`, ` - Effect: Allow # self-resolve callback URL for state-URL refresh / wake alarms`, ` Action: lambda:GetFunctionUrlConfig`, ` Resource: ${forwarderFnArn}`, ``, ` Forwarder:`, ` Type: AWS::Lambda::Function`, ` Properties:`, ` FunctionName: ${forwarderFunctionName(input.name)}`, ` Runtime: nodejs22.x`, ` Handler: index.handler`, ` # Webhook ACKs are fast, but routine-fire holds the connection for the WHOLE agent turn`, ` # (claim-before-run means a timeout never double-fires; the turn also continues and is`, ` # audited container-side). EventBridge→Lambda is async, so the long timeout costs nothing.`, ` Timeout: 900`, ` MemorySize: 256`, ` Role: !GetAtt ForwarderRole.Arn`, ` Environment:`, ` Variables:`, ` RUNTIME_ARN: !GetAtt Runtime.AgentRuntimeArn`, ` INGRESS_SESSION_ID: ${ingressSessionId(input.name)}`, ...(topology.webhooks ? [` WEBHOOKS_ENABLED: "1"`] : []), ` WAKE_SECRET: !Ref FastagentWakeSecret`, ` WAKE_ROLE_ARN: !GetAtt WakeSchedulerRole.Arn`, ` WAKE_PREFIX: ${wakeAlarmPrefix(input.name)}`, ` INGRESS_SECRET: !Ref FastagentIngressSecret`, ` MAX_WEBHOOK_BODY_BYTES: "${MAX_WEBHOOK_BODY_BYTES}"`, ` # A content-hashed key makes code changes visible to CloudFormation.`, ` Code:`, ` S3Bucket: !Ref ForwarderBucket`, ` S3Key: !Ref ForwarderS3Key`);
228
+ lines.push(``, ` ForwarderRole:`, ` Type: AWS::IAM::Role`, ` Properties:`, ` AssumeRolePolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Principal: { Service: lambda.amazonaws.com }`, ` Action: sts:AssumeRole`, ` ManagedPolicyArns: [arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]`, ` Policies:`, ` - PolicyName: invoke-runtime`, ` PolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Action: bedrock-agentcore:InvokeAgentRuntime`, ` Resource:`, ` - !GetAtt Runtime.AgentRuntimeArn`, ` - !Sub "\${Runtime.AgentRuntimeArn}/*"`, ` - Effect: Allow # wake alarms: mirror pending wake-ups into one-shot schedules`, ` Action: [scheduler:CreateSchedule, scheduler:UpdateSchedule]`, ` Resource: !Sub arn:aws:scheduler:\${AWS::Region}:\${AWS::AccountId}:schedule/default/${wakeAlarmPrefix(input.name)}*`, ` - Effect: Allow # schedules: one recurring schedule per schedules/ file, and delete what is gone`, ` Action: [scheduler:CreateSchedule, scheduler:UpdateSchedule, scheduler:GetSchedule, scheduler:DeleteSchedule]`, ` Resource: !Sub arn:aws:scheduler:\${AWS::Region}:\${AWS::AccountId}:schedule/default/${recurringSchedulePrefix(input.name)}*`, ` - Effect: Allow # find the recurring schedules to delete (ListSchedules takes no resource)`, ` Action: scheduler:ListSchedules`, ` Resource: "*"`, ` - Effect: Allow # hand the alarm schedules their invoke role`, ` Action: iam:PassRole`, ` Resource: !GetAtt WakeSchedulerRole.Arn`, ` - Effect: Allow # self-resolve callback URL for state-URL refresh / wake alarms`, ` Action: lambda:GetFunctionUrlConfig`, ` Resource: ${forwarderFnArn}`, ``, ` Forwarder:`, ` Type: AWS::Lambda::Function`, ` Properties:`, ` FunctionName: ${forwarderFunctionName(input.name)}`, ` Runtime: nodejs22.x`, ` Handler: index.handler`, ` # Webhook ACKs are fast, but schedule-fire holds the connection for the WHOLE agent turn`, ` # (claim-before-run means a timeout never double-fires; the turn also continues and is`, ` # audited container-side). EventBridge→Lambda is async, so the long timeout costs nothing.`, ` Timeout: 900`, ` MemorySize: 256`, ` Role: !GetAtt ForwarderRole.Arn`, ` Environment:`, ` Variables:`, ` RUNTIME_ARN: !GetAtt Runtime.AgentRuntimeArn`, ` INGRESS_SESSION_ID: ${ingressSessionId(input.name)}`, ...(topology.webhooks ? [` WEBHOOKS_ENABLED: "1"`] : []), ` WAKE_SECRET: !Ref FastagentWakeSecret`, ` WAKE_ROLE_ARN: !GetAtt WakeSchedulerRole.Arn`, ` WAKE_PREFIX: ${wakeAlarmPrefix(input.name)}`, ` SCHEDULE_PREFIX: ${recurringSchedulePrefix(input.name)}`, ` INGRESS_SECRET: !Ref FastagentIngressSecret`, ` MAX_WEBHOOK_BODY_BYTES: "${MAX_WEBHOOK_BODY_BYTES}"`, ` # A content-hashed key makes code changes visible to CloudFormation.`, ` Code:`, ` S3Bucket: !Ref ForwarderBucket`, ` S3Key: !Ref ForwarderS3Key`);
300
229
  lines.push(``, ` ForwarderUrl:`, ` Type: AWS::Lambda::Url`, ` Properties:`, ` TargetFunctionArn: !GetAtt Forwarder.Arn`, ` # NONE is deliberate: webhook callers (Telegram/Feishu) cannot SigV4-sign. Authenticity is`, ` # verified downstream by each channel (secret token / signature), exactly as on every host.`, ` AuthType: NONE`, ``, ` ForwarderUrlPermission:`, ` Type: AWS::Lambda::Permission`, ` Properties:`, ` FunctionName: !Ref Forwarder`, ` Action: lambda:InvokeFunctionUrl`, ` Principal: "*"`, ` FunctionUrlAuthType: NONE`, ``, ` # Function URLs created after Oct 2025 require lambda:InvokeFunction IN ADDITION to`, ` # lambda:InvokeFunctionUrl for public (NONE) access — with only the first, every request 403s`, ` # (found by the first real deploy). InvokedViaFunctionUrl scopes it to URL traffic: without it`, ` # the bare * principal would also let any AWS principal call the Lambda API directly, bypassing`, ` # the Function URL event shape to forge internal events.`, ` ForwarderInvokePermission:`, ` Type: AWS::Lambda::Permission`, ` Properties:`, ` FunctionName: !Ref Forwarder`, ` Action: lambda:InvokeFunction`, ` Principal: "*"`, ` InvokedViaFunctionUrl: true`);
301
- lines.push(``, ` # The role the wake-poke schedules assume to invoke the forwarder. Its policy names the`, ` # function by CONSTRUCTED arn (not !Ref) — the forwarder's env references this role, so a`, ` # !Ref back would be a circular dependency.`, ` WakeSchedulerRole:`, ` Type: AWS::IAM::Role`, ` Properties:`, ` AssumeRolePolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Principal: { Service: scheduler.amazonaws.com }`, ` Action: sts:AssumeRole`, ` Condition:`, ` StringEquals: { aws:SourceAccount: !Ref AWS::AccountId }`, ` Policies:`, ` - PolicyName: poke-forwarder`, ` PolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Action: lambda:InvokeFunction`, ` Resource: ${forwarderFnArn}`);
302
- if (translated.length > 0) {
303
- lines.push(``, ` SchedulerRole:`, ` Type: AWS::IAM::Role`, ` Properties:`, ` AssumeRolePolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Principal: { Service: scheduler.amazonaws.com }`, ` Action: sts:AssumeRole`, ` Condition:`, ` StringEquals: { aws:SourceAccount: !Ref AWS::AccountId }`, ` Policies:`, ` - PolicyName: fire-forwarder`, ` PolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Action: lambda:InvokeFunction`, ` Resource: !GetAtt Forwarder.Arn`);
304
- for (const { fact, expression } of translated) {
305
- lines.push(``, ` Schedule${logicalId(fact.name)}:`, ` Type: AWS::Scheduler::Schedule`, ` Properties:`, ` Name: ${scheduleResourceName(input.name, fact.name)}`, ` ScheduleExpression: ${expression}`, ` ScheduleExpressionTimezone: ${fact.tz ?? "Etc/UTC"}`, ` FlexibleTimeWindow: { Mode: "OFF" }`, ` Target:`, ` Arn: !GetAtt Forwarder.Arn`, ` RoleArn: !GetAtt SchedulerRole.Arn`, ` # <aws.scheduler.scheduled-time> is the clock's NAME for this occurrence: EventBridge repeats it`, ` # byte-identical on every redelivery, which is what makes the container's dedup work.`, ` Input: ${yamlSingleQuote(JSON.stringify({
306
- scheduleFire: { name: fact.name, occurrence: "<aws.scheduler.scheduled-time>" },
307
- }))}`);
308
- }
309
- }
230
+ lines.push(``, ` # The role the alarm schedules (wake pokes and schedule fires) assume to invoke the forwarder. Its policy names the`, ` # function by CONSTRUCTED arn (not !Ref) — the forwarder's env references this role, so a`, ` # !Ref back would be a circular dependency.`, ` WakeSchedulerRole:`, ` Type: AWS::IAM::Role`, ` Properties:`, ` AssumeRolePolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Principal: { Service: scheduler.amazonaws.com }`, ` Action: sts:AssumeRole`, ` Condition:`, ` StringEquals: { aws:SourceAccount: !Ref AWS::AccountId }`, ` Policies:`, ` - PolicyName: poke-forwarder`, ` PolicyDocument:`, ` Version: "2012-10-17"`, ` Statement:`, ` - Effect: Allow`, ` Action: lambda:InvokeFunction`, ` Resource: ${forwarderFnArn}`);
310
231
  lines.push(``, `Outputs:`, ` RuntimeArn:`, ` Value: !GetAtt Runtime.AgentRuntimeArn`);
311
232
  lines.push(` ForwarderUrl:`, ` Value: !GetAtt ForwarderUrl.FunctionUrl`);
312
233
  return `${lines.join("\n")}\n`;
@@ -316,40 +237,17 @@ export function planAgentcoreDeploy(input) {
316
237
  const { name, channels } = input;
317
238
  const stack = agentcoreStackName(name);
318
239
  const repo = agentcoreRepoName(name);
319
- const prefix = input.agentPrefix;
320
- // Translate every schedule; the ones EventBridge cannot express become explicit runbook warnings.
321
- const translated = [];
322
- const untranslatable = [];
323
- for (const fact of input.schedules) {
324
- const result = toEventBridgeCron(fact.cron);
325
- if ("expression" in result)
326
- translated.push({ fact, expression: result.expression });
327
- else
328
- untranslatable.push({ name: fact.name, reason: result.error });
329
- }
330
- // Identifier collisions: the author-side → AWS-side name mappings are lossy (logical ids strip punctuation;
331
- // parameter names collapse underscores), so two DISTINCT legal inputs can land on one CloudFormation key — which
332
- // would generate a silently wrong stack.
333
- const logicalIds = new Map();
334
- for (const { fact } of translated) {
335
- const id = `Schedule${logicalId(fact.name)}`;
336
- const clash = logicalIds.get(id);
337
- if (clash !== undefined) {
338
- throw new Error(`schedules "${clash}" and "${fact.name}" collapse to the same CloudFormation logical id (${id}) — rename one`);
339
- }
340
- logicalIds.set(id, fact.name);
341
- }
342
240
  const topology = agentcoreTopology(input);
343
241
  const artifacts = [
344
- { path: `${prefix}${TEMPLATE_FILE}`, content: template(input, translated, topology) },
345
- { path: `${prefix}${FORWARDER_FILE}`, content: forwarderSource() },
242
+ { path: TEMPLATE_FILE, content: template(input, topology) },
243
+ { path: FORWARDER_FILE, content: forwarderSource() },
346
244
  ...containerArtifacts(input),
347
245
  ];
348
246
  const secrets = input.secrets ?? [];
349
247
  const image = `<account-id>.dkr.ecr.<region>.amazonaws.com/${repo}:<tag>`;
350
248
  const bucketHint = deploymentBucketName(name, "<account-id>");
351
249
  const runbook = [
352
- `# Deploy "${name}" to AWS Bedrock AgentCore. ${prefix}${TEMPLATE_FILE} / Dockerfile(.dockerignore) are generated above.`,
250
+ `# Deploy "${name}" to AWS Bedrock AgentCore. ${TEMPLATE_FILE} / Dockerfile(.dockerignore) are generated above.`,
353
251
  `# Prereqs: AWS CLI v2 with credentials + a region where AgentCore is available, and Docker with buildx`,
354
252
  `# (the image MUST be linux/arm64 — the one host whose build runs on YOUR machine, not remotely).`,
355
253
  ``,
@@ -363,24 +261,25 @@ export function planAgentcoreDeploy(input) {
363
261
  ``,
364
262
  `# 1b. Package the forwarder and upload it. Name the object by its CONTENT (a hash/date):`,
365
263
  `# CloudFormation rolls the function only when the ForwarderS3Key VALUE changes.`,
366
- `(cd ${prefix}lambda && zip -q forwarder.zip index.js)`,
367
- `aws s3 cp ${prefix}lambda/forwarder.zip s3://${bucketHint}/forwarder/<hash>.zip`,
264
+ `(cd lambda && zip -q forwarder.zip index.js)`,
265
+ `aws s3 cp lambda/forwarder.zip s3://${bucketHint}/forwarder/<hash>.zip`,
368
266
  ``,
369
267
  `# 2. Build (linux/arm64) + push. Use a UNIQUE tag per deploy (a git sha / date): CloudFormation only`,
370
268
  `# rolls the runtime when the ImageUri VALUE changes — re-pushing the same tag deploys nothing.`,
371
269
  `aws ecr get-login-password | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com`,
372
- `docker buildx build --platform linux/arm64 -f ${prefix}Dockerfile -t ${image} --push .`,
270
+ `docker buildx build --platform linux/arm64 -f Dockerfile -t ${image} --push .`,
373
271
  ``,
374
- `# 3. Deploy the stack (runtime + ingress + schedules in one template).`,
272
+ `# 3. Deploy the stack (runtime + ingress in one template).`,
375
273
  ];
376
274
  if (secrets.length > 0) {
377
275
  runbook.push(`# Variables ride ONE NoEcho parameter, FastagentEnv: base64 of a JSON object {"NAME": "value", …},`, `# split every ${CARRIER_CHUNK_SIZE} chars across FastagentEnv, FastagentEnv2 … (\`--run\` builds it):`, ...secrets.map((s) => `# ${s.name}: ${s.hint}`));
378
276
  }
379
- const wakeSecretHint = " FastagentWakeSecret=<any random string>";
277
+ const wakeSecretHint = " FastagentWakeSecret=<any random string> FastagentIngressSecret=<another random string>";
380
278
  runbook.push(`# FastagentWakeSecret: the wake-alarm shared secret — any random string (\`--run\` mints one)`);
381
- runbook.push(`aws cloudformation deploy --stack-name ${stack} --template-file ${prefix}${TEMPLATE_FILE} \\`, ` --capabilities CAPABILITY_IAM \\`, ` --parameter-overrides ImageUri=${image} ForwarderBucket=${bucketHint} ForwarderS3Key=forwarder/<hash>.zip${secrets.length > 0 ? " FastagentEnv=<base64 JSON>" : ""}${wakeSecretHint}`, ``, `# 4. Read the outputs (the runtime ARN + callback URL; it serves webhooks only when configured):`, `aws cloudformation describe-stacks --stack-name ${stack} --query "Stacks[0].Outputs"`, ``, `# 5. Tail the Runtime's application stdout/stderr (same fastagent messages + log level as locally).`, `# Discovery resolves the per-endpoint log group from the stack's RuntimeArn:`, `fastagent logs agentcore --follow`, `# The ingress transport is a separate Lambda and therefore a separate log source:`, `fastagent logs agentcore --source forwarder --follow`, ``, `# 6. Set a log retention period on EVERY group this stack writes to. Each is created by the service that`, `# writes it, not by this template, and CloudWatch keeps log data indefinitely by default — which is`, `# forever-billed storage, and the logs are where WHY a scheduled turn failed is recorded. Logs are the`, `# ONE state path this host does not reclaim on its own.`, `aws logs put-retention-policy --log-group-name <the group \`fastagent logs agentcore\` resolves> --retention-in-days 14`, `# The forwarder is a separate Lambda, so its group is separate and defaults the same way:`, `aws logs put-retention-policy --log-group-name ${forwarderLogGroup(input.name)} --retention-in-days 14`);
279
+ runbook.push(`# FastagentIngressSecret: what proves an envelope came from the forwarder — another random string, kept for the activation below`);
280
+ runbook.push(`aws cloudformation deploy --stack-name ${stack} --template-file ${TEMPLATE_FILE} \\`, ` --capabilities CAPABILITY_IAM \\`, ` --parameter-overrides ImageUri=${image} ForwarderBucket=${bucketHint} ForwarderS3Key=forwarder/<hash>.zip${secrets.length > 0 ? " FastagentEnv=<base64 JSON>" : ""}${wakeSecretHint}`, ``, `# 4. Read the outputs (the runtime ARN + callback URL; it serves webhooks only when configured):`, `aws cloudformation describe-stacks --stack-name ${stack} --query "Stacks[0].Outputs"`, ``, `# 5. Tail the Runtime's application stdout/stderr (same fastagent messages + log level as locally).`, `# Discovery resolves the per-endpoint log group from the stack's RuntimeArn:`, `fastagent logs agentcore --follow`, `# The ingress transport is a separate Lambda and therefore a separate log source:`, `fastagent logs agentcore --source forwarder --follow`, ``, `# 6. Set a log retention period on EVERY group this stack writes to. Each is created by the service that`, `# writes it, not by this template, and CloudWatch keeps log data indefinitely by default — which is`, `# forever-billed storage, and the logs are where WHY a scheduled turn failed is recorded. Logs are the`, `# ONE state path this host does not reclaim on its own.`, `aws logs put-retention-policy --log-group-name <the group \`fastagent logs agentcore\` resolves> --retention-in-days 14`, `# The forwarder is a separate Lambda, so its group is separate and defaults the same way:`, `aws logs put-retention-policy --log-group-name ${forwarderLogGroup(input.name)} --retention-in-days 14`);
382
281
  if (input.boxLogin) {
383
- runbook.push(``, `# Model auth: after EVERY deploy and after 14 idle days (each storage reset wipes the last login),`, `# log the runtime in to ${input.boxLogin} from this workspace — before pointing any webhook at it:`, `${deploymentLoginCommand("agentcore", input.boxLogin)}`);
282
+ runbook.push(``, `# Model auth: after EVERY deploy and after 14 idle days (each storage reset wipes the last login),`, `# log the runtime in to ${input.boxLogin} from the agent directory — before pointing any webhook at it:`, `${deploymentLoginCommand("agentcore", input.boxLogin)}`);
384
283
  }
385
284
  // Post-deploy webhook registration — the shared channel-ingress steps, pointed at the forwarder's Function URL
386
285
  // (read from the stack outputs).
@@ -392,11 +291,8 @@ export function planAgentcoreDeploy(input) {
392
291
  }
393
292
  if (post.length > 0)
394
293
  runbook.push(``, ...post);
395
- for (const u of untranslatable) {
396
- runbook.push(``, `# WARNING: schedule "${u.name}" has NO EventBridge rule — ${u.reason}.`, `# It will NOT fire on this deployment until you create an equivalent trigger yourself.`);
397
- }
398
- runbook.push(``, `# Wake-ups: the agent's own follow-up turns (the wake tool) are EventBridge-backed — each pending wake-up is mirrored`, `# (via the forwarder, authenticated by FastagentWakeSecret) into a self-deleting one-shot`, `# schedule (fa-${name}-wk-*) that wakes the container at the right instant. Reliable even when`, `# the compute is reclaimed. The forwarder supplies the callback URL; use the deployment's`, `# fixed runtime session id for programmatic calls too.`);
399
- runbook.push(``, `# Invoke the agent programmatically (reuse the deployment session; conversations remain separate):`, `aws bedrock-agentcore invoke-agent-runtime --agent-runtime-arn <RuntimeArn> \\`, ` --runtime-session-id "${ingressSessionId(name)}" \\`, ` --payload '{"kind":"invoke","session":"cli","text":"hello"}' --cli-binary-format raw-in-base64-out /dev/stdout`);
400
- runbook.push(``, `# Stop the fixed runtime session after redeploy so the next call uses the new image.`, `# \`--run\` does this automatically. In-flight turns are interrupted.`, `aws bedrock-agentcore stop-runtime-session --agent-runtime-arn <RuntimeArn> \\`, ` --runtime-session-id "${ingressSessionId(name)}"`, ``, `# Redeploy = \`fastagent deploy agentcore\` (a new definition needs a fresh release manifest) + step 1b`, `# (new forwarder key, if its code changed) + step 2 with a NEW tag + step 3.`, `# STATE: ${MOUNT} is managed SessionStorage. It keeps base/ (including unfinished work), .state/`, `# and .secrets/ across compute stop/resume — an idle-reclaimed agent resumes with its memory. AWS`, `# RESETS it on every runtime version update (i.e. every deploy) and after 14 idle days, so a deploy`, `# replaces the state along with the image: sessions, channel state and pending wake-ups start blank.`, `# A provider API key in the value file travels with every deploy; a login on the runtime survives neither reset.`, `# Cross-deploy memory needs EFS or S3 Files, which are VPC-only (a NAT gateway for model/channel`, `# egress, ~$33/mo standing): use \`deploy fly\` or \`deploy railway\` for a real volume instead.`, `# Keep one runtime writer per workspace; use the fixed runtime session id printed above for every entry point.`);
401
- return { artifacts, runbook, untranslatableSchedules: untranslatable, topology };
294
+ runbook.push(``, `# Schedules and wake-ups are EventBridge-backed: the container mirrors (via the forwarder, authenticated by`, `# FastagentWakeSecret) each schedule into a recurring EventBridge schedule (${recurringSchedulePrefix(name)}*) and each pending`, `# wake-up into a self-deleting one-shot (${wakeAlarmPrefix(name)}*), which wake it even when the compute is reclaimed.`, `# So a schedule written or edited on the runtime takes effect without a deploy. The container sets them only`, `# once an envelope has reached it THROUGH THE FORWARDER, which tells it where the forwarder is; an`, `# invoke-agent-runtime call does not (that door is IAM's, and does not carry it). \`--run\` does this with its`, `# probe. After a manual deploy, do it once, or no schedule fires until a webhook arrives:`, `curl -fsS -X POST "<ForwarderUrl>/__fastagent/probe" -d '{"auth":"<FastagentIngressSecret>"}'`);
295
+ runbook.push(``, `# Check that the deployed agent opens ({"ok":true}); it is reached through its channels, not this call:`, `aws bedrock-agentcore invoke-agent-runtime --agent-runtime-arn <RuntimeArn> \\`, ` --runtime-session-id "${ingressSessionId(name)}" \\`, ` --payload '${PROBE_PAYLOAD}' --cli-binary-format raw-in-base64-out /dev/stdout`);
296
+ runbook.push(``, `# Stop the fixed runtime session after redeploy so the next call uses the new image.`, `# \`--run\` does this automatically. In-flight turns are interrupted.`, `aws bedrock-agentcore stop-runtime-session --agent-runtime-arn <RuntimeArn> \\`, ` --runtime-session-id "${ingressSessionId(name)}"`, ``, `# Redeploy = \`fastagent deploy agentcore\` (a new definition needs a fresh release manifest) + step 1b`, `# (new forwarder key, if its code changed) + step 2 with a NEW tag + step 3.`, `# STATE: ${MOUNT} is managed SessionStorage. It keeps definition/ (with what the agent wrote there), .state/`, `# and .secrets/ across compute stop/resume — an idle-reclaimed agent resumes with its memory. AWS`, `# RESETS it on every runtime version update (i.e. every deploy) and after 14 idle days, so a deploy`, `# replaces the state along with the image: sessions, channel state and pending wake-ups start blank.`, `# A provider API key in the value file travels with every deploy; a login on the runtime survives neither reset.`, `# Cross-deploy memory needs EFS or S3 Files, which are VPC-only (a NAT gateway for model/channel`, `# egress, ~$33/mo standing): use \`deploy fly\` or \`deploy railway\` for a real volume instead.`, `# Keep one runtime writer per agent; use the fixed runtime session id printed above for every entry point.`);
297
+ return { artifacts, runbook, topology };
402
298
  }
@@ -22,7 +22,7 @@ export interface AgentcoreRunPlan {
22
22
  secrets: Record<string, string>;
23
23
  /** Declared names the value file supplies no value for — the run gates on these before any side effect. */
24
24
  missingSecrets: string[];
25
- /** That value file, workspace-relative, so the gate names the file this deploy actually read. */
25
+ /** That value file, agent-dir-relative, so the gate names the file this deploy actually read. */
26
26
  valueFile: string;
27
27
  /** Every declared channel and its ingress — the driver asks which of them have a webhook. */
28
28
  channels: readonly DeclaredChannel[];
@@ -6,6 +6,8 @@ import { Buffer } from "node:buffer";
6
6
  import { CARRIERS, CARRIER_CHUNK_SIZE, CARRIER_MAX_CHUNKS, MOUNT, agentcoreRepoName, agentcoreStackName, carrierChunk, deploymentBucketName, forwarderSource, ingressSessionId, } from "./plan.js";
7
7
  import { zipSingleFile } from "./zip.js";
8
8
  import { encodeCarriedEnv, missingValuesGate } from "../secrets.js";
9
+ /** AWS keys are typed, so a coding agent's user signs the CLI in at a terminal of their own. */
10
+ const AWS_SIGN_IN = "run `aws configure` (or `aws sso login`) in a terminal of your own, where the keys are typed, then re-run";
9
11
  /**
10
12
  * Stack statuses that hold NO agent memory: a create that never succeeded, its rollback, a change set never
11
13
  * executed, or a stack already gone. Everything else — including `UPDATE_ROLLBACK_COMPLETE` and any status AWS adds
@@ -135,11 +137,11 @@ probe = {}) {
135
137
  }));
136
138
  if (!("ok" in identity)) {
137
139
  if ("absent" in identity)
138
- return gate("`aws sts get-caller-identity` found no caller — run `aws configure`");
140
+ return gate(`\`aws sts get-caller-identity\` found no caller — ${AWS_SIGN_IN}`);
139
141
  if (identity.code === 127)
140
142
  return gate(`${identity.unreadable}, then re-run`);
141
143
  // QUOTED: expired token, a missing profile and a proxy that eats STS are three different next actions.
142
- return gate(`no working AWS credentials (${identity.unreadable}) — run \`aws configure\`, then re-run`);
144
+ return gate(`no working AWS credentials (${identity.unreadable}) — ${AWS_SIGN_IN}`);
143
145
  }
144
146
  const { account, principal } = identity.ok;
145
147
  let region = plan.region;
@@ -297,7 +299,8 @@ probe = {}) {
297
299
  }
298
300
  // 6. Build (linux/arm64) + push in one step.
299
301
  log(`building + pushing ${image} (linux/arm64)…`);
300
- const buildArgs = ["buildx", "build", "--platform", "linux/arm64", "-t", image, "--push"];
302
+ // `--pull`: the base image is a floating tag, and a copy cached here may be older than the runtime floor.
303
+ const buildArgs = ["buildx", "build", "--pull", "--platform", "linux/arm64", "-t", image, "--push"];
301
304
  buildArgs.push("-f", plan.dockerfilePath);
302
305
  buildArgs.push(".");
303
306
  if ((await docker(buildArgs)).code !== 0) {
@@ -382,11 +385,11 @@ probe = {}) {
382
385
  }
383
386
  // Verify storage initialization and channel construction before registering webhooks.
384
387
  if (url) {
385
- log("probing the deployed runtime (workspace initialization + channel construction)…");
388
+ log("probing the deployed runtime (storage initialization + channel construction)…");
386
389
  const verdict = await probeRuntime(`${url}${RESERVED_PATHS.probe}`, plan.secrets.FASTAGENT_INGRESS_SECRET ?? "", probe.fetchImpl ?? fetch, probe.timeoutMs, probe.intervalMs);
387
390
  if (!verdict.ok)
388
391
  return gate(verdict.gate);
389
- log("runtime verified (workspace ready, channels constructed)");
392
+ log("runtime verified (storage ready, channels constructed)");
390
393
  }
391
394
  const notLoggedIn = await plan.boxLogin?.run(runtimeArn);
392
395
  if (notLoggedIn) {
@@ -19,7 +19,7 @@ export declare function shellExit(status: string): string | undefined;
19
19
  export declare function openShellChannel(url: string, command: string): BoxChannel;
20
20
  /**
21
21
  * The shell `login --deployment` opens on an AgentCore runtime, on the session its server runs in. `wake` first sends
22
- * that session an IAM `probe`: the runtime prepares its workspace only on an invocation, and after a deploy or an idle
22
+ * that session an IAM `probe`: the runtime prepares its storage only on an invocation, and after a deploy or an idle
23
23
  * reset nothing may have invoked it yet, which would leave the login no agent directory to run in.
24
24
  */
25
25
  export declare function agentcoreShell(runtimeArn: string, sessionId: string, aws: CliRunner): BoxShell;
@@ -21,7 +21,7 @@ import { PassThrough, Writable } from "node:stream";
21
21
  import { SignatureV4 } from "@smithy/signature-v4";
22
22
  import { WebSocket, ping } from "undici";
23
23
  import { awsCli, awsJson } from "./aws-cli.js";
24
- import { MOUNT } from "./plan.js";
24
+ import { MOUNT, PROBE_PAYLOAD } from "./plan.js";
25
25
  const STDIN = 0x00;
26
26
  const STDOUT = 0x01;
27
27
  const STDERR = 0x02;
@@ -167,7 +167,7 @@ export function openShellChannel(url, command) {
167
167
  }
168
168
  /**
169
169
  * The shell `login --deployment` opens on an AgentCore runtime, on the session its server runs in. `wake` first sends
170
- * that session an IAM `probe`: the runtime prepares its workspace only on an invocation, and after a deploy or an idle
170
+ * that session an IAM `probe`: the runtime prepares its storage only on an invocation, and after a deploy or an idle
171
171
  * reset nothing may have invoked it yet, which would leave the login no agent directory to run in.
172
172
  */
173
173
  export function agentcoreShell(runtimeArn, sessionId, aws) {
@@ -178,16 +178,16 @@ export function agentcoreShell(runtimeArn, sessionId, aws) {
178
178
  try {
179
179
  const reply = join(dir, "reply.json");
180
180
  const args = ["bedrock-agentcore", "invoke-agent-runtime", "--agent-runtime-arn", runtimeArn];
181
- args.push("--runtime-session-id", sessionId, "--payload", '{"kind":"probe"}');
181
+ args.push("--runtime-session-id", sessionId, "--payload", PROBE_PAYLOAD);
182
182
  args.push("--cli-binary-format", "raw-in-base64-out", reply);
183
183
  const sent = await awsCli(aws).present(args);
184
184
  if (!("ok" in sent)) {
185
185
  const why = "absent" in sent ? "the runtime is not there" : sent.unreadable;
186
- throw new Error(`could not open the AgentCore runtime's workspace (${why})`);
186
+ throw new Error(`could not open the AgentCore runtime's storage (${why})`);
187
187
  }
188
188
  const answer = await readFile(reply, "utf8");
189
189
  if (!/"ok"\s*:\s*true/.test(answer)) {
190
- throw new Error(`the AgentCore runtime did not open its workspace: ${answer.trim().slice(0, 300)}`);
190
+ throw new Error(`the AgentCore runtime did not open its storage: ${answer.trim().slice(0, 300)}`);
191
191
  }
192
192
  }
193
193
  finally {
@@ -0,0 +1,34 @@
1
+ import type { AgentConfig } from "../harnesses/pi-durable/define.ts";
2
+ /** Whether the deployment serves the API (and whether this deploy gives it its key), and why not when it does not. */
3
+ export type DeploymentApi = {
4
+ served: true;
5
+ generatesKey: boolean;
6
+ } | {
7
+ served: false;
8
+ why: string;
9
+ };
10
+ /**
11
+ * Decide the API for one deploy, writing nothing: a deploy the pre-flight refuses leaves the value file as it was.
12
+ * Turned off, it is off on the deployment too, a key the values or the host still hold included: the serve reads the
13
+ * same setting.
14
+ */
15
+ export declare function deploymentApi(input: {
16
+ config: AgentConfig;
17
+ /** The host serves the API at all: not AgentCore, reached only through `/invocations`. */
18
+ hostServes: boolean;
19
+ values: ReadonlyMap<string, string>;
20
+ }): DeploymentApi;
21
+ /**
22
+ * Give the deployment its key: into the value file, from which it travels with the other values, once the pre-flight
23
+ * passes (a host's own check may still stop this deploy; the key stays for the next). Answers a secrets directory it
24
+ * wrote into that git may track.
25
+ */
26
+ export declare function writeApiKey(agentDir: string): Promise<string | undefined>;
27
+ /**
28
+ * What a deploy says of the API, once the host has said where the deployment is reached (when it knows). The check
29
+ * names the agent's directory when the command runs elsewhere, since that is where `invoke --url` finds the key.
30
+ */
31
+ export declare function apiReport(api: DeploymentApi, where: {
32
+ valueFile: string;
33
+ agentArg: string | undefined;
34
+ }, reachedAt: string | undefined): string[];
@@ -0,0 +1,50 @@
1
+ /**
2
+ * A deployment's Agent API (SPEC.md §9.5, §9.6): served under `/v1` on every host but AgentCore, unless the
3
+ * definition turns it off (`http.api: false`), behind a key `deploy` generates into the value file the first time,
4
+ * which then travels with every other value. And what a deploy reports of it.
5
+ */
6
+ import { randomBytes } from "node:crypto";
7
+ import { API_PREFIX } from "../http/contract.js";
8
+ import { API_KEY_VARIABLE, API_TURNED_OFF, apiKeysFrom, apiTurnedOff } from "../http/server.js";
9
+ import { writeValues } from "../value-file.js";
10
+ /**
11
+ * Decide the API for one deploy, writing nothing: a deploy the pre-flight refuses leaves the value file as it was.
12
+ * Turned off, it is off on the deployment too, a key the values or the host still hold included: the serve reads the
13
+ * same setting.
14
+ */
15
+ export function deploymentApi(input) {
16
+ const { config, hostServes, values } = input;
17
+ if (!hostServes)
18
+ return { served: false, why: "this host reaches the agent only through its own invocations" };
19
+ if (apiTurnedOff(config))
20
+ return { served: false, why: API_TURNED_OFF };
21
+ return { served: true, generatesKey: apiKeysFrom(values.get(API_KEY_VARIABLE)).length === 0 };
22
+ }
23
+ /**
24
+ * Give the deployment its key: into the value file, from which it travels with the other values, once the pre-flight
25
+ * passes (a host's own check may still stop this deploy; the key stays for the next). Answers a secrets directory it
26
+ * wrote into that git may track.
27
+ */
28
+ export async function writeApiKey(agentDir) {
29
+ const key = randomBytes(32).toString("base64url");
30
+ // Named in `overwrite`: a line that holds no key (empty, or only commas) is replaced, not kept as set.
31
+ const { unprotectedSecretsDir } = await writeValues(agentDir, "Agent API", [{ name: API_KEY_VARIABLE, value: key }], [API_KEY_VARIABLE]);
32
+ return unprotectedSecretsDir;
33
+ }
34
+ /**
35
+ * What a deploy says of the API, once the host has said where the deployment is reached (when it knows). The check
36
+ * names the agent's directory when the command runs elsewhere, since that is where `invoke --url` finds the key.
37
+ */
38
+ export function apiReport(api, where, reachedAt) {
39
+ if (!api.served)
40
+ return [`Agent API: not served — ${api.why}`];
41
+ const { valueFile, agentArg } = where;
42
+ const base = reachedAt ?? "<the deployment's URL>";
43
+ return [
44
+ ...(api.generatesKey
45
+ ? [`Agent API: generated ${API_KEY_VARIABLE} in ${valueFile}; it travels with the other values`]
46
+ : []),
47
+ `Agent API: ${base}${API_PREFIX}, behind ${API_KEY_VARIABLE} in ${valueFile}`,
48
+ `check it: fastagent invoke --url ${base} "hello"${agentArg === undefined ? "" : ` ${agentArg}`}`,
49
+ ];
50
+ }
@@ -27,6 +27,12 @@ export interface BoxShell {
27
27
  }
28
28
  /** A host CLI that runs a command on the box itself: `bin ...args(command)`, run from `cwd`. */
29
29
  export declare function processShell(bin: string, args: (command: string) => string[], cwd: string): BoxShell;
30
+ /**
31
+ * Why a box's login cannot be driven from here: the fastagent the agent installed on the box is older than the CLI
32
+ * relaying it, and speaks less of `login --stdio` than this CLI does. Fixed by versions, never by a compatibility path.
33
+ * No quote of either kind: it rides inside the box's shell line, which a host may wrap in single quotes.
34
+ */
35
+ export declare const BOX_CLI_PREDATES: string;
30
36
  /**
31
37
  * The command that logs a deployment in, as every message and runbook names it: with the provider when it is known,
32
38
  * because the model needs THAT one, and a menu invites another.
@@ -19,6 +19,13 @@ export function processShell(bin, args, cwd) {
19
19
  },
20
20
  };
21
21
  }
22
+ /**
23
+ * Why a box's login cannot be driven from here: the fastagent the agent installed on the box is older than the CLI
24
+ * relaying it, and speaks less of `login --stdio` than this CLI does. Fixed by versions, never by a compatibility path.
25
+ * No quote of either kind: it rides inside the box's shell line, which a host may wrap in single quotes.
26
+ */
27
+ export const BOX_CLI_PREDATES = "the fastagent installed in the agent on the box predates the login --stdio this CLI speaks: align the " +
28
+ "@fastagent-sh/fastagent version in the agent package.json with the CLI that deploys it, then redeploy";
22
29
  /**
23
30
  * The command that logs a deployment in, as every message and runbook names it: with the provider when it is known,
24
31
  * because the model needs THAT one, and a menu invites another.
@@ -1,5 +1,5 @@
1
1
  import type { DeployReport } from "./preflight.ts";
2
- /** Workspace-relative paths the build context may hold and the image must not. */
2
+ /** Agent-dir-relative paths the build context may hold and the image must not. */
3
3
  export interface BuildContextPaths {
4
4
  /** The resolved machinery dirs the generated ignore excludes by path (ContainerInput.machineryPaths). */
5
5
  machineryPaths: string[];
@@ -7,15 +7,17 @@ export interface BuildContextPaths {
7
7
  leakCandidates: string[];
8
8
  /** The state root, when it exists inside the context. */
9
9
  stateShips?: string;
10
- /** The node_modules dirs that exist, the agent's and the workspace's. */
10
+ /** `content/`, when it exists: this machine's clones. */
11
+ contentShips?: string;
12
+ /** `context.local.json`, when it exists: the directories of this machine the agent is bound to. */
13
+ bindingsShip?: string;
14
+ /** The agent's node_modules, when it exists. */
11
15
  depDirs: string[];
12
16
  }
13
- export declare function buildContextPaths(workspace: string, agentDir: string, agentPrefix: string, authPath: string): Promise<BuildContextPaths>;
17
+ export declare function buildContextPaths(agentDir: string, authPath: string): Promise<BuildContextPaths>;
14
18
  /** Interrogate BOTH ignore files deploy emits, when the author kept them. */
15
19
  export declare function checkKeptIgnoreFiles(ctx: {
16
- workspace: string;
17
20
  agentDir: string;
18
- agentPrefix: string;
19
21
  force: boolean;
20
22
  paths: BuildContextPaths;
21
23
  }, report: DeployReport): Promise<void>;