@cursor/july 0.1.30 → 0.1.31

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 (392) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +10 -5
  3. package/dist/bin/agent-serve.js +4 -4
  4. package/dist/channels/github/index.d.ts +1 -1
  5. package/dist/channels/github/index.js +1 -1
  6. package/dist/channels/slack/bot-mentions.d.ts +1 -1
  7. package/dist/channels/slack/bot-mentions.d.ts.map +1 -1
  8. package/dist/channels/slack/bot-mentions.js +1 -1
  9. package/dist/channels/slack/eval-directive.js +1 -1
  10. package/dist/channels/slack/external-policy.d.ts +1 -1
  11. package/dist/channels/slack/external-policy.js +1 -1
  12. package/dist/channels/slack/log.d.ts +1 -1
  13. package/dist/channels/slack/log.js +1 -1
  14. package/dist/channels/slack/setup.js +1 -1
  15. package/dist/channels/slack/socket-mode.js +1 -1
  16. package/dist/docs/404.html +3 -3
  17. package/dist/docs/ab.html +11 -11
  18. package/dist/docs/assets/{ab.md.BMCZ6Hd7.js → ab.md.DAQoJ-up.js} +6 -6
  19. package/dist/docs/assets/{ab.md.BMCZ6Hd7.lean.js → ab.md.DAQoJ-up.lean.js} +1 -1
  20. package/dist/docs/assets/{app.Cm4lsMc4.js → app.DigB_9cQ.js} +1 -1
  21. package/dist/docs/assets/building-with-agents.md.CnHqvYDd.js +13 -0
  22. package/dist/docs/assets/{building-with-agents.md.CJCtZCyi.lean.js → building-with-agents.md.CnHqvYDd.lean.js} +1 -1
  23. package/dist/docs/assets/chunks/@localSearchIndexroot.CnFFl07y.js +1 -0
  24. package/dist/docs/assets/chunks/{VPLocalSearchBox.CYUFXspH.js → VPLocalSearchBox.BCMX25Bv.js} +1 -1
  25. package/dist/docs/assets/chunks/{theme.CTjkX9vc.js → theme.BDDWeELx.js} +2 -2
  26. package/dist/docs/assets/concepts.md.DFaQEFkA.js +4 -0
  27. package/dist/docs/assets/concepts.md.DFaQEFkA.lean.js +1 -0
  28. package/dist/docs/assets/deployment.md.9MYBuKM1.js +55 -0
  29. package/dist/docs/assets/deployment.md.9MYBuKM1.lean.js +1 -0
  30. package/dist/docs/assets/{evals.md.DYOjkRCX.js → evals.md.BIUoVZ6X.js} +13 -13
  31. package/dist/docs/assets/evals.md.BIUoVZ6X.lean.js +1 -0
  32. package/dist/docs/assets/{example-agents_approval-buddy.md.DFGBYLcc.js → example-agents_approval-buddy.md.BhEfleVx.js} +4 -4
  33. package/dist/docs/assets/{example-agents_approval-buddy.md.DFGBYLcc.lean.js → example-agents_approval-buddy.md.BhEfleVx.lean.js} +1 -1
  34. package/dist/docs/assets/example-agents_benny.md.2Et1qa8f.js +7 -0
  35. package/dist/docs/assets/{example-agents_bugbot.md.DelIdhxB.js → example-agents_bugbot.md.ByUexi5i.js} +5 -5
  36. package/dist/docs/assets/{example-agents_codebase-wiki.md.DC6sgwn0.js → example-agents_codebase-wiki.md.B4y-7ZVW.js} +6 -6
  37. package/dist/docs/assets/{example-agents_codebase-wiki.md.DC6sgwn0.lean.js → example-agents_codebase-wiki.md.B4y-7ZVW.lean.js} +1 -1
  38. package/dist/docs/assets/{example-agents_codeowners-review.md.Ku_tG2RY.js → example-agents_codeowners-review.md.D6ay4nvf.js} +6 -6
  39. package/dist/docs/assets/{example-agents_codeowners-review.md.Ku_tG2RY.lean.js → example-agents_codeowners-review.md.D6ay4nvf.lean.js} +1 -1
  40. package/dist/docs/assets/{example-agents_concierge.md.4rQTSMXt.js → example-agents_concierge.md.lL8rhYlj.js} +7 -7
  41. package/dist/docs/assets/{example-agents_fsd.md.CzgUrDfi.js → example-agents_fsd.md.DfNKQTHz.js} +5 -5
  42. package/dist/docs/assets/example-agents_index.md.DgGBwckv.js +2 -0
  43. package/dist/docs/assets/example-agents_index.md.DgGBwckv.lean.js +1 -0
  44. package/dist/docs/assets/{example-agents_knowledge-base.md.BPJiVueF.js → example-agents_knowledge-base.md.CzyZ2DCr.js} +5 -5
  45. package/dist/docs/assets/{example-agents_knowledge-base.md.BPJiVueF.lean.js → example-agents_knowledge-base.md.CzyZ2DCr.lean.js} +1 -1
  46. package/dist/docs/assets/example-agents_oncall.md.wFFXXEyW.js +10 -0
  47. package/dist/docs/assets/{example-agents_security-reviewer.md.Dhj_m7_B.js → example-agents_security-reviewer.md.Dkf1gyo6.js} +8 -8
  48. package/dist/docs/assets/example-agents_slack-agent.md.DvgvT4nn.js +5 -0
  49. package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.js +24 -0
  50. package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.lean.js +1 -0
  51. package/dist/docs/assets/{guides_agent-to-agent.md.Bpzgq2Pq.js → guides_agent-to-agent.md.Bmbxy-FA.js} +4 -4
  52. package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.js +9 -0
  53. package/dist/docs/assets/{guides_github.md.DOOCpqsW.js → guides_github.md.R2QlpR75.js} +5 -5
  54. package/dist/docs/assets/{guides_human-in-the-loop.md.DlUqsp1S.js → guides_human-in-the-loop.md.BWvT7UqY.js} +1 -1
  55. package/dist/docs/assets/{guides_mcp-oauth.md.Dd8EgSem.js → guides_mcp-oauth.md.C7G7IykG.js} +5 -5
  56. package/dist/docs/assets/guides_mcp-oauth.md.C7G7IykG.lean.js +1 -0
  57. package/dist/docs/assets/guides_slack.md.zriQpU_9.js +47 -0
  58. package/dist/docs/assets/guides_slack.md.zriQpU_9.lean.js +1 -0
  59. package/dist/docs/assets/{guides_webhooks.md.wSOYas3X.js → guides_webhooks.md.DiAwSR42.js} +1 -1
  60. package/dist/docs/assets/{hillclimbing.md.DHNast08.js → hillclimbing.md.D9Y1_bYh.js} +1 -1
  61. package/dist/docs/assets/index.md.CZqbBJPB.js +20 -0
  62. package/dist/docs/assets/index.md.CZqbBJPB.lean.js +1 -0
  63. package/dist/docs/assets/{quickstart.md.BU6Iwi_9.js → quickstart.md.TnEXYgYW.js} +12 -12
  64. package/dist/docs/assets/{reference_agent-config.md.DrW2JUM8.js → reference_agent-config.md.kuN6-OxK.js} +1 -1
  65. package/dist/docs/assets/reference_cli.md.sD-IUWjg.js +73 -0
  66. package/dist/docs/assets/{reference_cli.md.ccoKOoXt.lean.js → reference_cli.md.sD-IUWjg.lean.js} +1 -1
  67. package/dist/docs/assets/{reference_connections.md.B9Q3TOve.js → reference_connections.md.DGqAsFXb.js} +3 -3
  68. package/dist/docs/assets/reference_http-api.md.CfVM_ICa.js +11 -0
  69. package/dist/docs/assets/{reference_project-layout.md.Bd_CKtNS.js → reference_project-layout.md.D8E6ZmHJ.js} +4 -4
  70. package/dist/docs/assets/{reference_project-layout.md.Bd_CKtNS.lean.js → reference_project-layout.md.D8E6ZmHJ.lean.js} +1 -1
  71. package/dist/docs/assets/{reference_schedules.md.w_F2mXB6.js → reference_schedules.md.gmfYzf_I.js} +1 -1
  72. package/dist/docs/assets/{reference_sessions.md.DLd6mvbv.js → reference_sessions.md.C_ouF_uf.js} +3 -3
  73. package/dist/docs/assets/{reference_tools.md.BRSDnTbN.js → reference_tools.md.BswAQM41.js} +3 -3
  74. package/dist/docs/assets/{scaffolding-agents.md.C3pTrmoE.js → scaffolding-agents.md.Bsr9Pwzu.js} +1 -1
  75. package/dist/docs/assets/{scaffolding-agents.md.C3pTrmoE.lean.js → scaffolding-agents.md.Bsr9Pwzu.lean.js} +1 -1
  76. package/dist/docs/assets/{storage.md.DRTdnFvd.js → storage.md.xZoiGM58.js} +3 -3
  77. package/dist/docs/assets/storage.md.xZoiGM58.lean.js +1 -0
  78. package/dist/docs/assets/troubleshooting.md.B5RVX_tL.js +1 -0
  79. package/dist/docs/assets/{troubleshooting.md.CmQkmnzC.lean.js → troubleshooting.md.B5RVX_tL.lean.js} +1 -1
  80. package/dist/docs/building-with-agents.html +12 -12
  81. package/dist/docs/concepts.html +6 -6
  82. package/dist/docs/deployment.html +32 -32
  83. package/dist/docs/evals.html +19 -19
  84. package/dist/docs/example-agents/approval-buddy.html +9 -9
  85. package/dist/docs/example-agents/benny.html +11 -11
  86. package/dist/docs/example-agents/bugbot.html +10 -10
  87. package/dist/docs/example-agents/codebase-wiki.html +11 -11
  88. package/dist/docs/example-agents/codeowners-review.html +11 -11
  89. package/dist/docs/example-agents/concierge.html +12 -12
  90. package/dist/docs/example-agents/fsd.html +10 -10
  91. package/dist/docs/example-agents/index.html +7 -7
  92. package/dist/docs/example-agents/knowledge-base.html +10 -10
  93. package/dist/docs/example-agents/oncall.html +10 -10
  94. package/dist/docs/example-agents/security-reviewer.html +13 -13
  95. package/dist/docs/example-agents/slack-agent.html +10 -10
  96. package/dist/docs/example-agents/weather-agent.html +16 -16
  97. package/dist/docs/guides/agent-to-agent.html +9 -9
  98. package/dist/docs/guides/cloud-runtime.html +7 -7
  99. package/dist/docs/guides/github.html +10 -10
  100. package/dist/docs/guides/human-in-the-loop.html +7 -7
  101. package/dist/docs/guides/mcp-oauth.html +11 -11
  102. package/dist/docs/guides/slack.html +22 -17
  103. package/dist/docs/guides/webhooks.html +7 -7
  104. package/dist/docs/hashmap.json +1 -1
  105. package/dist/docs/hillclimbing.html +7 -7
  106. package/dist/docs/index.html +9 -9
  107. package/dist/docs/quickstart.html +17 -17
  108. package/dist/docs/reference/agent-config.html +7 -7
  109. package/dist/docs/reference/channels.html +5 -5
  110. package/dist/docs/reference/cli.html +56 -48
  111. package/dist/docs/reference/connections.html +9 -9
  112. package/dist/docs/reference/hooks.html +5 -5
  113. package/dist/docs/reference/http-api.html +7 -7
  114. package/dist/docs/reference/instructions.html +5 -5
  115. package/dist/docs/reference/playground.html +5 -5
  116. package/dist/docs/reference/project-layout.html +9 -9
  117. package/dist/docs/reference/prompt.html +5 -5
  118. package/dist/docs/reference/schedules.html +7 -7
  119. package/dist/docs/reference/sessions.html +8 -8
  120. package/dist/docs/reference/skills.html +5 -5
  121. package/dist/docs/reference/subagents.html +5 -5
  122. package/dist/docs/reference/tools.html +9 -9
  123. package/dist/docs/scaffolding-agents.html +6 -6
  124. package/dist/docs/storage.html +9 -9
  125. package/dist/docs/troubleshooting.html +6 -6
  126. package/dist/evals/reporters.d.ts +1 -1
  127. package/dist/evals/reporters.js +1 -1
  128. package/dist/evals.d.ts +2 -2
  129. package/dist/files-backends/agent-store-presigned-url.d.ts +100 -0
  130. package/dist/files-backends/agent-store-presigned-url.d.ts.map +1 -0
  131. package/dist/files-backends/agent-store-presigned-url.js +347 -0
  132. package/dist/files-backends/cursor-hosted.d.ts +87 -0
  133. package/dist/files-backends/cursor-hosted.d.ts.map +1 -0
  134. package/dist/files-backends/cursor-hosted.js +540 -0
  135. package/dist/files-backends/local-fs.d.ts +33 -0
  136. package/dist/files-backends/local-fs.d.ts.map +1 -0
  137. package/dist/files-backends/local-fs.js +199 -0
  138. package/dist/files.d.ts +139 -0
  139. package/dist/files.d.ts.map +1 -0
  140. package/dist/files.js +89 -0
  141. package/dist/internal/ab-collector.js +2 -2
  142. package/dist/internal/ab-fold.js +1 -1
  143. package/dist/internal/cli-ax.d.ts +2 -2
  144. package/dist/internal/cli-ax.js +2 -2
  145. package/dist/internal/cli-deploy.d.ts +1 -1
  146. package/dist/internal/cli-deploy.d.ts.map +1 -1
  147. package/dist/internal/cli-deploy.js +7 -2
  148. package/dist/internal/cli-docs.d.ts +1 -1
  149. package/dist/internal/cli-docs.js +1 -1
  150. package/dist/internal/cli-github.js +13 -13
  151. package/dist/internal/cli-mcp-oauth.d.ts +1 -1
  152. package/dist/internal/cli-mcp-oauth.js +2 -2
  153. package/dist/internal/cli-mcp.d.ts +3 -3
  154. package/dist/internal/cli-mcp.js +4 -4
  155. package/dist/internal/cli-skills.js +1 -1
  156. package/dist/internal/cloud-turn-cost.d.ts +9 -1
  157. package/dist/internal/cloud-turn-cost.d.ts.map +1 -1
  158. package/dist/internal/cloud-turn-cost.js +14 -4
  159. package/dist/internal/cursor/account-mcp.js +5 -5
  160. package/dist/internal/cursor/backend-client.js +1 -1
  161. package/dist/internal/cursor/github-credentials.js +3 -3
  162. package/dist/internal/cursor-account-mcp-auth.d.ts +1 -1
  163. package/dist/internal/cursor-account-mcp-auth.js +1 -1
  164. package/dist/internal/cursor-event-relay.js +1 -1
  165. package/dist/internal/cursor-relay-core.d.ts +1 -1
  166. package/dist/internal/cursor-relay-core.d.ts.map +1 -1
  167. package/dist/internal/cursor-slack-relay.js +1 -1
  168. package/dist/internal/deploy-client.d.ts +6 -1
  169. package/dist/internal/deploy-client.d.ts.map +1 -1
  170. package/dist/internal/deploy-client.js +3 -2
  171. package/dist/internal/deploy-source.d.ts +2 -2
  172. package/dist/internal/deploy-source.js +2 -2
  173. package/dist/internal/discovery.js +2 -2
  174. package/dist/internal/distribution.d.ts +5 -5
  175. package/dist/internal/distribution.d.ts.map +1 -1
  176. package/dist/internal/distribution.js +6 -6
  177. package/dist/internal/docs-site.js +5 -5
  178. package/dist/internal/eval-run-store.js +8 -8
  179. package/dist/internal/evals-client.d.ts +1 -1
  180. package/dist/internal/evals-client.js +1 -1
  181. package/dist/internal/github-fanout.js +2 -2
  182. package/dist/internal/host-files.d.ts +29 -0
  183. package/dist/internal/host-files.d.ts.map +1 -0
  184. package/dist/internal/host-files.js +283 -0
  185. package/dist/internal/host-platforms.js +5 -5
  186. package/dist/internal/hosting.d.ts +1 -1
  187. package/dist/internal/hosting.js +1 -1
  188. package/dist/internal/http-channel.d.ts.map +1 -1
  189. package/dist/internal/http-channel.js +26 -0
  190. package/dist/internal/install-cursor-skills.d.ts +1 -1
  191. package/dist/internal/install-cursor-skills.d.ts.map +1 -1
  192. package/dist/internal/install-cursor-skills.js +33 -4
  193. package/dist/internal/local-control-plane.js +2 -2
  194. package/dist/internal/logs-client.d.ts +2 -2
  195. package/dist/internal/logs-client.js +2 -2
  196. package/dist/internal/mcp-endpoint.js +1 -1
  197. package/dist/internal/mcp-oauth.js +2 -2
  198. package/dist/internal/platform-schedule-sync.js +2 -2
  199. package/dist/internal/playground/toolchain.js +6 -6
  200. package/dist/internal/reminder-runner.js +13 -13
  201. package/dist/internal/resolved-connections.js +6 -6
  202. package/dist/internal/schedule-runner.js +1 -1
  203. package/dist/internal/sdk-runner.js +5 -5
  204. package/dist/internal/server.js +16 -16
  205. package/dist/internal/session-cost.d.ts +3 -2
  206. package/dist/internal/session-cost.d.ts.map +1 -1
  207. package/dist/internal/session-cost.js +7 -6
  208. package/dist/internal/session-engine.d.ts +31 -1
  209. package/dist/internal/session-engine.d.ts.map +1 -1
  210. package/dist/internal/session-engine.js +119 -31
  211. package/dist/internal/slack-provision-client.js +1 -1
  212. package/dist/internal/storage-coordinator.js +7 -7
  213. package/dist/internal/trajectory.js +2 -2
  214. package/dist/internal/turn-cost.d.ts +27 -0
  215. package/dist/internal/turn-cost.d.ts.map +1 -0
  216. package/dist/internal/turn-cost.js +83 -0
  217. package/dist/internal/update-check.d.ts +3 -3
  218. package/dist/internal/update-check.d.ts.map +1 -1
  219. package/dist/internal/update-check.js +5 -5
  220. package/dist/memory.d.ts +1 -1
  221. package/dist/memory.js +1 -1
  222. package/dist/playground/assets/index-50PKeJlG.css +1 -0
  223. package/dist/playground/assets/index-C0f2Wl1q.js +85 -0
  224. package/dist/playground/index.html +2 -2
  225. package/dist/storage.d.ts +1 -1
  226. package/dist/storage.js +1 -1
  227. package/dist/types.d.ts +120 -16
  228. package/dist/types.d.ts.map +1 -1
  229. package/docs/README.md +23 -23
  230. package/docs/ab.md +12 -12
  231. package/docs/building-with-agents.md +9 -9
  232. package/docs/concepts.md +11 -11
  233. package/docs/deployment.md +55 -43
  234. package/docs/evals.md +20 -20
  235. package/docs/example-agents/approval-buddy.md +9 -9
  236. package/docs/example-agents/benny.md +13 -13
  237. package/docs/example-agents/bugbot.md +6 -6
  238. package/docs/example-agents/codebase-wiki.md +8 -8
  239. package/docs/example-agents/codeowners-review.md +8 -8
  240. package/docs/example-agents/concierge.md +10 -10
  241. package/docs/example-agents/fsd.md +7 -7
  242. package/docs/example-agents/index.md +8 -8
  243. package/docs/example-agents/knowledge-base.md +9 -9
  244. package/docs/example-agents/oncall.md +7 -7
  245. package/docs/example-agents/security-reviewer.md +12 -12
  246. package/docs/example-agents/slack-agent.md +10 -10
  247. package/docs/example-agents/weather-agent.md +30 -26
  248. package/docs/guides/agent-to-agent.md +4 -4
  249. package/docs/guides/cloud-runtime.md +3 -3
  250. package/docs/guides/github.md +6 -6
  251. package/docs/guides/human-in-the-loop.md +1 -1
  252. package/docs/guides/mcp-oauth.md +9 -9
  253. package/docs/guides/slack.md +94 -21
  254. package/docs/guides/webhooks.md +1 -1
  255. package/docs/hillclimbing.md +3 -3
  256. package/docs/quickstart.md +18 -18
  257. package/docs/reference/agent-config.md +1 -1
  258. package/docs/reference/cli.md +110 -79
  259. package/docs/reference/connections.md +3 -3
  260. package/docs/reference/http-api.md +2 -2
  261. package/docs/reference/project-layout.md +7 -7
  262. package/docs/reference/schedules.md +1 -1
  263. package/docs/reference/sessions.md +7 -7
  264. package/docs/reference/tools.md +3 -3
  265. package/docs/scaffolding-agents.md +2 -2
  266. package/docs/storage.md +5 -5
  267. package/docs/troubleshooting.md +11 -10
  268. package/package.json +3 -1
  269. package/skills/ab/SKILL.md +5 -5
  270. package/skills/create-agent/SKILL.md +17 -17
  271. package/skills/debug/SKILL.md +10 -10
  272. package/skills/evals/SKILL.md +13 -13
  273. package/skills/framework-map/SKILL.md +3 -3
  274. package/skills/github/SKILL.md +11 -11
  275. package/skills/hillclimb/SKILL.md +9 -9
  276. package/skills/mcp-auth/SKILL.md +11 -11
  277. package/skills/setup-slack/SKILL.md +28 -28
  278. package/src/bin/agent-serve.ts +4 -4
  279. package/src/channels/github/index.ts +1 -1
  280. package/src/channels/slack/bot-mentions.ts +1 -1
  281. package/src/channels/slack/eval-directive.ts +1 -1
  282. package/src/channels/slack/external-policy.ts +1 -1
  283. package/src/channels/slack/log.ts +1 -1
  284. package/src/channels/slack/setup.ts +1 -1
  285. package/src/channels/slack/socket-mode.ts +1 -1
  286. package/src/evals/reporters.ts +1 -1
  287. package/src/evals.ts +2 -2
  288. package/src/files-backends/agent-store-presigned-url.ts +402 -0
  289. package/src/files-backends/cursor-hosted.ts +698 -0
  290. package/src/files-backends/local-fs.ts +178 -0
  291. package/src/files.ts +195 -0
  292. package/src/internal/ab-collector.ts +2 -2
  293. package/src/internal/ab-fold.ts +1 -1
  294. package/src/internal/cli-ax.ts +2 -2
  295. package/src/internal/cli-deploy.ts +7 -2
  296. package/src/internal/cli-docs.ts +1 -1
  297. package/src/internal/cli-github.ts +13 -13
  298. package/src/internal/cli-mcp-oauth.ts +2 -2
  299. package/src/internal/cli-mcp.ts +4 -4
  300. package/src/internal/cli-skills.ts +1 -1
  301. package/src/internal/cloud-turn-cost.ts +20 -4
  302. package/src/internal/cursor/account-mcp.ts +5 -5
  303. package/src/internal/cursor/backend-client.ts +1 -1
  304. package/src/internal/cursor/github-credentials.ts +3 -3
  305. package/src/internal/cursor-account-mcp-auth.ts +1 -1
  306. package/src/internal/cursor-event-relay.ts +1 -1
  307. package/src/internal/cursor-relay-core.ts +1 -1
  308. package/src/internal/cursor-slack-relay.ts +1 -1
  309. package/src/internal/deploy-client.ts +8 -2
  310. package/src/internal/deploy-source.ts +2 -2
  311. package/src/internal/discovery.ts +2 -2
  312. package/src/internal/distribution.ts +6 -6
  313. package/src/internal/docs-site.ts +5 -5
  314. package/src/internal/eval-run-store.ts +8 -8
  315. package/src/internal/evals-client.ts +1 -1
  316. package/src/internal/github-fanout.ts +2 -2
  317. package/src/internal/host-files.ts +372 -0
  318. package/src/internal/host-platforms.ts +5 -5
  319. package/src/internal/hosting.ts +1 -1
  320. package/src/internal/http-channel.ts +30 -0
  321. package/src/internal/install-cursor-skills.ts +31 -3
  322. package/src/internal/local-control-plane.ts +2 -2
  323. package/src/internal/logs-client.ts +2 -2
  324. package/src/internal/mcp-endpoint.ts +1 -1
  325. package/src/internal/mcp-oauth.ts +2 -2
  326. package/src/internal/platform-schedule-sync.ts +2 -2
  327. package/src/internal/playground/toolchain.ts +6 -6
  328. package/src/internal/reminder-runner.ts +13 -13
  329. package/src/internal/resolved-connections.ts +6 -6
  330. package/src/internal/schedule-runner.ts +1 -1
  331. package/src/internal/sdk-runner.ts +5 -5
  332. package/src/internal/server.ts +16 -16
  333. package/src/internal/session-cost.ts +7 -6
  334. package/src/internal/session-engine.ts +141 -28
  335. package/src/internal/slack-provision-client.ts +1 -1
  336. package/src/internal/storage-coordinator.ts +7 -7
  337. package/src/internal/trajectory.ts +2 -2
  338. package/src/internal/turn-cost.ts +110 -0
  339. package/src/internal/update-check.ts +6 -6
  340. package/src/memory.ts +1 -1
  341. package/src/storage.ts +1 -1
  342. package/src/types.ts +148 -16
  343. package/dist/docs/assets/building-with-agents.md.CJCtZCyi.js +0 -13
  344. package/dist/docs/assets/chunks/@localSearchIndexroot.CbQshWFK.js +0 -1
  345. package/dist/docs/assets/concepts.md.Cfb9b-k1.js +0 -4
  346. package/dist/docs/assets/concepts.md.Cfb9b-k1.lean.js +0 -1
  347. package/dist/docs/assets/deployment.md.TecHo0_2.js +0 -55
  348. package/dist/docs/assets/deployment.md.TecHo0_2.lean.js +0 -1
  349. package/dist/docs/assets/evals.md.DYOjkRCX.lean.js +0 -1
  350. package/dist/docs/assets/example-agents_benny.md.B0gjhI-p.js +0 -7
  351. package/dist/docs/assets/example-agents_index.md.D2PEVSXl.js +0 -2
  352. package/dist/docs/assets/example-agents_index.md.D2PEVSXl.lean.js +0 -1
  353. package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.js +0 -10
  354. package/dist/docs/assets/example-agents_slack-agent.md.buLbgvBf.js +0 -5
  355. package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.js +0 -24
  356. package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.lean.js +0 -1
  357. package/dist/docs/assets/guides_cloud-runtime.md.gVzabdQL.js +0 -9
  358. package/dist/docs/assets/guides_mcp-oauth.md.Dd8EgSem.lean.js +0 -1
  359. package/dist/docs/assets/guides_slack.md.CjmJSvZS.js +0 -42
  360. package/dist/docs/assets/guides_slack.md.CjmJSvZS.lean.js +0 -1
  361. package/dist/docs/assets/index.md.CH_s5uZe.js +0 -20
  362. package/dist/docs/assets/index.md.CH_s5uZe.lean.js +0 -1
  363. package/dist/docs/assets/reference_cli.md.ccoKOoXt.js +0 -65
  364. package/dist/docs/assets/reference_http-api.md.BncLd3PZ.js +0 -11
  365. package/dist/docs/assets/storage.md.DRTdnFvd.lean.js +0 -1
  366. package/dist/docs/assets/troubleshooting.md.CmQkmnzC.js +0 -1
  367. package/dist/internal/model-pricing.d.ts +0 -49
  368. package/dist/internal/model-pricing.d.ts.map +0 -1
  369. package/dist/internal/model-pricing.js +0 -377
  370. package/dist/playground/assets/index-CquRB-l0.js +0 -85
  371. package/dist/playground/assets/index-Dj0bWpkn.css +0 -1
  372. package/src/internal/model-pricing.ts +0 -426
  373. /package/dist/docs/assets/{example-agents_benny.md.B0gjhI-p.lean.js → example-agents_benny.md.2Et1qa8f.lean.js} +0 -0
  374. /package/dist/docs/assets/{example-agents_bugbot.md.DelIdhxB.lean.js → example-agents_bugbot.md.ByUexi5i.lean.js} +0 -0
  375. /package/dist/docs/assets/{example-agents_concierge.md.4rQTSMXt.lean.js → example-agents_concierge.md.lL8rhYlj.lean.js} +0 -0
  376. /package/dist/docs/assets/{example-agents_fsd.md.CzgUrDfi.lean.js → example-agents_fsd.md.DfNKQTHz.lean.js} +0 -0
  377. /package/dist/docs/assets/{example-agents_oncall.md.BG_sUMly.lean.js → example-agents_oncall.md.wFFXXEyW.lean.js} +0 -0
  378. /package/dist/docs/assets/{example-agents_security-reviewer.md.Dhj_m7_B.lean.js → example-agents_security-reviewer.md.Dkf1gyo6.lean.js} +0 -0
  379. /package/dist/docs/assets/{example-agents_slack-agent.md.buLbgvBf.lean.js → example-agents_slack-agent.md.DvgvT4nn.lean.js} +0 -0
  380. /package/dist/docs/assets/{guides_agent-to-agent.md.Bpzgq2Pq.lean.js → guides_agent-to-agent.md.Bmbxy-FA.lean.js} +0 -0
  381. /package/dist/docs/assets/{guides_cloud-runtime.md.gVzabdQL.lean.js → guides_cloud-runtime.md.BZ2GA7Es.lean.js} +0 -0
  382. /package/dist/docs/assets/{guides_github.md.DOOCpqsW.lean.js → guides_github.md.R2QlpR75.lean.js} +0 -0
  383. /package/dist/docs/assets/{guides_human-in-the-loop.md.DlUqsp1S.lean.js → guides_human-in-the-loop.md.BWvT7UqY.lean.js} +0 -0
  384. /package/dist/docs/assets/{guides_webhooks.md.wSOYas3X.lean.js → guides_webhooks.md.DiAwSR42.lean.js} +0 -0
  385. /package/dist/docs/assets/{hillclimbing.md.DHNast08.lean.js → hillclimbing.md.D9Y1_bYh.lean.js} +0 -0
  386. /package/dist/docs/assets/{quickstart.md.BU6Iwi_9.lean.js → quickstart.md.TnEXYgYW.lean.js} +0 -0
  387. /package/dist/docs/assets/{reference_agent-config.md.DrW2JUM8.lean.js → reference_agent-config.md.kuN6-OxK.lean.js} +0 -0
  388. /package/dist/docs/assets/{reference_connections.md.B9Q3TOve.lean.js → reference_connections.md.DGqAsFXb.lean.js} +0 -0
  389. /package/dist/docs/assets/{reference_http-api.md.BncLd3PZ.lean.js → reference_http-api.md.CfVM_ICa.lean.js} +0 -0
  390. /package/dist/docs/assets/{reference_schedules.md.w_F2mXB6.lean.js → reference_schedules.md.gmfYzf_I.lean.js} +0 -0
  391. /package/dist/docs/assets/{reference_sessions.md.DLd6mvbv.lean.js → reference_sessions.md.C_ouF_uf.lean.js} +0 -0
  392. /package/dist/docs/assets/{reference_tools.md.BRSDnTbN.lean.js → reference_tools.md.BswAQM41.lean.js} +0 -0
@@ -1,4 +1,4 @@
1
- import{_ as t,c as a,o as s,ag as n}from"./chunks/framework.CAZyNGu9.js";const u=JSON.parse('{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule.","frontmatter":{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),o={name:"reference/project-layout.md"};function d(i,e,r,l,c,p){return s(),a("div",null,[...e[0]||(e[0]=[n(`<h1 id="project-layout" tabindex="-1">Project layout <a class="header-anchor" href="#project-layout" aria-label="Permalink to &quot;Project layout&quot;">​</a></h1><p>agentkit builds an agent by walking the filesystem under <code>agent/</code>. Each folder has a defined purpose. The path a file lands in determines how agentkit loads it.</p><h2 id="folder-structure" tabindex="-1">Folder structure <a class="header-anchor" href="#folder-structure" aria-label="Permalink to &quot;Folder structure&quot;">​</a></h2><p>For the capabilities below, identity usually comes from the path. A/B experiments can override their file-derived name.</p><table tabindex="0"><thead><tr><th>Path</th><th>Resolves to</th></tr></thead><tbody><tr><td><code>agent/tools/approve_pr.ts</code></td><td>tool <code>approve_pr</code></td></tr><tr><td><code>agent/mcp-connections/linear.ts</code></td><td>MCP connection <code>linear</code></td></tr><tr><td><code>agent/skills/pr-review.md</code></td><td>skill <code>pr-review</code></td></tr><tr><td><code>agent/subagents/reviewer/</code></td><td>subagent <code>reviewer</code></td></tr><tr><td><code>agent/channels/drive.ts</code></td><td>channel <code>drive</code>, routes under <code>/v1/channels/drive</code></td></tr><tr><td><code>agent/ab.ts</code></td><td>A/B experiment <code>ab</code> unless <code>name</code> overrides it</td></tr><tr><td><code>agent/ab/concise.ts</code></td><td>A/B experiment <code>concise</code> unless <code>name</code> overrides it</td></tr></tbody></table><p>The root agent takes its name from <code>package.json</code> <code>name</code>, falling back to the directory name. When serving multiple agents, the slug is the directory name and must match <code>[A-Za-z0-9][A-Za-z0-9_-]*</code> (and not the reserved <code>v1</code>, <code>playground</code>, or <code>docs</code> segments).</p><h2 id="full-project-layout" tabindex="-1">Full project layout <a class="header-anchor" href="#full-project-layout" aria-label="Permalink to &quot;Full project layout&quot;">​</a></h2><p>A full project looks like this.</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>my-agent/</span></span>
1
+ import{_ as t,c as a,o as s,ag as n}from"./chunks/framework.CAZyNGu9.js";const u=JSON.parse('{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule.","frontmatter":{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),d={name:"reference/project-layout.md"};function o(i,e,r,l,c,p){return s(),a("div",null,[...e[0]||(e[0]=[n(`<h1 id="project-layout" tabindex="-1">Project layout <a class="header-anchor" href="#project-layout" aria-label="Permalink to &quot;Project layout&quot;">​</a></h1><p>The Agent SDK builds an agent by walking the filesystem under <code>agent/</code>. Each folder has a defined purpose. The path a file lands in determines how the Agent SDK loads it.</p><h2 id="folder-structure" tabindex="-1">Folder structure <a class="header-anchor" href="#folder-structure" aria-label="Permalink to &quot;Folder structure&quot;">​</a></h2><p>For the capabilities below, identity usually comes from the path. A/B experiments can override their file-derived name.</p><table tabindex="0"><thead><tr><th>Path</th><th>Resolves to</th></tr></thead><tbody><tr><td><code>agent/tools/approve_pr.ts</code></td><td>tool <code>approve_pr</code></td></tr><tr><td><code>agent/mcp-connections/linear.ts</code></td><td>MCP connection <code>linear</code></td></tr><tr><td><code>agent/skills/pr-review.md</code></td><td>skill <code>pr-review</code></td></tr><tr><td><code>agent/subagents/reviewer/</code></td><td>subagent <code>reviewer</code></td></tr><tr><td><code>agent/channels/drive.ts</code></td><td>channel <code>drive</code>, routes under <code>/v1/channels/drive</code></td></tr><tr><td><code>agent/ab.ts</code></td><td>A/B experiment <code>ab</code> unless <code>name</code> overrides it</td></tr><tr><td><code>agent/ab/concise.ts</code></td><td>A/B experiment <code>concise</code> unless <code>name</code> overrides it</td></tr></tbody></table><p>The root agent takes its name from <code>package.json</code> <code>name</code>, falling back to the directory name. When serving multiple agents, the slug is the directory name and must match <code>[A-Za-z0-9][A-Za-z0-9_-]*</code> (and not the reserved <code>v1</code>, <code>playground</code>, or <code>docs</code> segments).</p><h2 id="full-project-layout" tabindex="-1">Full project layout <a class="header-anchor" href="#full-project-layout" aria-label="Permalink to &quot;Full project layout&quot;">​</a></h2><p>A full project looks like this.</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>my-agent/</span></span>
2
2
  <span class="line"><span>├── package.json</span></span>
3
3
  <span class="line"><span>├── agent/</span></span>
4
4
  <span class="line"><span>│ ├── agent.ts # runtime config (model, runtime, cloud/local)</span></span>
@@ -26,6 +26,6 @@ import{_ as t,c as a,o as s,ag as n}from"./chunks/framework.CAZyNGu9.js";const u
26
26
  <span class="line"><span>│ └── lib/ # shared code (import-only, never discovered)</span></span>
27
27
  <span class="line"><span>└── evals/</span></span>
28
28
  <span class="line"><span> ├── evals.config.ts # required when evals exist (maxConcurrency)</span></span>
29
- <span class="line"><span> └── readiness.eval.ts # filesystem evals</span></span></code></pre></div><p>Evals live in <code>evals/</code> at the project root, a sibling of <code>agent/</code>, never inside it. <code>agent/evals/</code> is silently ignored. See <a href="./../evals.html">Evals</a>.</p><h2 id="folder-reference" tabindex="-1">Folder reference <a class="header-anchor" href="#folder-reference" aria-label="Permalink to &quot;Folder reference&quot;">​</a></h2><p>Each path maps to a capability and a reference page.</p><table tabindex="0"><thead><tr><th>Path</th><th>What it is</th><th>Reference</th></tr></thead><tbody><tr><td><code>agent/agent.ts</code></td><td><code>defineAgent({ model?, runtime?, cloud?, local? })</code>; the model defaults to <code>grok-4.5</code> with <code>effort=high</code>, <code>fast=true</code></td><td><a href="./agent-config.html">Agent config</a></td></tr><tr><td><code>agent/instructions.md</code></td><td>Always-on system prompt, required on the root agent (<code>.ts</code> and directory forms exist)</td><td><a href="./instructions.html">Instructions</a></td></tr><tr><td><code>agent/tools/&lt;name&gt;.ts</code></td><td>One typed tool; filename = tool name. <code>execution: &quot;server&quot;</code> (in-process, default) or <code>&quot;agent&quot;</code> (a script that runs where the agent runs)</td><td><a href="./tools.html">Tools</a></td></tr><tr><td><code>agent/skills/*</code></td><td>SKILL.md-convention procedures, loaded on demand</td><td><a href="./skills.html">Skills</a></td></tr><tr><td><code>agent/mcp-connections/&lt;name&gt;.ts</code></td><td>MCP servers, available to the model, to server tools (<code>ctx.host.mcp</code>), and to channel/schedule handlers (<code>args.host.mcp</code>)</td><td><a href="./connections.html">MCP connections</a></td></tr><tr><td><code>agent/subagents/&lt;id&gt;/</code></td><td>Child agent directory; <code>description</code> required</td><td><a href="./subagents.html">Subagents</a></td></tr><tr><td><code>agent/channels/*.ts</code></td><td>HTTP surfaces beyond the built-in session API; <code>slack.ts</code> and <code>github.ts</code> use the platform packs</td><td><a href="./channels.html">Channels</a></td></tr><tr><td><code>agent/hooks/*.ts</code></td><td>Observe-only event subscribers, never fatal</td><td><a href="./hooks.html">Hooks</a></td></tr><tr><td><code>agent/ab.ts</code>, <code>agent/ab/*.ts</code></td><td><code>defineAB</code> experiments with sticky variants and live metrics</td><td><a href="./../ab.html">Live A/B metrics</a></td></tr><tr><td><code>agent/schedules/*</code></td><td>Cron-driven runs (UTC, 5-field; never auto-fire under <code>--dev</code>)</td><td><a href="./schedules.html">Schedules</a></td></tr><tr><td><code>agent/lib/</code></td><td>Import-only shared code, never discovered</td><td>None</td></tr><tr><td><code>evals/**/*.eval.ts</code></td><td>Filesystem evals; case id = path under <code>evals/</code></td><td><a href="./../evals.html">Evals</a></td></tr></tbody></table><p><code>agent/lib/</code> is the only place for shared code. Everything else under <code>agent/</code> is discovery surface. A stray <code>.ts</code> file in one of these folders is treated as a definition.</p><h2 id="why-didn-t-agentkit-discover-my-file" tabindex="-1">Why didn&#39;t agentkit discover my file? <a class="header-anchor" href="#why-didn-t-agentkit-discover-my-file" aria-label="Permalink to &quot;Why didn&#39;t agentkit discover my file?&quot;">​</a></h2><p>Run <code>agentkit validate --dir .</code> and <code>agentkit info --dir .</code>. <code>validate</code> prints diagnostics, and <code>serve</code> refuses to start on error-severity ones. Warnings, such as cloud runtime combined with local-only capabilities, print but don&#39;t block. <code>info</code> lists the discovered surface, so a missing tool or channel shows up immediately. From there, check the folder reference: the file is usually in the wrong directory or has the wrong extension.</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agentkit</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # diagnostics; non-zero exit on errors</span></span>
30
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agentkit</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # human-readable surface</span></span>
31
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agentkit</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # machine-readable manifest (same shape as GET /v1/info)</span></span></code></pre></div><h2 id="what-s-next" tabindex="-1">What&#39;s next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to &quot;What&#39;s next&quot;">​</a></h2><p>Continue with these pages:</p><ul><li><a href="./agent-config.html">Agent config</a>: the runtime config at the root</li><li><a href="./tools.html">Tools</a>: add typed actions under <code>agent/tools/</code></li><li><a href="./../ab.html">Live A/B metrics</a>: compare variants from <code>agent/ab.ts</code> or <code>agent/ab/</code></li><li><a href="./../concepts.html">Concepts</a>: why the filesystem is the interface</li></ul>`,20)])])}const g=t(o,[["render",d]]);export{u as __pageData,g as default};
29
+ <span class="line"><span> └── readiness.eval.ts # filesystem evals</span></span></code></pre></div><p>Evals live in <code>evals/</code> at the project root, a sibling of <code>agent/</code>, never inside it. <code>agent/evals/</code> is silently ignored. See <a href="./../evals.html">Evals</a>.</p><h2 id="folder-reference" tabindex="-1">Folder reference <a class="header-anchor" href="#folder-reference" aria-label="Permalink to &quot;Folder reference&quot;">​</a></h2><p>Each path maps to a capability and a reference page.</p><table tabindex="0"><thead><tr><th>Path</th><th>What it is</th><th>Reference</th></tr></thead><tbody><tr><td><code>agent/agent.ts</code></td><td><code>defineAgent({ model?, runtime?, cloud?, local? })</code>; the model defaults to <code>grok-4.5</code> with <code>effort=high</code>, <code>fast=true</code></td><td><a href="./agent-config.html">Agent config</a></td></tr><tr><td><code>agent/instructions.md</code></td><td>Always-on system prompt, required on the root agent (<code>.ts</code> and directory forms exist)</td><td><a href="./instructions.html">Instructions</a></td></tr><tr><td><code>agent/tools/&lt;name&gt;.ts</code></td><td>One typed tool; filename = tool name. <code>execution: &quot;server&quot;</code> (in-process, default) or <code>&quot;agent&quot;</code> (a script that runs where the agent runs)</td><td><a href="./tools.html">Tools</a></td></tr><tr><td><code>agent/skills/*</code></td><td>SKILL.md-convention procedures, loaded on demand</td><td><a href="./skills.html">Skills</a></td></tr><tr><td><code>agent/mcp-connections/&lt;name&gt;.ts</code></td><td>MCP servers, available to the model, to server tools (<code>ctx.host.mcp</code>), and to channel/schedule handlers (<code>args.host.mcp</code>)</td><td><a href="./connections.html">MCP connections</a></td></tr><tr><td><code>agent/subagents/&lt;id&gt;/</code></td><td>Child agent directory; <code>description</code> required</td><td><a href="./subagents.html">Subagents</a></td></tr><tr><td><code>agent/channels/*.ts</code></td><td>HTTP surfaces beyond the built-in session API; <code>slack.ts</code> and <code>github.ts</code> use the platform packs</td><td><a href="./channels.html">Channels</a></td></tr><tr><td><code>agent/hooks/*.ts</code></td><td>Observe-only event subscribers, never fatal</td><td><a href="./hooks.html">Hooks</a></td></tr><tr><td><code>agent/ab.ts</code>, <code>agent/ab/*.ts</code></td><td><code>defineAB</code> experiments with sticky variants and live metrics</td><td><a href="./../ab.html">Live A/B metrics</a></td></tr><tr><td><code>agent/schedules/*</code></td><td>Cron-driven runs (UTC, 5-field; never auto-fire under <code>--dev</code>)</td><td><a href="./schedules.html">Schedules</a></td></tr><tr><td><code>agent/lib/</code></td><td>Import-only shared code, never discovered</td><td>None</td></tr><tr><td><code>evals/**/*.eval.ts</code></td><td>Filesystem evals; case id = path under <code>evals/</code></td><td><a href="./../evals.html">Evals</a></td></tr></tbody></table><p><code>agent/lib/</code> is the only place for shared code. Everything else under <code>agent/</code> is discovery surface. A stray <code>.ts</code> file in one of these folders is treated as a definition.</p><h2 id="why-didn-t-the-agent-sdk-discover-my-file" tabindex="-1">Why didn&#39;t the Agent SDK discover my file? <a class="header-anchor" href="#why-didn-t-the-agent-sdk-discover-my-file" aria-label="Permalink to &quot;Why didn&#39;t the Agent SDK discover my file?&quot;">​</a></h2><p>Run <code>agent-sdk validate --dir .</code> and <code>agent-sdk info --dir .</code>. <code>validate</code> prints diagnostics, and <code>serve</code> refuses to start on error-severity ones. Warnings, such as cloud runtime combined with local-only capabilities, print but don&#39;t block. <code>info</code> lists the discovered surface, so a missing tool or channel shows up immediately. From there, check the folder reference: the file is usually in the wrong directory or has the wrong extension.</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # diagnostics; non-zero exit on errors</span></span>
30
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # human-readable surface</span></span>
31
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # machine-readable manifest (same shape as GET /v1/info)</span></span></code></pre></div><h2 id="what-s-next" tabindex="-1">What&#39;s next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to &quot;What&#39;s next&quot;">​</a></h2><p>Continue with these pages:</p><ul><li><a href="./agent-config.html">Agent config</a>: the runtime config at the root</li><li><a href="./tools.html">Tools</a>: add typed actions under <code>agent/tools/</code></li><li><a href="./../ab.html">Live A/B metrics</a>: compare variants from <code>agent/ab.ts</code> or <code>agent/ab/</code></li><li><a href="./../concepts.html">Concepts</a>: why the filesystem is the interface</li></ul>`,20)])])}const g=t(d,[["render",o]]);export{u as __pageData,g as default};
@@ -1 +1 @@
1
- import{_ as t,c as a,o as s,ag as n}from"./chunks/framework.CAZyNGu9.js";const u=JSON.parse('{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule.","frontmatter":{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),o={name:"reference/project-layout.md"};function d(i,e,r,l,c,p){return s(),a("div",null,[...e[0]||(e[0]=[n("",20)])])}const g=t(o,[["render",d]]);export{u as __pageData,g as default};
1
+ import{_ as t,c as a,o as s,ag as n}from"./chunks/framework.CAZyNGu9.js";const u=JSON.parse('{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule.","frontmatter":{"title":"Project layout","description":"The folder structure under agent/ and the path-derived naming rule."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),d={name:"reference/project-layout.md"};function o(i,e,r,l,c,p){return s(),a("div",null,[...e[0]||(e[0]=[n("",20)])])}const g=t(d,[["render",o]]);export{u as __pageData,g as default};
@@ -17,7 +17,7 @@ import{_ as i,c as a,o as n,ag as e}from"./chunks/framework.CAZyNGu9.js";const E
17
17
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span>
18
18
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> );</span></span>
19
19
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
20
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p><code>defineSchedule</code> requires exactly one of <code>markdown</code> or <code>run</code>. The <code>run</code> handler receives <code>receive</code> (hand off into a channel), <code>callTool</code> (deterministic server-tool calls), <code>waitUntil</code>, <code>appAuth</code> (a schedule-scoped principal for work the agent does on its own behalf), and <code>host</code> (shared services: <code>host.mcp</code>, <code>host.github</code>, <code>host.slack</code>, <code>host.reminders</code>).</p><h3 id="dispatch-and-dev-mode" tabindex="-1">Dispatch and dev mode <a class="header-anchor" href="#dispatch-and-dev-mode" aria-label="Permalink to &quot;Dispatch and dev mode&quot;">​</a></h3><p>In production (<code>agentkit serve</code>), schedules fire on their cron cadence. Disable them with <code>--no-schedules</code>. There&#39;s no cross-host coordination, so run them in exactly one process per project.</p><p>In dev (<code>serve --dev</code>), schedules never fire automatically. Dispatch one by hand, exactly once, through the same path production uses:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/v1/dev/schedules/heartbeat</span></span>
20
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p><code>defineSchedule</code> requires exactly one of <code>markdown</code> or <code>run</code>. The <code>run</code> handler receives <code>receive</code> (hand off into a channel), <code>callTool</code> (deterministic server-tool calls), <code>waitUntil</code>, <code>appAuth</code> (a schedule-scoped principal for work the agent does on its own behalf), and <code>host</code> (shared services: <code>host.mcp</code>, <code>host.github</code>, <code>host.slack</code>, <code>host.reminders</code>).</p><h3 id="dispatch-and-dev-mode" tabindex="-1">Dispatch and dev mode <a class="header-anchor" href="#dispatch-and-dev-mode" aria-label="Permalink to &quot;Dispatch and dev mode&quot;">​</a></h3><p>In production (<code>agent-sdk serve</code>), schedules fire on their cron cadence. Disable them with <code>--no-schedules</code>. There&#39;s no cross-host coordination, so run them in exactly one process per project.</p><p>In dev (<code>serve --dev</code>), schedules never fire automatically. Dispatch one by hand, exactly once, through the same path production uses:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/v1/dev/schedules/heartbeat</span></span>
21
21
  <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># {&quot;scheduleId&quot;:&quot;heartbeat&quot;,&quot;sessionIds&quot;:[&quot;ses_…&quot;]}</span></span></code></pre></div><p>The playground can dispatch schedules in dev mode too, and <code>handle.dispatchSchedule(&quot;heartbeat&quot;)</code> does it programmatically.</p><h2 id="reminders" tabindex="-1">Reminders <a class="header-anchor" href="#reminders" aria-label="Permalink to &quot;Reminders&quot;">​</a></h2><p>A reminder is created at runtime and bound to a channel continuation. When it fires, it wakes that conversation. Recurring reminders behave like <code>setInterval</code>, one-shots like <code>setTimeout</code>, and both are durable on disk.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> handle.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">createReminder</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
22
22
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> purpose: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;ci_recheck&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
23
23
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> channelId: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;drive&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
@@ -1,8 +1,8 @@
1
- import{_ as t,c as s,o as a,ag as o}from"./chunks/framework.CAZyNGu9.js";const u=JSON.parse('{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives.","frontmatter":{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives."},"headers":[],"relativePath":"reference/sessions.md","filePath":"reference/sessions.md"}'),n={name:"reference/sessions.md"};function i(d,e,r,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o(`<h1 id="sessions-events-and-streaming" tabindex="-1">Sessions, events, and streaming <a class="header-anchor" href="#sessions-events-and-streaming" aria-label="Permalink to &quot;Sessions, events, and streaming&quot;">​</a></h1><p>A session keeps one conversation, its workspace, and an append-only record of every message and tool call.</p><h2 id="what-does-a-session-contain" tabindex="-1">What does a session contain? <a class="header-anchor" href="#what-does-a-session-contain" aria-label="Permalink to &quot;What does a session contain?&quot;">​</a></h2><p>Each session combines:</p><ul><li>A channel and authenticated caller</li><li>A conversation the caller can continue</li><li>A workspace for local turns</li><li>An NDJSON event stream</li><li>Runtime state needed to resume after a server restart</li></ul><p>Sessions belong to the principal that created them. Follow-up, stream, and list routes return <code>403</code> when another caller tries to access one.</p><h2 id="which-session-identifier-should-i-use" tabindex="-1">Which session identifier should I use? <a class="header-anchor" href="#which-session-identifier-should-i-use" aria-label="Permalink to &quot;Which session identifier should I use?&quot;">​</a></h2><p>Sessions have two identifiers because conversation routing and inspection are different jobs.</p><table tabindex="0"><thead><tr><th>Identifier</th><th>Use it for</th></tr></thead><tbody><tr><td><code>continuationToken</code></td><td>Continue a conversation through its channel</td></tr><tr><td><code>sessionId</code></td><td>Stream events, inspect state, resolve approvals, or run a session-bound tool call</td></tr></tbody></table><p>Channels decide what a continuation token looks like. Slack uses its thread identity. A PR channel can use a key such as <code>pr:owner/repo#1</code>. The built-in HTTP API returns an opaque token and rotates it after each accepted follow-up. Reusing a stale HTTP token returns <code>409</code>.</p><p>Use the continuation token to keep talking. Use the session ID to observe or manage the stored session.</p><h2 id="which-session-modes-are-available" tabindex="-1">Which session modes are available? <a class="header-anchor" href="#which-session-modes-are-available" aria-label="Permalink to &quot;Which session modes are available?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>Mode</th><th>Created by</th><th>What happens after a turn</th></tr></thead><tbody><tr><td><code>chat</code></td><td>HTTP sessions, channel <code>send</code>, Slack, or MCP <code>ask</code></td><td>Waits in <code>session.waiting</code> and accepts follow-ups</td></tr><tr><td><code>task</code></td><td>Markdown schedules and fire-and-forget dispatch</td><td>Ends in <code>session.completed</code> or <code>session.failed</code></td></tr></tbody></table><p>Task sessions don&#39;t accept follow-ups. Trying one returns <code>409</code>.</p><h2 id="what-happens-when-i-send-a-follow-up" tabindex="-1">What happens when I send a follow-up? <a class="header-anchor" href="#what-happens-when-i-send-a-follow-up" aria-label="Permalink to &quot;What happens when I send a follow-up?&quot;">​</a></h2><p>A follow-up to an idle chat session starts another turn. Admission when the session is already busy depends on the channel:</p><table tabindex="0"><thead><tr><th>Path</th><th>Busy-session policy</th></tr></thead><tbody><tr><td>HTTP playground / <code>POST /v1/session/:id</code> / MCP <code>ask</code></td><td><strong>Preempt</strong> (default): interrupt the in-flight turn, wait for it to settle, then run the new message</td></tr><tr><td>Slack mentions / DMs / alert-watch</td><td><strong>Coalesce</strong>: leave the active turn running, enqueue the follow-up, and drain queued asks into one follow-up turn when the active turn finishes (no mid-turn tool/hook inject)</td></tr></tbody></table><p>Pass <code>admission: &quot;coalesce&quot;</code> on <code>send()</code> to opt into the Slack policy from other callers. Omit it (or pass <code>&quot;preempt&quot;</code>) to keep interrupt semantics.</p><p><code>POST /v1/session/:id/stop</code> interrupts a turn without sending a new message. Interrupted turns record <code>turn.failed</code> with <code>&quot;turn interrupted&quot;</code>. This means the turn was preempted. A whole-message Slack <code>stop</code> / <code>@agent stop</code> does the same for that thread and clears pending coalesced nudges.</p><p>Session-bound deterministic tool calls share the same execution lock. They return <code>409 session_busy</code> while a model turn is running.</p><h2 id="which-events-can-i-stream" tabindex="-1">Which events can I stream? <a class="header-anchor" href="#which-events-can-i-stream" aria-label="Permalink to &quot;Which events can I stream?&quot;">​</a></h2><p>Each NDJSON line uses this envelope: <code>{ type, index, sessionId, turnId?, at, data }</code>. The <code>index</code> increases within one session. The <code>at</code> field is an ISO-8601 timestamp.</p><table tabindex="0"><thead><tr><th>Phase</th><th>Events</th><th>What they tell you</th></tr></thead><tbody><tr><td>Session</td><td><code>session.started</code>, <a href="./../ab.html#assign-sticky-variants"><code>ab.assigned</code></a>, <code>session.waiting</code>, <code>session.completed</code>, <code>session.failed</code></td><td>Session creation, A/B enrollment, readiness, and task completion</td></tr><tr><td>Agent</td><td><code>agent.bound</code></td><td>Cursor SDK agent ID and cloud conversation URL</td></tr><tr><td>Input</td><td><code>message.received</code></td><td>A user message was accepted</td></tr><tr><td>Turn</td><td><code>turn.started</code>, <code>turn.completed</code>, <code>turn.failed</code></td><td>Turn status, final result, and token usage</td></tr><tr><td>Steps</td><td><code>step.started</code>, <code>step.completed</code></td><td>Model step boundaries and duration</td></tr><tr><td>Reasoning</td><td><code>reasoning.appended</code>, <code>reasoning.completed</code></td><td>Streamed reasoning blocks</td></tr><tr><td>Reply</td><td><code>message.appended</code>, <code>message.completed</code></td><td>Text deltas and finalized assistant messages</td></tr><tr><td>Tools</td><td><code>actions.requested</code>, <code>action.result</code></td><td>Tool names, validated arguments, outputs, and errors</td></tr><tr><td>Approvals</td><td><code>action.approval_requested</code>, <code>action.approval_resolved</code></td><td>A parked tool call and the human decision</td></tr><tr><td>Subagents</td><td><code>subagent.called</code>, <code>subagent.completed</code></td><td>Delegated work</td></tr></tbody></table><p>Pair <code>actions.requested</code> with <code>action.result</code> to reconstruct the tool trajectory. Read <code>turn.completed.data.usage</code> for input, output, and cache token counts.</p><h2 id="how-do-i-stream-or-replay-session-events" tabindex="-1">How do I stream or replay session events? <a class="header-anchor" href="#how-do-i-stream-or-replay-session-events" aria-label="Permalink to &quot;How do I stream or replay session events?&quot;">​</a></h2><p>One endpoint handles both live streaming and replay:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -N</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;http://127.0.0.1:3000/&lt;slug&gt;/v1/session/ses_…/stream?startIndex=0&#39;</span></span></code></pre></div><p>Pass <code>startIndex</code> to continue after the last event you received. Omit it or pass <code>0</code> to replay the full session before following new events. <code>GET /v1/session/:id/events</code> returns a one-time dump without staying connected.</p><p>Event streams replay from disk after a server restart. Conversation state resumes from the Cursor SDK store.</p><h2 id="what-goes-into-a-local-session-workspace" tabindex="-1">What goes into a local session workspace? <a class="header-anchor" href="#what-goes-into-a-local-session-workspace" aria-label="Permalink to &quot;What goes into a local session workspace?&quot;">​</a></h2><p>agentkit creates a workspace before the first local turn:</p><table tabindex="0"><thead><tr><th>Source path</th><th>Lands as</th></tr></thead><tbody><tr><td><code>instructions.*</code></td><td><code>AGENTS.md</code></td></tr><tr><td><code>skills/*</code></td><td><code>.cursor/skills/&lt;name&gt;/SKILL.md</code></td></tr><tr><td>agent tools (<code>execution: &quot;agent&quot;</code>)</td><td>scripts under <code>.agentkit/tools/</code>, with a catalog in <code>AGENTS.md</code></td></tr><tr><td><code>sandbox/workspace/**</code></td><td>copied in as seed files</td></tr><tr><td>per-send <code>workspaceFiles</code></td><td>written before the turn</td></tr></tbody></table><p>The local harness uses this workspace as its working directory. Parent directories can contribute <code>AGENTS.md</code> and <code>.cursor</code> settings. Set <code>local.cwd</code> when you need a clean parent directory. A channel can also provide a different working directory for one session, such as a PR worktree.</p><p>See <a href="./agent-config.html#local-cwd">Agent config: local cwd</a> for the inheritance rules.</p><h2 id="where-does-agentkit-store-session-data" tabindex="-1">Where does agentkit store session data? <a class="header-anchor" href="#where-does-agentkit-store-session-data" aria-label="Permalink to &quot;Where does agentkit store session data?&quot;">​</a></h2><p>Local state uses one directory tree:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>&lt;project&gt;/.agentkit/ # or &lt;stateRoot&gt;/&lt;slug&gt;/ under serve</span></span>
1
+ import{_ as t,c as s,o as a,ag as o}from"./chunks/framework.CAZyNGu9.js";const u=JSON.parse('{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives.","frontmatter":{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives."},"headers":[],"relativePath":"reference/sessions.md","filePath":"reference/sessions.md"}'),n={name:"reference/sessions.md"};function i(d,e,r,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o(`<h1 id="sessions-events-and-streaming" tabindex="-1">Sessions, events, and streaming <a class="header-anchor" href="#sessions-events-and-streaming" aria-label="Permalink to &quot;Sessions, events, and streaming&quot;">​</a></h1><p>A session keeps one conversation, its workspace, and an append-only record of every message and tool call.</p><h2 id="what-does-a-session-contain" tabindex="-1">What does a session contain? <a class="header-anchor" href="#what-does-a-session-contain" aria-label="Permalink to &quot;What does a session contain?&quot;">​</a></h2><p>Each session combines:</p><ul><li>A channel and authenticated caller</li><li>A conversation the caller can continue</li><li>A workspace for local turns</li><li>An NDJSON event stream</li><li>Runtime state needed to resume after a server restart</li></ul><p>Sessions belong to the principal that created them. Follow-up, stream, and list routes return <code>403</code> when another caller tries to access one.</p><h2 id="which-session-identifier-should-i-use" tabindex="-1">Which session identifier should I use? <a class="header-anchor" href="#which-session-identifier-should-i-use" aria-label="Permalink to &quot;Which session identifier should I use?&quot;">​</a></h2><p>Sessions have two identifiers because conversation routing and inspection are different jobs.</p><table tabindex="0"><thead><tr><th>Identifier</th><th>Use it for</th></tr></thead><tbody><tr><td><code>continuationToken</code></td><td>Continue a conversation through its channel</td></tr><tr><td><code>sessionId</code></td><td>Stream events, inspect state, resolve approvals, or run a session-bound tool call</td></tr></tbody></table><p>Channels decide what a continuation token looks like. Slack uses its thread identity. A PR channel can use a key such as <code>pr:owner/repo#1</code>. The built-in HTTP API returns an opaque token and rotates it after each accepted follow-up. Reusing a stale HTTP token returns <code>409</code>.</p><p>Use the continuation token to keep talking. Use the session ID to observe or manage the stored session.</p><h2 id="which-session-modes-are-available" tabindex="-1">Which session modes are available? <a class="header-anchor" href="#which-session-modes-are-available" aria-label="Permalink to &quot;Which session modes are available?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>Mode</th><th>Created by</th><th>What happens after a turn</th></tr></thead><tbody><tr><td><code>chat</code></td><td>HTTP sessions, channel <code>send</code>, Slack, or MCP <code>ask</code></td><td>Waits in <code>session.waiting</code> and accepts follow-ups</td></tr><tr><td><code>task</code></td><td>Markdown schedules and fire-and-forget dispatch</td><td>Ends in <code>session.completed</code> or <code>session.failed</code></td></tr></tbody></table><p>Task sessions don&#39;t accept follow-ups. Trying one returns <code>409</code>.</p><h2 id="what-happens-when-i-send-a-follow-up" tabindex="-1">What happens when I send a follow-up? <a class="header-anchor" href="#what-happens-when-i-send-a-follow-up" aria-label="Permalink to &quot;What happens when I send a follow-up?&quot;">​</a></h2><p>A follow-up to an idle chat session starts another turn. Admission when the session is already busy depends on the channel:</p><table tabindex="0"><thead><tr><th>Path</th><th>Busy-session policy</th></tr></thead><tbody><tr><td>HTTP playground / <code>POST /v1/session/:id</code> / MCP <code>ask</code></td><td><strong>Preempt</strong> (default): interrupt the in-flight turn, wait for it to settle, then run the new message</td></tr><tr><td>Slack mentions / DMs / alert-watch</td><td><strong>Coalesce</strong>: leave the active turn running, enqueue the follow-up, and drain queued asks into one follow-up turn when the active turn finishes (no mid-turn tool/hook inject)</td></tr></tbody></table><p>Pass <code>admission: &quot;coalesce&quot;</code> on <code>send()</code> to opt into the Slack policy from other callers. Omit it (or pass <code>&quot;preempt&quot;</code>) to keep interrupt semantics.</p><p><code>POST /v1/session/:id/stop</code> interrupts a turn without sending a new message. Interrupted turns record <code>turn.failed</code> with <code>&quot;turn interrupted&quot;</code>. This means the turn was preempted. A whole-message Slack <code>stop</code> / <code>@agent stop</code> does the same for that thread and clears pending coalesced nudges.</p><p>Session-bound deterministic tool calls share the same execution lock. They return <code>409 session_busy</code> while a model turn is running.</p><h2 id="which-events-can-i-stream" tabindex="-1">Which events can I stream? <a class="header-anchor" href="#which-events-can-i-stream" aria-label="Permalink to &quot;Which events can I stream?&quot;">​</a></h2><p>Each NDJSON line uses this envelope: <code>{ type, index, sessionId, turnId?, at, data }</code>. The <code>index</code> increases within one session. The <code>at</code> field is an ISO-8601 timestamp.</p><table tabindex="0"><thead><tr><th>Phase</th><th>Events</th><th>What they tell you</th></tr></thead><tbody><tr><td>Session</td><td><code>session.started</code>, <a href="./../ab.html#assign-sticky-variants"><code>ab.assigned</code></a>, <code>session.waiting</code>, <code>session.completed</code>, <code>session.failed</code></td><td>Session creation, A/B enrollment, readiness, and task completion</td></tr><tr><td>Agent</td><td><code>agent.bound</code></td><td>Cursor SDK agent ID and cloud conversation URL</td></tr><tr><td>Input</td><td><code>message.received</code></td><td>A user message was accepted</td></tr><tr><td>Turn</td><td><code>turn.started</code>, <code>turn.completed</code>, <code>turn.failed</code></td><td>Turn status, final result, and token usage</td></tr><tr><td>Steps</td><td><code>step.started</code>, <code>step.completed</code></td><td>Model step boundaries and duration</td></tr><tr><td>Reasoning</td><td><code>reasoning.appended</code>, <code>reasoning.completed</code></td><td>Streamed reasoning blocks</td></tr><tr><td>Reply</td><td><code>message.appended</code>, <code>message.completed</code></td><td>Text deltas and finalized assistant messages</td></tr><tr><td>Tools</td><td><code>actions.requested</code>, <code>action.result</code></td><td>Tool names, validated arguments, outputs, and errors</td></tr><tr><td>Approvals</td><td><code>action.approval_requested</code>, <code>action.approval_resolved</code></td><td>A parked tool call and the human decision</td></tr><tr><td>Subagents</td><td><code>subagent.called</code>, <code>subagent.completed</code></td><td>Delegated work</td></tr></tbody></table><p>Pair <code>actions.requested</code> with <code>action.result</code> to reconstruct the tool trajectory. Read <code>turn.completed.data.usage</code> for input, output, and cache token counts.</p><h2 id="how-do-i-stream-or-replay-session-events" tabindex="-1">How do I stream or replay session events? <a class="header-anchor" href="#how-do-i-stream-or-replay-session-events" aria-label="Permalink to &quot;How do I stream or replay session events?&quot;">​</a></h2><p>One endpoint handles both live streaming and replay:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -N</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;http://127.0.0.1:3000/&lt;slug&gt;/v1/session/ses_…/stream?startIndex=0&#39;</span></span></code></pre></div><p>Pass <code>startIndex</code> to continue after the last event you received. Omit it or pass <code>0</code> to replay the full session before following new events. <code>GET /v1/session/:id/events</code> returns a one-time dump without staying connected.</p><p>Event streams replay from disk after a server restart. Conversation state resumes from the Cursor SDK store.</p><h2 id="what-goes-into-a-local-session-workspace" tabindex="-1">What goes into a local session workspace? <a class="header-anchor" href="#what-goes-into-a-local-session-workspace" aria-label="Permalink to &quot;What goes into a local session workspace?&quot;">​</a></h2><p>The Agent SDK creates a workspace before the first local turn:</p><table tabindex="0"><thead><tr><th>Source path</th><th>Lands as</th></tr></thead><tbody><tr><td><code>instructions.*</code></td><td><code>AGENTS.md</code></td></tr><tr><td><code>skills/*</code></td><td><code>.cursor/skills/&lt;name&gt;/SKILL.md</code></td></tr><tr><td>agent tools (<code>execution: &quot;agent&quot;</code>)</td><td>scripts under <code>.agent-sdk/tools/</code>, with a catalog in <code>AGENTS.md</code></td></tr><tr><td><code>sandbox/workspace/**</code></td><td>copied in as seed files</td></tr><tr><td>per-send <code>workspaceFiles</code></td><td>written before the turn</td></tr></tbody></table><p>The local harness uses this workspace as its working directory. Parent directories can contribute <code>AGENTS.md</code> and <code>.cursor</code> settings. Set <code>local.cwd</code> when you need a clean parent directory. A channel can also provide a different working directory for one session, such as a PR worktree.</p><p>See <a href="./agent-config.html#local-cwd">Agent config: local cwd</a> for the inheritance rules.</p><h2 id="where-does-the-agent-sdk-store-session-data" tabindex="-1">Where does the Agent SDK store session data? <a class="header-anchor" href="#where-does-the-agent-sdk-store-session-data" aria-label="Permalink to &quot;Where does the Agent SDK store session data?&quot;">​</a></h2><p>Local state uses one directory tree:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>&lt;project&gt;/.agent-sdk/ # or &lt;stateRoot&gt;/&lt;slug&gt;/ under serve</span></span>
2
2
  <span class="line"><span> sessions/&lt;id&gt;/session.json # metadata: channel, mode, principal, tokens</span></span>
3
3
  <span class="line"><span> sessions/&lt;id&gt;/events.ndjson # the durable stream</span></span>
4
4
  <span class="line"><span> sessions/&lt;id&gt;/workspace/ # the harness cwd</span></span>
5
5
  <span class="line"><span> traces/&lt;sessionId&gt;.ndjson # written by \`run\`</span></span>
6
6
  <span class="line"><span> runner/ # Cursor SDK conversation store</span></span>
7
- <span class="line"><span> tool-calls/&lt;callId&gt;/ # ephemeral deterministic-call workspaces</span></span></code></pre></div><p>Deleting a session directory removes the session from the server: it disappears from listings and can no longer be streamed or continued. The <code>runner/</code> store keeps its own conversation copy until you remove it. Cloud conversations remain on the Cursor backend.</p><p>Change the root with <code>--state-root</code> or <code>stateRoot</code>. Keep it outside repositories whose parent rules shouldn&#39;t reach the agent. See <a href="./../concepts.html#what-files-can-a-local-session-access">local session workspaces</a>.</p><h2 id="how-do-i-inspect-a-saved-event-stream" tabindex="-1">How do I inspect a saved event stream? <a class="header-anchor" href="#how-do-i-inspect-a-saved-event-stream" aria-label="Permalink to &quot;How do I inspect a saved event stream?&quot;">​</a></h2><p>Use <code>trajectory</code> with a trace or session event file:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agentkit</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> trajectory</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --events</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .agentkit/traces/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">sessionI</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.ndjson</span></span>
8
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agentkit</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> trajectory</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --events</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> &lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">stateRoo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">t</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/sessions/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">i</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/events.ndjson</span></span></code></pre></div><p>The command prints tool calls, the reply, and token usage in the same JSON shape as <code>run</code>. Use <strong>Open trace</strong> in the playground for a visual view.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to &quot;Related&quot;">​</a></h2><ul><li><a href="./http-api.html">HTTP API</a></li><li><a href="./hooks.html">Hooks</a></li><li><a href="./../ab.html">Live A/B metrics</a></li><li><a href="./../concepts.html">How agentkit works</a></li></ul>`,45)])])}const k=t(n,[["render",i]]);export{u as __pageData,k as default};
7
+ <span class="line"><span> tool-calls/&lt;callId&gt;/ # ephemeral deterministic-call workspaces</span></span></code></pre></div><p>Deleting a session directory removes the session from the server: it disappears from listings and can no longer be streamed or continued. The <code>runner/</code> store keeps its own conversation copy until you remove it. Cloud conversations remain on the Cursor backend.</p><p>Change the root with <code>--state-root</code> or <code>stateRoot</code>. Keep it outside repositories whose parent rules shouldn&#39;t reach the agent. See <a href="./../concepts.html#what-files-can-a-local-session-access">local session workspaces</a>.</p><h2 id="how-do-i-inspect-a-saved-event-stream" tabindex="-1">How do I inspect a saved event stream? <a class="header-anchor" href="#how-do-i-inspect-a-saved-event-stream" aria-label="Permalink to &quot;How do I inspect a saved event stream?&quot;">​</a></h2><p>Use <code>trajectory</code> with a trace or session event file:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> trajectory</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --events</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .agent-sdk/traces/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">sessionI</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.ndjson</span></span>
8
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> trajectory</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --events</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> &lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">stateRoo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">t</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/sessions/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">i</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/events.ndjson</span></span></code></pre></div><p>The command prints tool calls, the reply, and token usage in the same JSON shape as <code>run</code>. Use <strong>Open trace</strong> in the playground for a visual view.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to &quot;Related&quot;">​</a></h2><ul><li><a href="./http-api.html">HTTP API</a></li><li><a href="./hooks.html">Hooks</a></li><li><a href="./../ab.html">Live A/B metrics</a></li><li><a href="./../concepts.html">How the Agent SDK works</a></li></ul>`,45)])])}const k=t(n,[["render",i]]);export{u as __pageData,k as default};
@@ -34,7 +34,7 @@ import{_ as i,c as a,o as e,ag as t}from"./chunks/framework.CAZyNGu9.js";const c
34
34
  <span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">message=$(python3 -c &#39;import json,sys; print(json.load(sys.stdin)[&quot;message&quot;])&#39;)</span></span>
35
35
  <span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">printf &#39;%s</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\\\\</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">n&#39; &quot;$message&quot;</span></span>
36
36
  <span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
37
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>On the local runtime, scripts land under <code>.agentkit/tools/</code> in the session workspace with a catalog in <code>AGENTS.md</code>. On cloud, the catalog and script bodies travel on the first prompt.</p><h2 id="gate-a-tool-on-human-approval" tabindex="-1">Gate a tool on human approval <a class="header-anchor" href="#gate-a-tool-on-human-approval" aria-label="Permalink to &quot;Gate a tool on human approval&quot;">​</a></h2><p>A server tool can require a person to sign off before it runs. Set <code>needsApproval</code> to <code>true</code>, or to a predicate over the validated input:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineTool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
37
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>On the local runtime, scripts land under <code>.agent-sdk/tools/</code> in the session workspace with a catalog in <code>AGENTS.md</code>. On cloud, the catalog and script bodies travel on the first prompt.</p><h2 id="gate-a-tool-on-human-approval" tabindex="-1">Gate a tool on human approval <a class="header-anchor" href="#gate-a-tool-on-human-approval" aria-label="Permalink to &quot;Gate a tool on human approval&quot;">​</a></h2><p>A server tool can require a person to sign off before it runs. Set <code>needsApproval</code> to <code>true</code>, or to a predicate over the validated input:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineTool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
38
38
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> description: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;Promote a verified build to an environment.&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
39
39
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> needsApproval: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// or: (input) =&gt; input.environment === &quot;production&quot;</span></span>
40
40
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> inputSchema: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">object</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
@@ -49,9 +49,9 @@ import{_ as i,c as a,o as e,ag as t}from"./chunks/framework.CAZyNGu9.js";const c
49
49
  <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;content-type: application/json&#39;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
50
50
  <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;{&quot;input&quot;:{&quot;prUrl&quot;:&quot;https://github.com/acme/checkout/pull/42&quot;}}&#39;</span></span>
51
51
  <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># {&quot;ok&quot;:true,&quot;toolName&quot;:&quot;inspect_pr&quot;,&quot;callId&quot;:&quot;tool_inspect_pr_…&quot;,</span></span>
52
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># &quot;isError&quot;:false,&quot;result&quot;:{…},&quot;durationMs&quot;:12}</span></span></code></pre></div><p>From the CLI, which starts an ephemeral server unless <code>--url</code> targets a running one:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agentkit</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> inspect_pr</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
52
+ <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># &quot;isError&quot;:false,&quot;result&quot;:{…},&quot;durationMs&quot;:12}</span></span></code></pre></div><p>From the CLI, which starts an ephemeral server unless <code>--url</code> targets a running one:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> inspect_pr</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
53
53
  <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;{&quot;prUrl&quot;:&quot;https://github.com/acme/checkout/pull/42&quot;}&#39;</span></span>
54
- <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agentkit</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> inspect_pr</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
54
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> inspect_pr</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
55
55
  <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --url</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
56
56
  <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;{&quot;prUrl&quot;:&quot;https://github.com/acme/checkout/pull/42&quot;}&#39;</span></span></code></pre></div><p>Programmatically, <code>callTool(toolName, input, options?)</code> is available on the serve handle, on channel route handlers and <code>onStart</code> args, and on schedule <code>run</code> handlers, so a channel can mix deterministic calls with model turns, fetching PR metadata deterministically and then <code>send()</code>ing the review prompt:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> outcome</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> handle.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">callTool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;inspect_pr&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, {</span></span>
57
57
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> prUrl: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;https://github.com/acme/checkout/pull/42&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
@@ -1 +1 @@
1
- import{_ as a,c as o,o as t,ag as l}from"./chunks/framework.CAZyNGu9.js";const f=JSON.parse('{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent.","frontmatter":{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent."},"headers":[],"relativePath":"scaffolding-agents.md","filePath":"scaffolding-agents.md"}'),r={name:"scaffolding-agents.md"};function i(s,e,n,d,h,c){return t(),o("div",null,[...e[0]||(e[0]=[l('<h1 id="scaffold-an-agent-with-cursor" tabindex="-1">Scaffold an agent with Cursor <a class="header-anchor" href="#scaffold-an-agent-with-cursor" aria-label="Permalink to &quot;Scaffold an agent with Cursor&quot;">​</a></h1><p>Turn an idea into a verified agent while Cursor guides you through each decision.</p><h2 id="what-does-the-create-agent-skill-do" tabindex="-1">What does the create-agent skill do? <a class="header-anchor" href="#what-does-the-create-agent-skill-do" aria-label="Permalink to &quot;What does the create-agent skill do?&quot;">​</a></h2><p>The bundled <a href="./../skills/create-agent/SKILL.html"><code>create-agent</code> skill</a> turns your goal into a small working project. Have Cursor read that file and follow it (monorepo path: <code>packages/agent-serve/skills/create-agent/SKILL.md</code>).</p><p>Cursor will:</p><ul><li>Ask only for choices missing from your prompt</li><li>Recommend defaults based on what you want to build</li><li>Show you the plan and file tree before writing files</li><li>Create the agent after you confirm the plan</li><li>Run structural checks, a real turn, and a smoke eval</li></ul><p>Use this skill for a new agent. Use <a href="./hillclimbing.html"><code>hillclimb</code></a> (<code>skills/hillclimb/SKILL.md</code>) when an existing agent works but needs better results.</p><h2 id="how-do-i-start-a-guided-scaffold" tabindex="-1">How do I start a guided scaffold? <a class="header-anchor" href="#how-do-i-start-a-guided-scaffold" aria-label="Permalink to &quot;How do I start a guided scaffold?&quot;">​</a></h2><p>Describe the outcome and any constraints you already know:</p><blockquote><p>Build a local weather agent for the playground. Give it one tool for current conditions and add a smoke eval. Guide me through the remaining decisions.</p></blockquote><p>More detail means fewer questions. Include a channel, runtime, model, or required integration when those choices are fixed.</p><h2 id="which-choices-will-cursor-ask-me-to-make" tabindex="-1">Which choices will Cursor ask me to make? <a class="header-anchor" href="#which-choices-will-cursor-ask-me-to-make" aria-label="Permalink to &quot;Which choices will Cursor ask me to make?&quot;">​</a></h2><p>Cursor fills gaps in two short rounds:</p><ul><li><strong>Identity:</strong> purpose, project name, and location</li><li><strong>Runtime:</strong> local or cloud</li><li><strong>Model:</strong> the default model or another Cursor model</li><li><strong>Channels:</strong> playground and HTTP, Slack, GitHub, a webhook, or a schedule</li><li><strong>MCP connections:</strong> remote or local MCP servers</li><li><strong>Capabilities:</strong> tools, skills, subagents, hooks, seed files, approvals, and evals</li></ul><p>Questions adapt to your goal. A playground chat agent won&#39;t get cloud-repository questions. A local agent won&#39;t get cloud setup questions.</p><h2 id="what-happens-before-cursor-writes-files" tabindex="-1">What happens before Cursor writes files? <a class="header-anchor" href="#what-happens-before-cursor-writes-files" aria-label="Permalink to &quot;What happens before Cursor writes files?&quot;">​</a></h2><p>Cursor shows one plan with the choices it made and the folders it will create. Choose <strong>Scaffold it</strong> to continue or <strong>Adjust something</strong> to change the plan.</p><p>No files change before you approve this step.</p><h2 id="what-will-cursor-create" tabindex="-1">What will Cursor create? <a class="header-anchor" href="#what-will-cursor-create" aria-label="Permalink to &quot;What will Cursor create?&quot;">​</a></h2><p>A first version usually includes:</p><ul><li><code>agent/agent.ts</code> for the model and runtime</li><li><code>agent/instructions.md</code> for the always-on prompt</li><li>One or two tools under <code>agent/tools/</code></li><li>Any channels or MCP connections you selected</li><li><code>evals/evals.config.ts</code> and one smoke eval</li></ul><p>Cursor keeps the first version small. Side-effecting server tools use <code>needsApproval</code>. Deterministic setup, such as fetching a pull request, stays in host code instead of model instructions.</p><p>See <a href="./reference/project-layout.html">Project layout</a> for every supported folder.</p><h2 id="how-does-cursor-verify-the-scaffold" tabindex="-1">How does Cursor verify the scaffold? <a class="header-anchor" href="#how-does-cursor-verify-the-scaffold" aria-label="Permalink to &quot;How does Cursor verify the scaffold?&quot;">​</a></h2><p>Cursor checks the project in this order:</p><ol><li>Run <code>agentkit validate</code> and fix every error</li><li>Inspect the discovered surface with <code>info --json</code></li><li>Call each server tool directly with validated sample input</li><li>Run one end-to-end model turn</li><li>Run the smoke eval</li><li>Run the project&#39;s TypeScript check</li></ol><p>Validation, discovery, direct server-tool calls, and server startup work without a Cursor credential. Model turns and evals need <code>CURSOR_API_KEY</code> or a saved <code>agentkit login</code>.</p><h2 id="what-happens-after-the-first-agent-works" tabindex="-1">What happens after the first agent works? <a class="header-anchor" href="#what-happens-after-the-first-agent-works" aria-label="Permalink to &quot;What happens after the first agent works?&quot;">​</a></h2><p>Choose one to three fixed inputs, define what should improve, and name what must stay unchanged. Then have Cursor follow <a href="./../skills/hillclimb/SKILL.html"><code>skills/hillclimb/SKILL.md</code></a>.</p><p>The hillclimb skill measures a baseline, changes one lever, runs the same inputs again, and adds an eval for each improvement you keep.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to &quot;Related&quot;">​</a></h2><ul><li><a href="./quickstart.html">Build your first PR approver</a></li><li><a href="./building-with-agents.html">Building agents with agents</a></li><li><a href="./evals.html">Evals</a></li><li><a href="./hillclimbing.html">Hillclimbing</a></li><li><a href="./reference/project-layout.html">Project layout</a></li></ul>',32)])])}const p=a(r,[["render",i]]);export{f as __pageData,p as default};
1
+ import{_ as a,c as o,o as t,ag as l}from"./chunks/framework.CAZyNGu9.js";const f=JSON.parse('{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent.","frontmatter":{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent."},"headers":[],"relativePath":"scaffolding-agents.md","filePath":"scaffolding-agents.md"}'),r={name:"scaffolding-agents.md"};function s(i,e,n,d,h,c){return t(),o("div",null,[...e[0]||(e[0]=[l('<h1 id="scaffold-an-agent-with-cursor" tabindex="-1">Scaffold an agent with Cursor <a class="header-anchor" href="#scaffold-an-agent-with-cursor" aria-label="Permalink to &quot;Scaffold an agent with Cursor&quot;">​</a></h1><p>Turn an idea into a verified agent while Cursor guides you through each decision.</p><h2 id="what-does-the-create-agent-skill-do" tabindex="-1">What does the create-agent skill do? <a class="header-anchor" href="#what-does-the-create-agent-skill-do" aria-label="Permalink to &quot;What does the create-agent skill do?&quot;">​</a></h2><p>The bundled <a href="./../skills/create-agent/SKILL.html"><code>create-agent</code> skill</a> turns your goal into a small working project. Have Cursor read that file and follow it (monorepo path: <code>packages/agent-serve/skills/create-agent/SKILL.md</code>).</p><p>Cursor will:</p><ul><li>Ask only for choices missing from your prompt</li><li>Recommend defaults based on what you want to build</li><li>Show you the plan and file tree before writing files</li><li>Create the agent after you confirm the plan</li><li>Run structural checks, a real turn, and a smoke eval</li></ul><p>Use this skill for a new agent. Use <a href="./hillclimbing.html"><code>hillclimb</code></a> (<code>skills/hillclimb/SKILL.md</code>) when an existing agent works but needs better results.</p><h2 id="how-do-i-start-a-guided-scaffold" tabindex="-1">How do I start a guided scaffold? <a class="header-anchor" href="#how-do-i-start-a-guided-scaffold" aria-label="Permalink to &quot;How do I start a guided scaffold?&quot;">​</a></h2><p>Describe the outcome and any constraints you already know:</p><blockquote><p>Build a local weather agent for the playground. Give it one tool for current conditions and add a smoke eval. Guide me through the remaining decisions.</p></blockquote><p>More detail means fewer questions. Include a channel, runtime, model, or required integration when those choices are fixed.</p><h2 id="which-choices-will-cursor-ask-me-to-make" tabindex="-1">Which choices will Cursor ask me to make? <a class="header-anchor" href="#which-choices-will-cursor-ask-me-to-make" aria-label="Permalink to &quot;Which choices will Cursor ask me to make?&quot;">​</a></h2><p>Cursor fills gaps in two short rounds:</p><ul><li><strong>Identity:</strong> purpose, project name, and location</li><li><strong>Runtime:</strong> local or cloud</li><li><strong>Model:</strong> the default model or another Cursor model</li><li><strong>Channels:</strong> playground and HTTP, Slack, GitHub, a webhook, or a schedule</li><li><strong>MCP connections:</strong> remote or local MCP servers</li><li><strong>Capabilities:</strong> tools, skills, subagents, hooks, seed files, approvals, and evals</li></ul><p>Questions adapt to your goal. A playground chat agent won&#39;t get cloud-repository questions. A local agent won&#39;t get cloud setup questions.</p><h2 id="what-happens-before-cursor-writes-files" tabindex="-1">What happens before Cursor writes files? <a class="header-anchor" href="#what-happens-before-cursor-writes-files" aria-label="Permalink to &quot;What happens before Cursor writes files?&quot;">​</a></h2><p>Cursor shows one plan with the choices it made and the folders it will create. Choose <strong>Scaffold it</strong> to continue or <strong>Adjust something</strong> to change the plan.</p><p>No files change before you approve this step.</p><h2 id="what-will-cursor-create" tabindex="-1">What will Cursor create? <a class="header-anchor" href="#what-will-cursor-create" aria-label="Permalink to &quot;What will Cursor create?&quot;">​</a></h2><p>A first version usually includes:</p><ul><li><code>agent/agent.ts</code> for the model and runtime</li><li><code>agent/instructions.md</code> for the always-on prompt</li><li>One or two tools under <code>agent/tools/</code></li><li>Any channels or MCP connections you selected</li><li><code>evals/evals.config.ts</code> and one smoke eval</li></ul><p>Cursor keeps the first version small. Side-effecting server tools use <code>needsApproval</code>. Deterministic setup, such as fetching a pull request, stays in host code instead of model instructions.</p><p>See <a href="./reference/project-layout.html">Project layout</a> for every supported folder.</p><h2 id="how-does-cursor-verify-the-scaffold" tabindex="-1">How does Cursor verify the scaffold? <a class="header-anchor" href="#how-does-cursor-verify-the-scaffold" aria-label="Permalink to &quot;How does Cursor verify the scaffold?&quot;">​</a></h2><p>Cursor checks the project in this order:</p><ol><li>Run <code>agent-sdk validate</code> and fix every error</li><li>Inspect the discovered surface with <code>info --json</code></li><li>Call each server tool directly with validated sample input</li><li>Run one end-to-end model turn</li><li>Run the smoke eval</li><li>Run the project&#39;s TypeScript check</li></ol><p>Validation, discovery, direct server-tool calls, and server startup work without a Cursor credential. Model turns and evals need <code>CURSOR_API_KEY</code> or a saved <code>agent-sdk login</code>.</p><h2 id="what-happens-after-the-first-agent-works" tabindex="-1">What happens after the first agent works? <a class="header-anchor" href="#what-happens-after-the-first-agent-works" aria-label="Permalink to &quot;What happens after the first agent works?&quot;">​</a></h2><p>Choose one to three fixed inputs, define what should improve, and name what must stay unchanged. Then have Cursor follow <a href="./../skills/hillclimb/SKILL.html"><code>skills/hillclimb/SKILL.md</code></a>.</p><p>The hillclimb skill measures a baseline, changes one lever, runs the same inputs again, and adds an eval for each improvement you keep.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to &quot;Related&quot;">​</a></h2><ul><li><a href="./quickstart.html">Build your first PR approver</a></li><li><a href="./building-with-agents.html">Building agents with agents</a></li><li><a href="./evals.html">Evals</a></li><li><a href="./hillclimbing.html">Hillclimbing</a></li><li><a href="./reference/project-layout.html">Project layout</a></li></ul>',32)])])}const p=a(r,[["render",s]]);export{f as __pageData,p as default};
@@ -1 +1 @@
1
- import{_ as a,c as o,o as t,ag as l}from"./chunks/framework.CAZyNGu9.js";const f=JSON.parse('{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent.","frontmatter":{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent."},"headers":[],"relativePath":"scaffolding-agents.md","filePath":"scaffolding-agents.md"}'),r={name:"scaffolding-agents.md"};function i(s,e,n,d,h,c){return t(),o("div",null,[...e[0]||(e[0]=[l("",32)])])}const p=a(r,[["render",i]]);export{f as __pageData,p as default};
1
+ import{_ as a,c as o,o as t,ag as l}from"./chunks/framework.CAZyNGu9.js";const f=JSON.parse('{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent.","frontmatter":{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent."},"headers":[],"relativePath":"scaffolding-agents.md","filePath":"scaffolding-agents.md"}'),r={name:"scaffolding-agents.md"};function s(i,e,n,d,h,c){return t(),o("div",null,[...e[0]||(e[0]=[l("",32)])])}const p=a(r,[["render",s]]);export{f as __pageData,p as default};
@@ -1,4 +1,4 @@
1
- import{_ as t,c as e,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse(`{"title":"Storage","description":"Point agentkit's durable storage at a backend you own with defineStorage.","frontmatter":{"title":"Storage","description":"Point agentkit's durable storage at a backend you own with defineStorage."},"headers":[],"relativePath":"storage.md","filePath":"storage.md"}`),n={name:"storage.md"};function o(h,s,r,d,l,p){return i(),e("div",null,[...s[0]||(s[0]=[a(`<h1 id="storage" tabindex="-1">Storage <a class="header-anchor" href="#storage" aria-label="Permalink to &quot;Storage&quot;">​</a></h1><p>agentkit owns durable storage for sessions, continuation tokens, reminders, playground eval history, and live A/B samples. It chooses the keys (under <code>agentkit/v1/</code>), when to read and write, and how to restore after restart.</p><p>Keys have bounded length: caller-controlled segments (channel ids, continuation tokens) are URI-encoded, and any segment past 256 encoded bytes is replaced by its <code>sha256:…</code> digest — deterministically, so writes and lookups always agree. Backends can rely on this instead of imposing their own key-length caps (which would silently drop writes, since a throwing <code>put</code> is at-most-once).</p><p>By default that storage lives under <code>--state-root</code> on local disk. Fine for one machine; it does not survive replacing the host.</p><p>To keep the same framework storage across hosts, plug in a key-value backend with <code>agent/storage.ts</code>. You provide <code>put</code> / <code>get</code> / <code>delete</code> / <code>list</code>. agentkit does the rest.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// agent/storage.ts</span></span>
1
+ import{_ as t,c as e,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse(`{"title":"Storage","description":"Point the Agent SDK's durable storage at a backend you own with defineStorage.","frontmatter":{"title":"Storage","description":"Point the Agent SDK's durable storage at a backend you own with defineStorage."},"headers":[],"relativePath":"storage.md","filePath":"storage.md"}`),n={name:"storage.md"};function o(h,s,r,d,l,p){return i(),e("div",null,[...s[0]||(s[0]=[a(`<h1 id="storage" tabindex="-1">Storage <a class="header-anchor" href="#storage" aria-label="Permalink to &quot;Storage&quot;">​</a></h1><p>The Agent SDK owns durable storage for sessions, continuation tokens, reminders, playground eval history, and live A/B samples. It chooses the keys (under <code>agentkit/v1/</code>), when to read and write, and how to restore after restart.</p><p>Keys have bounded length: caller-controlled segments (channel ids, continuation tokens) are URI-encoded, and any segment past 256 encoded bytes is replaced by its <code>sha256:…</code> digest — deterministically, so writes and lookups always agree. Backends can rely on this instead of imposing their own key-length caps (which would silently drop writes, since a throwing <code>put</code> is at-most-once).</p><p>By default that storage lives under <code>--state-root</code> on local disk. Fine for one machine; it does not survive replacing the host.</p><p>To keep the same framework storage across hosts, plug in a key-value backend with <code>agent/storage.ts</code>. You provide <code>put</code> / <code>get</code> / <code>delete</code> / <code>list</code>. The Agent SDK does the rest.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// agent/storage.ts</span></span>
2
2
  <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineStorage } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july/storage&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
3
3
  <span class="line"></span>
4
4
  <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineStorage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
@@ -14,8 +14,8 @@ import{_ as t,c as e,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const c
14
14
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> restore: { maxSessions: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">500</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
15
15
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
16
16
  <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // put / get / delete / list …</span></span>
17
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><table tabindex="0"><thead><tr><th>Knob</th><th>Default</th><th>Meaning</th></tr></thead><tbody><tr><td><code>debounceMs</code></td><td>unset (once per turn)</td><td>Wait this long after activity before writing event batches</td></tr><tr><td><code>restore</code></td><td>caps below</td><td>How much to load at serve start</td></tr><tr><td><code>restore.maxSessions</code></td><td><code>1000</code></td><td>Max sessions loaded at serve start</td></tr><tr><td><code>restore.maxAgeMs</code></td><td>30 days</td><td>Skip older sessions at serve start</td></tr><tr><td><code>restore.maxTotalBytes</code></td><td>1 GiB</td><td>Stop loading once this budget is reached</td></tr></tbody></table><p>Set <code>restore: &quot;off&quot;</code> on high-traffic hosts. Sessions then load when a follow-up arrives instead of at startup.</p><h2 id="restore-after-restart" tabindex="-1">Restore after restart <a class="header-anchor" href="#restore-after-restart" aria-label="Permalink to &quot;Restore after restart&quot;">​</a></h2><p>With <code>get</code> and <code>list</code>, serve can rebuild local state from your store:</p><ul><li>At startup, agentkit loads recent sessions up to the restore caps. Local disk wins when both sides have the same session. Reminders hydrate the same way into <code>--state-root/reminders</code>.</li><li>On demand, a missing continuation token resolves through the store and resumes that session.</li><li>Playground eval history and A/B aggregates can load from the same sink.</li></ul><p>A turn in flight at crash time is not replayed. The next follow-up resumes from the last flushed state.</p><h2 id="author-kv-ctx-host-kv" tabindex="-1">Author KV (<code>ctx.host.kv</code>) <a class="header-anchor" href="#author-kv-ctx-host-kv" aria-label="Permalink to &quot;Author KV (\`ctx.host.kv\`)&quot;">​</a></h2><p>Handlers can store their own JSON under the same sink without minting framework keys:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ctx.host.kv.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">put</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;alert-memory/abc&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, { updated: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;…&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
18
- <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> prior</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ctx.host.kv.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;alert-memory/abc&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><p>agentkit prefixes author keys as <code>agentkit/v1/{agent}/kv/{key}</code> (same bounded encoding as continuation tokens). Writes <strong>await</strong> the sink and propagate errors — unlike session mirrors, which are at-most-once.</p><p>Without <code>agent/storage.ts</code>, <code>host.kv</code> falls back to files under <code>--state-root/kv</code>. That is fine for local dogfood; it does <strong>not</strong> survive replacing the host. For Cursor-managed hosting, prefer <code>@cursor/july/storage/cursor-hosted</code> so sessions and author KV share the platform Bugbot tables through a control-plane HTTP proxy (authenticated as the deployment pod credential — engines never receive a database URL). For self-hosted Postgres you own, use <code>@cursor/july/storage/postgres-kv</code> and supply <code>BUGBOTDB_URL</code> / <code>AGENT_SERVE_DEPLOYMENT_ID</code> yourself.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// agent/storage.ts — Cursor-managed hosting</span></span>
17
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><table tabindex="0"><thead><tr><th>Knob</th><th>Default</th><th>Meaning</th></tr></thead><tbody><tr><td><code>debounceMs</code></td><td>unset (once per turn)</td><td>Wait this long after activity before writing event batches</td></tr><tr><td><code>restore</code></td><td>caps below</td><td>How much to load at serve start</td></tr><tr><td><code>restore.maxSessions</code></td><td><code>1000</code></td><td>Max sessions loaded at serve start</td></tr><tr><td><code>restore.maxAgeMs</code></td><td>30 days</td><td>Skip older sessions at serve start</td></tr><tr><td><code>restore.maxTotalBytes</code></td><td>1 GiB</td><td>Stop loading once this budget is reached</td></tr></tbody></table><p>Set <code>restore: &quot;off&quot;</code> on high-traffic hosts. Sessions then load when a follow-up arrives instead of at startup.</p><h2 id="restore-after-restart" tabindex="-1">Restore after restart <a class="header-anchor" href="#restore-after-restart" aria-label="Permalink to &quot;Restore after restart&quot;">​</a></h2><p>With <code>get</code> and <code>list</code>, serve can rebuild local state from your store:</p><ul><li>At startup, the Agent SDK loads recent sessions up to the restore caps. Local disk wins when both sides have the same session. Reminders hydrate the same way into <code>--state-root/reminders</code>.</li><li>On demand, a missing continuation token resolves through the store and resumes that session.</li><li>Playground eval history and A/B aggregates can load from the same sink.</li></ul><p>A turn in flight at crash time is not replayed. The next follow-up resumes from the last flushed state.</p><h2 id="author-kv-ctx-host-kv" tabindex="-1">Author KV (<code>ctx.host.kv</code>) <a class="header-anchor" href="#author-kv-ctx-host-kv" aria-label="Permalink to &quot;Author KV (\`ctx.host.kv\`)&quot;">​</a></h2><p>Handlers can store their own JSON under the same sink without minting framework keys:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ctx.host.kv.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">put</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;alert-memory/abc&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, { updated: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;…&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
18
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> prior</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ctx.host.kv.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;alert-memory/abc&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><p>The Agent SDK prefixes author keys as <code>agentkit/v1/{agent}/kv/{key}</code> (same bounded encoding as continuation tokens). Writes <strong>await</strong> the sink and propagate errors — unlike session mirrors, which are at-most-once.</p><p>Without <code>agent/storage.ts</code>, <code>host.kv</code> falls back to files under <code>--state-root/kv</code>. That is fine for local dogfood; it does <strong>not</strong> survive replacing the host. For Cursor-managed hosting, prefer <code>@cursor/july/storage/cursor-hosted</code> so sessions and author KV share the platform Bugbot tables through a control-plane HTTP proxy (authenticated as the deployment pod credential — engines never receive a database URL). For self-hosted Postgres you own, use <code>@cursor/july/storage/postgres-kv</code> and supply <code>BUGBOTDB_URL</code> / <code>AGENT_SERVE_DEPLOYMENT_ID</code> yourself.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// agent/storage.ts — Cursor-managed hosting</span></span>
19
19
  <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineStorage } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july/storage&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
20
20
  <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { cursorHostedStorage } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july/storage/cursor-hosted&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
21
21
  <span class="line"></span>
@@ -0,0 +1 @@
1
+ import{_ as t,c as e,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse(`{"title":"Storage","description":"Point the Agent SDK's durable storage at a backend you own with defineStorage.","frontmatter":{"title":"Storage","description":"Point the Agent SDK's durable storage at a backend you own with defineStorage."},"headers":[],"relativePath":"storage.md","filePath":"storage.md"}`),n={name:"storage.md"};function o(h,s,r,d,l,p){return i(),e("div",null,[...s[0]||(s[0]=[a("",27)])])}const g=t(n,[["render",o]]);export{c as __pageData,g as default};
@@ -0,0 +1 @@
1
+ import{_ as t,c as o,o as a,ag as d}from"./chunks/framework.CAZyNGu9.js";const p=JSON.parse('{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail.","frontmatter":{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail."},"headers":[],"relativePath":"troubleshooting.md","filePath":"troubleshooting.md"}'),r={name:"troubleshooting.md"};function s(n,e,i,c,h,l){return a(),o("div",null,[...e[0]||(e[0]=[d('<h1 id="fix-common-agent-problems" tabindex="-1">Fix common agent problems <a class="header-anchor" href="#fix-common-agent-problems" aria-label="Permalink to &quot;Fix common agent problems&quot;">​</a></h1><p>Start with four checks, in order:</p><ol><li>Project discovery: <code>agent-sdk validate --dir .</code></li><li>Whether the serve process is running</li><li>What the playground or HTTP API shows</li><li>The session event stream (trace)</li></ol><p>Match your symptom below. Keep the commands as <code>agent-sdk</code>; see <a href="./README.html#run-the-cli">Run the CLI</a> if you still need an alias.</p><h2 id="what-if-serve-or-the-playground-looks-wrong" tabindex="-1">What if serve or the playground looks wrong? <a class="header-anchor" href="#what-if-serve-or-the-playground-looks-wrong" aria-label="Permalink to &quot;What if serve or the playground looks wrong?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>serve</code> won&#39;t start</td><td>Run <code>agent-sdk validate --dir .</code> and fix the reported errors.</td></tr><tr><td>Playground is blank or says there are no agents</td><td>The UI needs a running <code>serve</code> process. Building the playground assets alone is not enough.</td></tr><tr><td>Edits to the playground don&#39;t show up</td><td>Use <code>serve --dev</code> and open the printed playground HMR URL (often port <code>5273</code>), not only the static <code>:3000</code> URL.</td></tr><tr><td>Sessions exist on disk but the playground list is empty</td><td>The list shows sessions for the authenticated caller. In <code>--dev</code> on loopback the list is wider. Otherwise open <code>/&lt;slug&gt;/playground?sessionId=ses_…</code> or inspect <code>sessions/</code> under your state root.</td></tr><tr><td>Port 3000 or 5273 is already in use</td><td>Find and stop the listener (<code>lsof -iTCP:3000 -sTCP:LISTEN</code> on macOS/Linux), and any leftover Vite or webhook-forwarder processes.</td></tr></tbody></table><h2 id="what-if-a-model-turn-goes-wrong" tabindex="-1">What if a model turn goes wrong? <a class="header-anchor" href="#what-if-a-model-turn-goes-wrong" aria-label="Permalink to &quot;What if a model turn goes wrong?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td>Built-in file reads and greps fail; the turn retries for a long time</td><td>Run under Node 22.13+ (or <code>tsx</code>), never Bun. Look for <code>NGHTTP2_FRAME_SIZE_ERROR</code> in logs.</td></tr><tr><td>The turn fails immediately with an API-key error</td><td>Sign in with <code>agent-sdk login</code>, or set <code>CURSOR_API_KEY</code>. Discovery, <code>info</code>, <code>call</code>, and serve bring-up work without a key; model turns need one.</td></tr><tr><td>Replies quote rules or <code>AGENTS.md</code> from outside your agent project</td><td>The session workspace inherited parent-folder config. Point <code>defineAgent({ local: { cwd } })</code> outside that tree, or set <code>--state-root</code> to a clean directory (for example under <code>/tmp</code>).</td></tr><tr><td>Server tools, skills, or workspace seed files never appear</td><td>The agent runtime is <code>cloud</code>. Those features apply on the local runtime. <code>validate</code> warns when this combination is present.</td></tr><tr><td><code>validate</code> and <code>run</code> succeed, but typecheck fails in CI</td><td>The CLI runs TypeScript with type-stripping only. Keep tool <code>execute</code> return types as object literals or <code>type</code> aliases, not <code>interface</code> types.</td></tr><tr><td>Login works, but turns are rejected when using custom API hosts</td><td>Point login and model traffic at the same host (<code>CURSOR_API_BASE_URL</code> and <code>CURSOR_BACKEND_URL</code>). A key from one host is rejected by the other.</td></tr></tbody></table><h2 id="what-if-the-http-api-returns-an-error" tabindex="-1">What if the HTTP API returns an error? <a class="header-anchor" href="#what-if-the-http-api-returns-an-error" aria-label="Permalink to &quot;What if the HTTP API returns an error?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>409</code> on a follow-up message</td><td>Refresh the <code>continuationToken</code> (it rotates on each accepted follow-up), wait if the session is busy, or confirm the session is a chat session (task and schedule sessions are not followable).</td></tr><tr><td><code>409 session_busy</code> on <code>call --session</code></td><td>Wait for the model turn to finish, or omit <code>--session</code> for a one-off call.</td></tr><tr><td><code>403</code> on stream or follow-up</td><td>Use the same auth identity that created the session. Off localhost, pass <code>--bearer-token</code> and send it on every request.</td></tr><tr><td>Works on localhost; blocked through a tunnel or LAN</td><td>Default auth allows only direct loopback callers. Share the host with <code>--bearer-token &lt;secret&gt;</code> (or authored <code>bearerAuth</code>). Use <code>--allow-anonymous</code> only on a trusted private network.</td></tr><tr><td>A channel route fails to compile with a schema type error</td><td><code>GET</code> routes need a Zod <code>querySchema</code>. <code>POST</code> / <code>PUT</code> / <code>PATCH</code> need a Zod <code>bodySchema</code>. Use <code>z.object({})</code> or <code>z.unknown()</code> for open shapes.</td></tr></tbody></table><h2 id="what-if-github-webhooks-misbehave" tabindex="-1">What if GitHub webhooks misbehave? <a class="header-anchor" href="#what-if-github-webhooks-misbehave" aria-label="Permalink to &quot;What if GitHub webhooks misbehave?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>github forward</code> returns 401 on every delivery, but the hook was created</td><td>Clear <code>GITHUB_TOKEN</code> and <code>GH_TOKEN</code> for that command. The forwarder uses your <code>gh</code> CLI login: <code>GITHUB_TOKEN= GH_TOKEN= agent-sdk github forward …</code></td></tr><tr><td><code>Hook already exists</code> when starting a forwarder</td><td>GitHub allows one forwarder per repo. Run a single <code>github forward --dir &lt;parent&gt;</code> and stop stale forwarders.</td></tr><tr><td>Deliveries rejected outside <code>--dev</code></td><td>Set <code>GITHUB_WEBHOOK_SECRET</code> on the server and on the signer. Without a secret, the channel stays loopback-only.</td></tr><tr><td>You lack repo admin and can&#39;t forward</td><td>Use <code>agent-sdk github replay &lt;pr-url&gt;</code>. It needs pull access only and posts signed test payloads.</td></tr></tbody></table><h2 id="what-if-slack-stays-quiet" tabindex="-1">What if Slack stays quiet? <a class="header-anchor" href="#what-if-slack-stays-quiet" aria-label="Permalink to &quot;What if Slack stays quiet?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td>Logs show <code>channel idle … missing credentials</code></td><td>Expected when tokens are missing. Run <code>agent-sdk slack create --dir &lt;agent&gt;</code> to provision the app and write the tokens, or set <code>&lt;PREFIX&gt;_SLACK_BOT_TOKEN</code> and <code>&lt;PREFIX&gt;_SLACK_APP_TOKEN</code> per agent yourself, then run <code>agent-sdk slack doctor --prefix &lt;PREFIX&gt;</code>.</td></tr><tr><td><code>slack create</code> reports the app needs admin approval</td><td>The workspace requires admin approval for new apps. A Slack workspace admin approves it at the printed link (in the dashboard: <strong>Approve in Slack</strong>), then re-run <code>agent-sdk slack create</code> (or <strong>Retry</strong> in the dashboard).</td></tr><tr><td>The bot ignores ordinary channel posts</td><td>Default engagement is mentions and DMs only. Enable <code>engagement.channelPosts</code> with an allowlist, and subscribe the app to <code>message.channels</code> / <code>message.groups</code>.</td></tr><tr><td>Approve / Deny buttons do nothing</td><td>Re-import a Slack app manifest with interactivity enabled. Channels that post approval cards need <code>toolApprovals: true</code> (and <code>interactivity: true</code> when you compose events by hand).</td></tr></tbody></table><h2 id="what-if-host-mcp-oauth-fails" tabindex="-1">What if host MCP OAuth fails? <a class="header-anchor" href="#what-if-host-mcp-oauth-fails" aria-label="Permalink to &quot;What if host MCP OAuth fails?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>must be defineConnection({ url, oauth: true })</code></td><td>The connection file needs <code>oauth: true</code>, or you passed the wrong connection name to <code>agent-sdk mcp oauth</code>.</td></tr><tr><td>Local auth works; hosted calls unauthorized</td><td>Run <code>agent-sdk mcp oauth &lt;name&gt; --store</code>, confirm names with <code>agent-sdk secrets list &lt;slug&gt;</code>, then redeploy.</td></tr><tr><td>Model asks for <code>mcp_auth</code> or IDE MCP for a privileged server</td><td>That connection is likely <code>hostOnly</code>. Call it from a host tool via <code>ctx.host.mcp</code>, and update instructions.</td></tr></tbody></table><p>See <a href="./guides/mcp-oauth.html">Host MCP OAuth</a> and <a href="./../skills/mcp-auth/SKILL.html"><code>skills/mcp-auth/SKILL.md</code></a>.</p><h2 id="what-if-schedules-reminders-or-approvals-stall" tabindex="-1">What if schedules, reminders, or approvals stall? <a class="header-anchor" href="#what-if-schedules-reminders-or-approvals-stall" aria-label="Permalink to &quot;What if schedules, reminders, or approvals stall?&quot;">​</a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td>A schedule or reminder never fires under <code>--dev</code></td><td>Dev mode does not auto-fire. Trigger with <code>POST /&lt;slug&gt;/v1/dev/schedules/&lt;id&gt;</code> or <code>POST /&lt;slug&gt;/v1/dev/reminders/&lt;id&gt;</code> (list reminders at <code>GET /v1/dev/reminders</code>).</td></tr><tr><td>A pending tool approval disappeared after restart</td><td>Parked approvals do not survive host restart. They resolve as interrupted. Run the turn again.</td></tr><tr><td>A reminder is disarmed after restart (<code>handler_lost_on_restart</code>)</td><td>Handler-form reminders live in memory. Re-arm them from the code that created them, or use prompt-form reminders.</td></tr></tbody></table><h2 id="how-do-i-read-a-session-trace" tabindex="-1">How do I read a session trace? <a class="header-anchor" href="#how-do-i-read-a-session-trace" aria-label="Permalink to &quot;How do I read a session trace?&quot;">​</a></h2><p>Look at <code>actions.requested</code> / <code>action.result</code> pairs for the tool trajectory. Count calls by tool name before blaming latency. Separate host-side work (channel <code>callTool</code>, preparation) from tools the model chose.</p><p><code>turn.failed</code> with <code>&quot;turn interrupted&quot;</code> means a follow-up or stop ended the turn on purpose.</p><p>If the model reads outside the session workspace, the prepared files don&#39;t match what the instructions expect. Fix the layout. See <a href="./hillclimbing.html">Hillclimbing</a>.</p><p><code>agent-sdk trajectory --events &lt;file&gt;</code> summarizes any saved NDJSON stream. The playground <strong>Open trace</strong> control does the same visually.</p><h2 id="what-s-next" tabindex="-1">What&#39;s next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to &quot;What&#39;s next&quot;">​</a></h2><ul><li><a href="./concepts.html">Concepts</a>: the model behind these symptoms</li><li><a href="./hillclimbing.html">Hillclimbing</a>: when the agent runs but underperforms</li><li><a href="./deployment.html">Deployment</a>: auth and state on shared hosts</li></ul>',26)])])}const m=t(r,[["render",s]]);export{p as __pageData,m as default};
@@ -1 +1 @@
1
- import{_ as t,c as o,o as a,ag as d}from"./chunks/framework.CAZyNGu9.js";const p=JSON.parse('{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail.","frontmatter":{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail."},"headers":[],"relativePath":"troubleshooting.md","filePath":"troubleshooting.md"}'),r={name:"troubleshooting.md"};function s(n,e,i,h,c,l){return a(),o("div",null,[...e[0]||(e[0]=[d("",26)])])}const m=t(r,[["render",s]]);export{p as __pageData,m as default};
1
+ import{_ as t,c as o,o as a,ag as d}from"./chunks/framework.CAZyNGu9.js";const p=JSON.parse('{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail.","frontmatter":{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail."},"headers":[],"relativePath":"troubleshooting.md","filePath":"troubleshooting.md"}'),r={name:"troubleshooting.md"};function s(n,e,i,c,h,l){return a(),o("div",null,[...e[0]||(e[0]=[d("",26)])])}const m=t(r,[["render",s]]);export{p as __pageData,m as default};