@cursor/july 0.1.35 → 0.1.36

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 (195) hide show
  1. package/AGENTS.md +5 -9
  2. package/README.md +5 -9
  3. package/dist/channels/github/github-channel.d.ts +1 -1
  4. package/dist/channels/github/github-channel.js +1 -1
  5. package/dist/channels/github/index.d.ts +1 -1
  6. package/dist/channels/github/index.js +1 -1
  7. package/dist/channels/slack/index.d.ts +1 -1
  8. package/dist/channels/slack/index.js +1 -1
  9. package/dist/channels/slack/init.d.ts.map +1 -1
  10. package/dist/channels/slack/init.js +2 -1
  11. package/dist/docs/404.html +2 -2
  12. package/dist/docs/ab.html +8 -17
  13. package/dist/docs/assets/{ab.md.DAQoJ-up.js → ab.md.6cLOW7--.js} +4 -13
  14. package/dist/docs/assets/{ab.md.DAQoJ-up.lean.js → ab.md.6cLOW7--.lean.js} +1 -1
  15. package/dist/docs/assets/{app.D5Mv1T0U.js → app.DEcxy4oz.js} +1 -1
  16. package/dist/docs/assets/{building-with-agents.md.CnHqvYDd.js → building-with-agents.md.txrcGU2B.js} +2 -2
  17. package/dist/docs/assets/chunks/@localSearchIndexroot.ByFYcFly.js +1 -0
  18. package/dist/docs/assets/chunks/{VPLocalSearchBox.CMq_BQce.js → VPLocalSearchBox.n1VOZcy3.js} +1 -1
  19. package/dist/docs/assets/chunks/{theme.C6D9UPLK.js → theme.BaF1MQ9c.js} +2 -2
  20. package/dist/docs/assets/{concepts.md.DFaQEFkA.js → concepts.md.CqOsxbMU.js} +1 -1
  21. package/dist/docs/assets/{deployment.md.9MYBuKM1.js → deployment.md.CuK5SNjN.js} +1 -1
  22. package/dist/docs/assets/{evals.md.BIUoVZ6X.js → evals.md.BQXI3rXy.js} +9 -15
  23. package/dist/docs/assets/{evals.md.BIUoVZ6X.lean.js → evals.md.BQXI3rXy.lean.js} +1 -1
  24. package/dist/docs/assets/{example-agents_approval-buddy.md.BhEfleVx.js → example-agents_approval-buddy.md.CIiZ9coo.js} +1 -1
  25. package/dist/docs/assets/{example-agents_benny.md.2Et1qa8f.js → example-agents_benny.md.l7JTmm8X.js} +1 -1
  26. package/dist/docs/assets/{example-agents_bugbot.md.ByUexi5i.js → example-agents_bugbot.md.Dp5JqHSQ.js} +2 -2
  27. package/dist/docs/assets/{example-agents_bugbot.md.ByUexi5i.lean.js → example-agents_bugbot.md.Dp5JqHSQ.lean.js} +1 -1
  28. package/dist/docs/assets/{example-agents_codebase-wiki.md.B4y-7ZVW.js → example-agents_codebase-wiki.md.D-lteFf0.js} +1 -1
  29. package/dist/docs/assets/{example-agents_codebase-wiki.md.B4y-7ZVW.lean.js → example-agents_codebase-wiki.md.D-lteFf0.lean.js} +1 -1
  30. package/dist/docs/assets/{example-agents_codeowners-review.md.D6ay4nvf.js → example-agents_codeowners-review.md.BU2ZXLf-.js} +1 -1
  31. package/dist/docs/assets/{example-agents_codeowners-review.md.D6ay4nvf.lean.js → example-agents_codeowners-review.md.BU2ZXLf-.lean.js} +1 -1
  32. package/dist/docs/assets/{example-agents_concierge.md.lL8rhYlj.js → example-agents_concierge.md.DA2al_NK.js} +2 -2
  33. package/dist/docs/assets/{example-agents_concierge.md.lL8rhYlj.lean.js → example-agents_concierge.md.DA2al_NK.lean.js} +1 -1
  34. package/dist/docs/assets/{example-agents_fsd.md.DfNKQTHz.js → example-agents_fsd.md.DPz9ezO4.js} +1 -1
  35. package/dist/docs/assets/{example-agents_knowledge-base.md.CzyZ2DCr.js → example-agents_knowledge-base.md.IneynQSR.js} +1 -1
  36. package/dist/docs/assets/{example-agents_oncall.md.wFFXXEyW.js → example-agents_oncall.md.ZE0n6ZFN.js} +1 -1
  37. package/dist/docs/assets/{example-agents_slack-agent.md.DvgvT4nn.js → example-agents_slack-agent.md.06jQXTAI.js} +1 -1
  38. package/dist/docs/assets/{example-agents_weather-agent.md.BADkPqxQ.js → example-agents_weather-agent.md.CrGZ0SqR.js} +3 -3
  39. package/dist/docs/assets/{example-agents_weather-agent.md.BADkPqxQ.lean.js → example-agents_weather-agent.md.CrGZ0SqR.lean.js} +1 -1
  40. package/dist/docs/assets/guides_cloud-runtime.md.V5igN4Sq.js +9 -0
  41. package/dist/docs/assets/guides_cloud-runtime.md.V5igN4Sq.lean.js +1 -0
  42. package/dist/docs/assets/{guides_webhooks.md.DiAwSR42.js → guides_webhooks.md.BERuBSJW.js} +1 -1
  43. package/dist/docs/assets/{hillclimbing.md.D9Y1_bYh.js → hillclimbing.md.yXqdlv2R.js} +1 -1
  44. package/dist/docs/assets/index.md.CmhptOmN.js +24 -0
  45. package/dist/docs/assets/{index.md.CZqbBJPB.lean.js → index.md.CmhptOmN.lean.js} +1 -1
  46. package/dist/docs/assets/{quickstart.md.TnEXYgYW.js → quickstart.md.C_b6ESpD.js} +7 -4
  47. package/dist/docs/assets/{quickstart.md.TnEXYgYW.lean.js → quickstart.md.C_b6ESpD.lean.js} +1 -1
  48. package/dist/docs/assets/{reference_agent-config.md.kuN6-OxK.js → reference_agent-config.md.CRmkoxd6.js} +6 -4
  49. package/dist/docs/assets/{reference_agent-config.md.kuN6-OxK.lean.js → reference_agent-config.md.CRmkoxd6.lean.js} +1 -1
  50. package/dist/docs/assets/reference_artifacts.md.BGG4bZo-.js +19 -0
  51. package/dist/docs/assets/reference_artifacts.md.BGG4bZo-.lean.js +1 -0
  52. package/dist/docs/assets/{reference_channels.md.CDhTRfUz.js → reference_channels.md.BIabFUAI.js} +2 -2
  53. package/dist/docs/assets/{reference_channels.md.CDhTRfUz.lean.js → reference_channels.md.BIabFUAI.lean.js} +1 -1
  54. package/dist/docs/assets/{reference_cli.md.sD-IUWjg.js → reference_cli.md.Byvrg8eu.js} +15 -9
  55. package/dist/docs/assets/{reference_cli.md.sD-IUWjg.lean.js → reference_cli.md.Byvrg8eu.lean.js} +1 -1
  56. package/dist/docs/assets/{reference_hooks.md.DyLVfE1O.js → reference_hooks.md.BGDw4VLm.js} +2 -2
  57. package/dist/docs/assets/{reference_hooks.md.DyLVfE1O.lean.js → reference_hooks.md.BGDw4VLm.lean.js} +1 -1
  58. package/dist/docs/assets/reference_http-api.md.DGrw_wOu.js +11 -0
  59. package/dist/docs/assets/reference_http-api.md.DGrw_wOu.lean.js +1 -0
  60. package/dist/docs/assets/{reference_project-layout.md.D8E6ZmHJ.js → reference_project-layout.md._XdeMahr.js} +2 -2
  61. package/dist/docs/assets/{reference_project-layout.md.D8E6ZmHJ.lean.js → reference_project-layout.md._XdeMahr.lean.js} +1 -1
  62. package/dist/docs/assets/{reference_sessions.md.C_ouF_uf.js → reference_sessions.md.DBVFi2Sx.js} +2 -2
  63. package/dist/docs/assets/{reference_subagents.md.zWAMNfi1.js → reference_subagents.md.DSrGLIuB.js} +2 -2
  64. package/dist/docs/assets/{reference_subagents.md.zWAMNfi1.lean.js → reference_subagents.md.DSrGLIuB.lean.js} +1 -1
  65. package/dist/docs/assets/{reference_tools.md.BswAQM41.js → reference_tools.md.lSrsTxYJ.js} +4 -4
  66. package/dist/docs/assets/{reference_tools.md.BswAQM41.lean.js → reference_tools.md.lSrsTxYJ.lean.js} +1 -1
  67. package/dist/docs/assets/scaffolding-agents.md.mkc3B_ZW.js +1 -0
  68. package/dist/docs/assets/{scaffolding-agents.md.Bsr9Pwzu.lean.js → scaffolding-agents.md.mkc3B_ZW.lean.js} +1 -1
  69. package/dist/docs/assets/{storage.md.xZoiGM58.js → storage.md.mQDtIULc.js} +3 -3
  70. package/dist/docs/assets/{storage.md.xZoiGM58.lean.js → storage.md.mQDtIULc.lean.js} +1 -1
  71. package/dist/docs/building-with-agents.html +6 -6
  72. package/dist/docs/concepts.html +5 -5
  73. package/dist/docs/deployment.html +6 -6
  74. package/dist/docs/evals.html +13 -19
  75. package/dist/docs/example-agents/approval-buddy.html +5 -5
  76. package/dist/docs/example-agents/benny.html +5 -5
  77. package/dist/docs/example-agents/bugbot.html +5 -5
  78. package/dist/docs/example-agents/codebase-wiki.html +5 -5
  79. package/dist/docs/example-agents/codeowners-review.html +5 -5
  80. package/dist/docs/example-agents/concierge.html +6 -6
  81. package/dist/docs/example-agents/fsd.html +5 -5
  82. package/dist/docs/example-agents/index.html +4 -4
  83. package/dist/docs/example-agents/knowledge-base.html +5 -5
  84. package/dist/docs/example-agents/oncall.html +5 -5
  85. package/dist/docs/example-agents/security-reviewer.html +4 -4
  86. package/dist/docs/example-agents/slack-agent.html +5 -5
  87. package/dist/docs/example-agents/weather-agent.html +6 -6
  88. package/dist/docs/guides/agent-to-agent.html +5 -5
  89. package/dist/docs/guides/cloud-runtime.html +6 -6
  90. package/dist/docs/guides/github.html +4 -4
  91. package/dist/docs/guides/human-in-the-loop.html +4 -4
  92. package/dist/docs/guides/mcp-oauth.html +5 -5
  93. package/dist/docs/guides/slack.html +4 -4
  94. package/dist/docs/guides/webhooks.html +6 -6
  95. package/dist/docs/hashmap.json +1 -1
  96. package/dist/docs/hillclimbing.html +6 -6
  97. package/dist/docs/index.html +11 -7
  98. package/dist/docs/quickstart.html +10 -7
  99. package/dist/docs/reference/agent-config.html +10 -8
  100. package/dist/docs/reference/artifacts.html +43 -0
  101. package/dist/docs/reference/channels.html +6 -6
  102. package/dist/docs/reference/cli.html +18 -12
  103. package/dist/docs/reference/connections.html +4 -4
  104. package/dist/docs/reference/hooks.html +6 -6
  105. package/dist/docs/reference/http-api.html +7 -7
  106. package/dist/docs/reference/instructions.html +4 -4
  107. package/dist/docs/reference/playground.html +4 -4
  108. package/dist/docs/reference/project-layout.html +6 -6
  109. package/dist/docs/reference/prompt.html +4 -4
  110. package/dist/docs/reference/schedules.html +4 -4
  111. package/dist/docs/reference/sessions.html +7 -7
  112. package/dist/docs/reference/skills.html +4 -4
  113. package/dist/docs/reference/subagents.html +6 -6
  114. package/dist/docs/reference/tools.html +7 -7
  115. package/dist/docs/scaffolding-agents.html +5 -5
  116. package/dist/docs/storage.html +6 -6
  117. package/dist/docs/troubleshooting.html +4 -4
  118. package/dist/files-backends/agent-store-presigned-url.d.ts.map +1 -1
  119. package/dist/files-backends/agent-store-presigned-url.js +15 -22
  120. package/dist/internal/cli-github.d.ts.map +1 -1
  121. package/dist/internal/cli-github.js +8 -7
  122. package/dist/internal/cli-slack.js +9 -9
  123. package/dist/internal/event-mapper.d.ts +3 -3
  124. package/dist/internal/event-mapper.d.ts.map +1 -1
  125. package/dist/internal/event-mapper.js +7 -4
  126. package/dist/internal/session-engine.js +3 -3
  127. package/dist/internal/workspace.d.ts +8 -6
  128. package/dist/internal/workspace.d.ts.map +1 -1
  129. package/dist/internal/workspace.js +15 -11
  130. package/dist/playground/assets/{index-D7OV8B_H.js → index-DOnKC85G.js} +18 -18
  131. package/dist/playground/assets/{index-DOb96C0M.css → index-DoQjqj5w.css} +1 -1
  132. package/dist/playground/index.html +2 -2
  133. package/docs/README.md +32 -13
  134. package/docs/ab.md +23 -36
  135. package/docs/building-with-agents.md +2 -2
  136. package/docs/concepts.md +3 -2
  137. package/docs/deployment.md +1 -1
  138. package/docs/evals.md +102 -33
  139. package/docs/example-agents/approval-buddy.md +2 -1
  140. package/docs/example-agents/benny.md +2 -0
  141. package/docs/example-agents/bugbot.md +3 -0
  142. package/docs/example-agents/codebase-wiki.md +2 -0
  143. package/docs/example-agents/codeowners-review.md +2 -0
  144. package/docs/example-agents/concierge.md +1 -0
  145. package/docs/example-agents/fsd.md +1 -0
  146. package/docs/example-agents/knowledge-base.md +2 -0
  147. package/docs/example-agents/oncall.md +2 -0
  148. package/docs/example-agents/slack-agent.md +1 -0
  149. package/docs/example-agents/weather-agent.md +9 -4
  150. package/docs/guides/cloud-runtime.md +11 -4
  151. package/docs/guides/webhooks.md +1 -1
  152. package/docs/hillclimbing.md +1 -1
  153. package/docs/quickstart.md +39 -7
  154. package/docs/reference/agent-config.md +74 -14
  155. package/docs/reference/artifacts.md +117 -0
  156. package/docs/reference/channels.md +45 -15
  157. package/docs/reference/cli.md +141 -20
  158. package/docs/reference/hooks.md +11 -4
  159. package/docs/reference/http-api.md +50 -4
  160. package/docs/reference/project-layout.md +6 -0
  161. package/docs/reference/sessions.md +5 -4
  162. package/docs/reference/subagents.md +5 -3
  163. package/docs/reference/tools.md +23 -7
  164. package/docs/scaffolding-agents.md +11 -2
  165. package/docs/storage.md +27 -2
  166. package/package.json +1 -1
  167. package/src/channels/github/github-channel.ts +1 -1
  168. package/src/channels/github/index.ts +1 -1
  169. package/src/channels/slack/index.ts +1 -1
  170. package/src/channels/slack/init.ts +2 -1
  171. package/src/files-backends/agent-store-presigned-url.ts +2 -1
  172. package/src/internal/cli-github.ts +8 -7
  173. package/src/internal/cli-slack.ts +9 -9
  174. package/src/internal/event-mapper.ts +9 -4
  175. package/src/internal/session-engine.ts +3 -3
  176. package/src/internal/workspace.ts +15 -11
  177. package/dist/docs/assets/chunks/@localSearchIndexroot.Cu7b6o1D.js +0 -1
  178. package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.js +0 -9
  179. package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.lean.js +0 -1
  180. package/dist/docs/assets/index.md.CZqbBJPB.js +0 -20
  181. package/dist/docs/assets/reference_http-api.md.CfVM_ICa.js +0 -11
  182. package/dist/docs/assets/reference_http-api.md.CfVM_ICa.lean.js +0 -1
  183. package/dist/docs/assets/scaffolding-agents.md.Bsr9Pwzu.js +0 -1
  184. /package/dist/docs/assets/{building-with-agents.md.CnHqvYDd.lean.js → building-with-agents.md.txrcGU2B.lean.js} +0 -0
  185. /package/dist/docs/assets/{concepts.md.DFaQEFkA.lean.js → concepts.md.CqOsxbMU.lean.js} +0 -0
  186. /package/dist/docs/assets/{deployment.md.9MYBuKM1.lean.js → deployment.md.CuK5SNjN.lean.js} +0 -0
  187. /package/dist/docs/assets/{example-agents_approval-buddy.md.BhEfleVx.lean.js → example-agents_approval-buddy.md.CIiZ9coo.lean.js} +0 -0
  188. /package/dist/docs/assets/{example-agents_benny.md.2Et1qa8f.lean.js → example-agents_benny.md.l7JTmm8X.lean.js} +0 -0
  189. /package/dist/docs/assets/{example-agents_fsd.md.DfNKQTHz.lean.js → example-agents_fsd.md.DPz9ezO4.lean.js} +0 -0
  190. /package/dist/docs/assets/{example-agents_knowledge-base.md.CzyZ2DCr.lean.js → example-agents_knowledge-base.md.IneynQSR.lean.js} +0 -0
  191. /package/dist/docs/assets/{example-agents_oncall.md.wFFXXEyW.lean.js → example-agents_oncall.md.ZE0n6ZFN.lean.js} +0 -0
  192. /package/dist/docs/assets/{example-agents_slack-agent.md.DvgvT4nn.lean.js → example-agents_slack-agent.md.06jQXTAI.lean.js} +0 -0
  193. /package/dist/docs/assets/{guides_webhooks.md.DiAwSR42.lean.js → guides_webhooks.md.BERuBSJW.lean.js} +0 -0
  194. /package/dist/docs/assets/{hillclimbing.md.D9Y1_bYh.lean.js → hillclimbing.md.yXqdlv2R.lean.js} +0 -0
  195. /package/dist/docs/assets/{reference_sessions.md.C_ouF_uf.lean.js → reference_sessions.md.DBVFi2Sx.lean.js} +0 -0
package/AGENTS.md CHANGED
@@ -80,12 +80,12 @@ my-agent/
80
80
  skills/*.md
81
81
  channels/
82
82
  ab.ts # optional live A/B metrics (defineAB)
83
- ab.config.ts # optional: maxPlaygroundSessions (default 200) / persist*
83
+ ab.config.ts # optional: maxPlaygroundSessions (default 200)
84
84
  ...
85
85
  evals/
86
86
  smoke.eval.ts # single datapoint → id: smoke
87
87
  weather.eval.ts # cases → weather/nyc, weather/paris, …
88
- evals.config.ts # required: maxConcurrency; optional maxPlaygroundRuns (default 20) / persistRuns
88
+ evals.config.ts # required: maxConcurrency; optional maxPlaygroundRuns (default 20)
89
89
  ```
90
90
 
91
91
  ## Authoring evals
@@ -116,18 +116,14 @@ Select with the CLI: one datapoint (`weather/nyc`), a whole file
116
116
 
117
117
  `evals/evals.config.ts` must set `maxConcurrency` (hard-capped at 200 due to
118
118
  model provider request limits; examples use `20`). Playground batches default
119
- to in-memory only (`maxPlaygroundRuns`, default 20); set `persistRuns` to survive
120
- serve restart:
119
+ to in-memory only (`maxPlaygroundRuns`, default 20); declare an `evals` table
120
+ in `agent/storage.ts` (`defineStorage`) to survive serve restart:
121
121
 
122
122
  ```ts
123
- import {
124
- defineEvalConfig,
125
- persistEvalRunsToDir,
126
- } from "@cursor/july/evals";
123
+ import { defineEvalConfig } from "@cursor/july/evals";
127
124
 
128
125
  export default defineEvalConfig({
129
126
  maxConcurrency: 20,
130
- // persistRuns: persistEvalRunsToDir(".agent-serve/eval-runs"),
131
127
  });
132
128
  ```
133
129
  ## CLI notes for agents
package/README.md CHANGED
@@ -308,22 +308,18 @@ Case id is the path under `evals/` for a single-`test` file, or
308
308
 
309
309
  Every project with evals needs `evals/evals.config.ts` with a required
310
310
  `maxConcurrency` (hard-capped at 200 due to model provider request limits).
311
- Playground batches are in-memory by default; set optional `persistRuns` to
312
- keep them across serve restarts. Optional `maxPlaygroundRuns` caps how many
313
- batches the playground / `/v1/dev/evals*` history keeps (default 20):
311
+ Playground batches are in-memory by default; declare an `evals` table in
312
+ `agent/storage.ts` (`defineStorage`) to keep them across serve restarts.
313
+ Optional `maxPlaygroundRuns` caps how many batches the playground /
314
+ `/v1/dev/evals*` history keeps (default 20):
314
315
 
315
316
  ```ts
316
- import {
317
- defineEvalConfig,
318
- persistEvalRunsToDir,
319
- } from "@cursor/july/evals";
317
+ import { defineEvalConfig } from "@cursor/july/evals";
320
318
 
321
319
  export default defineEvalConfig({
322
320
  maxConcurrency: 20,
323
321
  // Optional — playground /v1/dev/evals history window (default 20):
324
322
  // maxPlaygroundRuns: 50,
325
- // Optional — survive serve restarts (omit to keep runs in memory only):
326
- persistRuns: persistEvalRunsToDir(".agent-serve/eval-runs"),
327
323
  });
328
324
  ```
329
325
 
@@ -63,7 +63,7 @@ export declare function verifyGitHubWebhookSignature(args: {
63
63
  * hooks:
64
64
  *
65
65
  * ```ts
66
- * import { defaultGitHubAuth, githubChannel } from "@anysphere/agent-serve/channels/github";
66
+ * import { defaultGitHubAuth, githubChannel } from "@cursor/july/channels/github";
67
67
  *
68
68
  * export default githubChannel({
69
69
  * botName: "my-agent",
@@ -250,7 +250,7 @@ function verifyWebhookSha256Signature(args) {
250
250
  * hooks:
251
251
  *
252
252
  * ```ts
253
- * import { defaultGitHubAuth, githubChannel } from "@anysphere/agent-serve/channels/github";
253
+ * import { defaultGitHubAuth, githubChannel } from "@cursor/july/channels/github";
254
254
  *
255
255
  * export default githubChannel({
256
256
  * botName: "my-agent",
@@ -2,7 +2,7 @@
2
2
  * GitHub webhook channel pack for agent-serve (Eve-compatible dispatch).
3
3
  *
4
4
  * ```ts
5
- * import { defaultGitHubAuth, githubChannel } from "@anysphere/agent-serve/channels/github";
5
+ * import { defaultGitHubAuth, githubChannel } from "@cursor/july/channels/github";
6
6
  *
7
7
  * export default githubChannel({
8
8
  * botName: "my-agent",
@@ -2,7 +2,7 @@
2
2
  * GitHub webhook channel pack for agent-serve (Eve-compatible dispatch).
3
3
  *
4
4
  * ```ts
5
- * import { defaultGitHubAuth, githubChannel } from "@anysphere/agent-serve/channels/github";
5
+ * import { defaultGitHubAuth, githubChannel } from "@cursor/july/channels/github";
6
6
  *
7
7
  * export default githubChannel({
8
8
  * botName: "my-agent",
@@ -2,7 +2,7 @@
2
2
  * Slack platform channel pack for agent-serve.
3
3
  *
4
4
  * ```ts
5
- * import { slackChannel } from "@anysphere/agent-serve/channels/slack";
5
+ * import { slackChannel } from "@cursor/july/channels/slack";
6
6
  *
7
7
  * // Single agent: SLACK_BOT_TOKEN + SLACK_APP_TOKEN
8
8
  * export default slackChannel();
@@ -2,7 +2,7 @@
2
2
  * Slack platform channel pack for agent-serve.
3
3
  *
4
4
  * ```ts
5
- * import { slackChannel } from "@anysphere/agent-serve/channels/slack";
5
+ * import { slackChannel } from "@cursor/july/channels/slack";
6
6
  *
7
7
  * // Single agent: SLACK_BOT_TOKEN + SLACK_APP_TOKEN
8
8
  * export default slackChannel();
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAkG1B"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAkG1B"}
@@ -12,6 +12,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
12
12
  };
13
13
  import { mkdir, writeFile } from "node:fs/promises";
14
14
  import { basename, join, resolve } from "node:path";
15
+ import { PACKAGE_NAME } from "../../internal/distribution.js";
15
16
  import { envPrefixFromName, slackEnvKeys } from "./credentials.js";
16
17
  import { buildSlackManifestPair } from "./manifest.js";
17
18
  export function initSlackChannel(options) {
@@ -33,7 +34,7 @@ export function initSlackChannel(options) {
33
34
  const envPrefixLine = envPrefix === undefined
34
35
  ? ""
35
36
  : ` envPrefix: ${JSON.stringify(envPrefix)},\n`;
36
- yield write("agent/channels/slack.ts", `import { slackChannel } from "@anysphere/agent-serve/channels/slack";
37
+ yield write("agent/channels/slack.ts", `import { slackChannel } from "${PACKAGE_NAME}/channels/slack";
37
38
 
38
39
  /**
39
40
  * Slack channel (Socket Mode).
@@ -9,14 +9,14 @@
9
9
  <link rel="preload stylesheet" href="/docs/assets/style.Bj-IXa5W.css" as="style">
10
10
  <link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
11
11
 
12
- <script type="module" src="/docs/assets/app.D5Mv1T0U.js"></script>
12
+ <script type="module" src="/docs/assets/app.DEcxy4oz.js"></script>
13
13
  <link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
14
14
  <script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
15
15
  <script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
16
16
  </head>
17
17
  <body>
18
18
  <div id="app"></div>
19
- <script>window.__VP_HASH_MAP__=JSON.parse("{\"ab.md\":\"DAQoJ-up\",\"building-with-agents.md\":\"CnHqvYDd\",\"concepts.md\":\"DFaQEFkA\",\"deployment.md\":\"9MYBuKM1\",\"evals.md\":\"BIUoVZ6X\",\"example-agents_approval-buddy.md\":\"BhEfleVx\",\"example-agents_benny.md\":\"2Et1qa8f\",\"example-agents_bugbot.md\":\"ByUexi5i\",\"example-agents_codebase-wiki.md\":\"B4y-7ZVW\",\"example-agents_codeowners-review.md\":\"D6ay4nvf\",\"example-agents_concierge.md\":\"lL8rhYlj\",\"example-agents_fsd.md\":\"DfNKQTHz\",\"example-agents_index.md\":\"DgGBwckv\",\"example-agents_knowledge-base.md\":\"CzyZ2DCr\",\"example-agents_oncall.md\":\"wFFXXEyW\",\"example-agents_security-reviewer.md\":\"Dkf1gyo6\",\"example-agents_slack-agent.md\":\"DvgvT4nn\",\"example-agents_weather-agent.md\":\"BADkPqxQ\",\"guides_agent-to-agent.md\":\"Bmbxy-FA\",\"guides_cloud-runtime.md\":\"CDJGvVC4\",\"guides_github.md\":\"R2QlpR75\",\"guides_human-in-the-loop.md\":\"BWvT7UqY\",\"guides_mcp-oauth.md\":\"C7G7IykG\",\"guides_slack.md\":\"zriQpU_9\",\"guides_webhooks.md\":\"DiAwSR42\",\"hillclimbing.md\":\"D9Y1_bYh\",\"index.md\":\"CZqbBJPB\",\"quickstart.md\":\"TnEXYgYW\",\"reference_agent-config.md\":\"kuN6-OxK\",\"reference_channels.md\":\"CDhTRfUz\",\"reference_cli.md\":\"sD-IUWjg\",\"reference_connections.md\":\"DGqAsFXb\",\"reference_hooks.md\":\"DyLVfE1O\",\"reference_http-api.md\":\"CfVM_ICa\",\"reference_instructions.md\":\"CgoV-YEb\",\"reference_playground.md\":\"CPZhfYaO\",\"reference_project-layout.md\":\"D8E6ZmHJ\",\"reference_prompt.md\":\"BaiweQxE\",\"reference_schedules.md\":\"gmfYzf_I\",\"reference_sessions.md\":\"C_ouF_uf\",\"reference_skills.md\":\"B_jHN7JL\",\"reference_subagents.md\":\"zWAMNfi1\",\"reference_tools.md\":\"BswAQM41\",\"scaffolding-agents.md\":\"Bsr9Pwzu\",\"storage.md\":\"xZoiGM58\",\"troubleshooting.md\":\"B5RVX_tL\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Agent SDK\",\"description\":\"Filesystem-first framework for building and serving Cursor agents.\",\"base\":\"/docs/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Guides\",\"link\":\"/guides/webhooks\"},{\"text\":\"Examples\",\"link\":\"/example-agents/\"},{\"text\":\"Reference\",\"link\":\"/reference/project-layout\"}],\"search\":{\"provider\":\"local\"},\"outline\":{\"level\":[2,3]},\"sidebar\":[{\"text\":\"Getting started\",\"items\":[{\"text\":\"Overview\",\"link\":\"/\"},{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Scaffold an agent with Cursor\",\"link\":\"/scaffolding-agents\"},{\"text\":\"Concepts\",\"link\":\"/concepts\"}]},{\"text\":\"Improving agents\",\"items\":[{\"text\":\"Building agents with agents\",\"link\":\"/building-with-agents\"},{\"text\":\"Evals\",\"link\":\"/evals\"},{\"text\":\"Live A/B metrics\",\"link\":\"/ab\"},{\"text\":\"Storage\",\"link\":\"/storage\"},{\"text\":\"Hillclimbing\",\"link\":\"/hillclimbing\"}]},{\"text\":\"Guides\",\"items\":[{\"text\":\"Webhooks & custom channels\",\"link\":\"/guides/webhooks\"},{\"text\":\"GitHub\",\"link\":\"/guides/github\"},{\"text\":\"Slack\",\"link\":\"/guides/slack\"},{\"text\":\"Human-in-the-loop approvals\",\"link\":\"/guides/human-in-the-loop\"},{\"text\":\"Agent-to-agent\",\"link\":\"/guides/agent-to-agent\"},{\"text\":\"Cloud runtime\",\"link\":\"/guides/cloud-runtime\"}]},{\"text\":\"Example agents\",\"items\":[{\"text\":\"Choose an example\",\"link\":\"/example-agents/\"},{\"text\":\"Weather agent\",\"link\":\"/example-agents/weather-agent\"},{\"text\":\"Slack agent\",\"link\":\"/example-agents/slack-agent\"},{\"text\":\"Concierge\",\"link\":\"/example-agents/concierge\"},{\"text\":\"Playbook router\",\"link\":\"/example-agents/benny\"},{\"text\":\"Alert investigator\",\"link\":\"/example-agents/oncall\"},{\"text\":\"PR evidence reviewer\",\"link\":\"/example-agents/bugbot\"},{\"text\":\"Approval Buddy\",\"link\":\"/example-agents/approval-buddy\"},{\"text\":\"Security Reviewer\",\"link\":\"/example-agents/security-reviewer\"},{\"text\":\"Remote PR coordinator\",\"link\":\"/example-agents/fsd\"},{\"text\":\"Knowledge base\",\"link\":\"/example-agents/knowledge-base\"},{\"text\":\"Codebase wiki\",\"link\":\"/example-agents/codebase-wiki\"},{\"text\":\"Codeowners review\",\"link\":\"/example-agents/codeowners-review\"}]},{\"text\":\"Operating\",\"items\":[{\"text\":\"Deployment\",\"link\":\"/deployment\"},{\"text\":\"Fix common problems\",\"link\":\"/troubleshooting\"}]},{\"text\":\"Reference\",\"collapsed\":false,\"items\":[{\"text\":\"Project layout\",\"link\":\"/reference/project-layout\"},{\"text\":\"Agent config\",\"link\":\"/reference/agent-config\"},{\"text\":\"Instructions\",\"link\":\"/reference/instructions\"},{\"text\":\"Tools\",\"link\":\"/reference/tools\"},{\"text\":\"prompt\",\"link\":\"/reference/prompt\"},{\"text\":\"Skills\",\"link\":\"/reference/skills\"},{\"text\":\"MCP Connections\",\"link\":\"/reference/connections\"},{\"text\":\"Subagents\",\"link\":\"/reference/subagents\"},{\"text\":\"Channels\",\"link\":\"/reference/channels\"},{\"text\":\"Schedules & reminders\",\"link\":\"/reference/schedules\"},{\"text\":\"Hooks\",\"link\":\"/reference/hooks\"},{\"text\":\"Sessions & streaming\",\"link\":\"/reference/sessions\"},{\"text\":\"Playground\",\"link\":\"/reference/playground\"},{\"text\":\"CLI\",\"link\":\"/reference/cli\"},{\"text\":\"HTTP API\",\"link\":\"/reference/http-api\"}]}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
19
+ <script>window.__VP_HASH_MAP__=JSON.parse("{\"ab.md\":\"6cLOW7--\",\"building-with-agents.md\":\"txrcGU2B\",\"concepts.md\":\"CqOsxbMU\",\"deployment.md\":\"CuK5SNjN\",\"evals.md\":\"BQXI3rXy\",\"example-agents_approval-buddy.md\":\"CIiZ9coo\",\"example-agents_benny.md\":\"l7JTmm8X\",\"example-agents_bugbot.md\":\"Dp5JqHSQ\",\"example-agents_codebase-wiki.md\":\"D-lteFf0\",\"example-agents_codeowners-review.md\":\"BU2ZXLf-\",\"example-agents_concierge.md\":\"DA2al_NK\",\"example-agents_fsd.md\":\"DPz9ezO4\",\"example-agents_index.md\":\"DgGBwckv\",\"example-agents_knowledge-base.md\":\"IneynQSR\",\"example-agents_oncall.md\":\"ZE0n6ZFN\",\"example-agents_security-reviewer.md\":\"Dkf1gyo6\",\"example-agents_slack-agent.md\":\"06jQXTAI\",\"example-agents_weather-agent.md\":\"CrGZ0SqR\",\"guides_agent-to-agent.md\":\"Bmbxy-FA\",\"guides_cloud-runtime.md\":\"V5igN4Sq\",\"guides_github.md\":\"R2QlpR75\",\"guides_human-in-the-loop.md\":\"BWvT7UqY\",\"guides_mcp-oauth.md\":\"C7G7IykG\",\"guides_slack.md\":\"zriQpU_9\",\"guides_webhooks.md\":\"BERuBSJW\",\"hillclimbing.md\":\"yXqdlv2R\",\"index.md\":\"CmhptOmN\",\"quickstart.md\":\"C_b6ESpD\",\"reference_agent-config.md\":\"CRmkoxd6\",\"reference_artifacts.md\":\"BGG4bZo-\",\"reference_channels.md\":\"BIabFUAI\",\"reference_cli.md\":\"Byvrg8eu\",\"reference_connections.md\":\"DGqAsFXb\",\"reference_hooks.md\":\"BGDw4VLm\",\"reference_http-api.md\":\"DGrw_wOu\",\"reference_instructions.md\":\"CgoV-YEb\",\"reference_playground.md\":\"CPZhfYaO\",\"reference_project-layout.md\":\"_XdeMahr\",\"reference_prompt.md\":\"BaiweQxE\",\"reference_schedules.md\":\"gmfYzf_I\",\"reference_sessions.md\":\"DBVFi2Sx\",\"reference_skills.md\":\"B_jHN7JL\",\"reference_subagents.md\":\"DSrGLIuB\",\"reference_tools.md\":\"lSrsTxYJ\",\"scaffolding-agents.md\":\"mkc3B_ZW\",\"storage.md\":\"mQDtIULc\",\"troubleshooting.md\":\"B5RVX_tL\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Agent SDK\",\"description\":\"Filesystem-first framework for building and serving Cursor agents.\",\"base\":\"/docs/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Guides\",\"link\":\"/guides/webhooks\"},{\"text\":\"Examples\",\"link\":\"/example-agents/\"},{\"text\":\"Reference\",\"link\":\"/reference/project-layout\"}],\"search\":{\"provider\":\"local\"},\"outline\":{\"level\":[2,3]},\"sidebar\":[{\"text\":\"Getting started\",\"items\":[{\"text\":\"Overview\",\"link\":\"/\"},{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Scaffold an agent with Cursor\",\"link\":\"/scaffolding-agents\"},{\"text\":\"Concepts\",\"link\":\"/concepts\"}]},{\"text\":\"Improving agents\",\"items\":[{\"text\":\"Building agents with agents\",\"link\":\"/building-with-agents\"},{\"text\":\"Evals\",\"link\":\"/evals\"},{\"text\":\"Live A/B metrics\",\"link\":\"/ab\"},{\"text\":\"Storage\",\"link\":\"/storage\"},{\"text\":\"Hillclimbing\",\"link\":\"/hillclimbing\"}]},{\"text\":\"Guides\",\"items\":[{\"text\":\"Webhooks & custom channels\",\"link\":\"/guides/webhooks\"},{\"text\":\"GitHub\",\"link\":\"/guides/github\"},{\"text\":\"Slack\",\"link\":\"/guides/slack\"},{\"text\":\"Human-in-the-loop approvals\",\"link\":\"/guides/human-in-the-loop\"},{\"text\":\"Agent-to-agent\",\"link\":\"/guides/agent-to-agent\"},{\"text\":\"Host MCP OAuth\",\"link\":\"/guides/mcp-oauth\"},{\"text\":\"Cloud runtime\",\"link\":\"/guides/cloud-runtime\"}]},{\"text\":\"Example agents\",\"items\":[{\"text\":\"Choose an example\",\"link\":\"/example-agents/\"},{\"text\":\"Weather agent\",\"link\":\"/example-agents/weather-agent\"},{\"text\":\"Slack agent\",\"link\":\"/example-agents/slack-agent\"},{\"text\":\"Concierge\",\"link\":\"/example-agents/concierge\"},{\"text\":\"Playbook router\",\"link\":\"/example-agents/benny\"},{\"text\":\"Alert investigator\",\"link\":\"/example-agents/oncall\"},{\"text\":\"PR evidence reviewer\",\"link\":\"/example-agents/bugbot\"},{\"text\":\"Approval Buddy\",\"link\":\"/example-agents/approval-buddy\"},{\"text\":\"Security Reviewer\",\"link\":\"/example-agents/security-reviewer\"},{\"text\":\"Remote PR coordinator\",\"link\":\"/example-agents/fsd\"},{\"text\":\"Knowledge base\",\"link\":\"/example-agents/knowledge-base\"},{\"text\":\"Codebase wiki\",\"link\":\"/example-agents/codebase-wiki\"},{\"text\":\"Codeowners review\",\"link\":\"/example-agents/codeowners-review\"}]},{\"text\":\"Operating\",\"items\":[{\"text\":\"Deployment\",\"link\":\"/deployment\"},{\"text\":\"Fix common problems\",\"link\":\"/troubleshooting\"}]},{\"text\":\"Reference\",\"collapsed\":false,\"items\":[{\"text\":\"Project layout\",\"link\":\"/reference/project-layout\"},{\"text\":\"Agent config\",\"link\":\"/reference/agent-config\"},{\"text\":\"Instructions\",\"link\":\"/reference/instructions\"},{\"text\":\"Tools\",\"link\":\"/reference/tools\"},{\"text\":\"prompt\",\"link\":\"/reference/prompt\"},{\"text\":\"Skills\",\"link\":\"/reference/skills\"},{\"text\":\"MCP Connections\",\"link\":\"/reference/connections\"},{\"text\":\"Subagents\",\"link\":\"/reference/subagents\"},{\"text\":\"Channels\",\"link\":\"/reference/channels\"},{\"text\":\"Schedules & reminders\",\"link\":\"/reference/schedules\"},{\"text\":\"Hooks\",\"link\":\"/reference/hooks\"},{\"text\":\"Artifacts\",\"link\":\"/reference/artifacts\"},{\"text\":\"Sessions & streaming\",\"link\":\"/reference/sessions\"},{\"text\":\"Playground\",\"link\":\"/reference/playground\"},{\"text\":\"CLI\",\"link\":\"/reference/cli\"},{\"text\":\"HTTP API\",\"link\":\"/reference/http-api\"}]}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
20
20
 
21
21
  </body>
22
22
  </html>
package/dist/docs/ab.html CHANGED
@@ -9,16 +9,16 @@
9
9
  <link rel="preload stylesheet" href="/docs/assets/style.Bj-IXa5W.css" as="style">
10
10
  <link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
11
11
 
12
- <script type="module" src="/docs/assets/app.D5Mv1T0U.js"></script>
12
+ <script type="module" src="/docs/assets/app.DEcxy4oz.js"></script>
13
13
  <link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
14
- <link rel="modulepreload" href="/docs/assets/chunks/theme.C6D9UPLK.js">
14
+ <link rel="modulepreload" href="/docs/assets/chunks/theme.BaF1MQ9c.js">
15
15
  <link rel="modulepreload" href="/docs/assets/chunks/framework.CAZyNGu9.js">
16
- <link rel="modulepreload" href="/docs/assets/ab.md.DAQoJ-up.lean.js">
16
+ <link rel="modulepreload" href="/docs/assets/ab.md.6cLOW7--.lean.js">
17
17
  <script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
18
18
  <script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
19
19
  </head>
20
20
  <body>
21
- <div id="app"><div class="Layout" data-v-05085060><!--[--><!--]--><!--[--><span tabindex="-1" data-v-30dc752a></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-30dc752a>Skip to content</a><!--]--><!----><header class="VPNav" data-v-05085060 data-v-cbe59881><div class="VPNavBar" data-v-cbe59881 data-v-dd8a1864><div class="wrapper" data-v-dd8a1864><div class="container" data-v-dd8a1864><div class="title" data-v-dd8a1864><div class="VPNavBarTitle has-sidebar" data-v-dd8a1864 data-v-f9346b2b><a class="title" href="/docs/" data-v-f9346b2b><!--[--><!--]--><!----><span data-v-f9346b2b>Agent SDK</span><!--[--><!--]--></a></div></div><div class="content" data-v-dd8a1864><div class="content-body" data-v-dd8a1864><!--[--><!--]--><div class="VPNavBarSearch search" data-v-dd8a1864><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-dd8a1864 data-v-7ed6e5ac><span id="main-nav-aria-label" class="visually-hidden" data-v-7ed6e5ac> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/quickstart.html" tabindex="0" data-v-7ed6e5ac data-v-65720067><!--[--><span data-v-65720067>Quickstart</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/guides/webhooks.html" tabindex="0" data-v-7ed6e5ac data-v-65720067><!--[--><span data-v-65720067>Guides</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/example-agents/" tabindex="0" data-v-7ed6e5ac data-v-65720067><!--[--><span data-v-65720067>Examples</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/reference/project-layout.html" tabindex="0" data-v-7ed6e5ac data-v-65720067><!--[--><span data-v-65720067>Reference</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-dd8a1864 data-v-2b2b395e><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-2b2b395e data-v-182deabf data-v-2562b538><span class="check" data-v-2562b538><span class="icon" data-v-2562b538><!--[--><span class="vpi-sun sun" data-v-182deabf></span><span class="vpi-moon moon" data-v-182deabf></span><!--]--></span></span></button></div><!----><div class="VPFlyout VPNavBarExtra extra" data-v-dd8a1864 data-v-f3b584b7 data-v-82133de6><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-82133de6><span class="vpi-more-horizontal icon" data-v-82133de6></span></button><div class="menu" data-v-82133de6><div class="VPMenu" data-v-82133de6 data-v-759c9e19><!----><!--[--><!--[--><!----><div class="group" data-v-f3b584b7><div class="item appearance" data-v-f3b584b7><p class="label" data-v-f3b584b7>Appearance</p><div class="appearance-action" data-v-f3b584b7><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-f3b584b7 data-v-182deabf data-v-2562b538><span class="check" data-v-2562b538><span class="icon" data-v-2562b538><!--[--><span class="vpi-sun sun" data-v-182deabf></span><span class="vpi-moon moon" data-v-182deabf></span><!--]--></span></span></button></div></div></div><!----><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-dd8a1864 data-v-ab07e844><span class="container" data-v-ab07e844><span class="top" data-v-ab07e844></span><span class="middle" data-v-ab07e844></span><span class="bottom" data-v-ab07e844></span></span></button></div></div></div></div><div class="divider" data-v-dd8a1864><div class="divider-line" data-v-dd8a1864></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-05085060 data-v-826b8761><div class="container" data-v-826b8761><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-826b8761><span class="vpi-align-left menu-icon" data-v-826b8761></span><span class="menu-text" data-v-826b8761>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-826b8761 data-v-01af9e73><button data-v-01af9e73>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-05085060 data-v-5cd5b4d8><div class="curtain" data-v-5cd5b4d8></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-5cd5b4d8><span class="visually-hidden" id="sidebar-aria-label" data-v-5cd5b4d8> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Getting started</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Overview</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/quickstart.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Quickstart</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/scaffolding-agents.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Scaffold an agent with Cursor</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/concepts.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Concepts</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0 has-active" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Improving agents</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/building-with-agents.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Building agents with agents</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/evals.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Evals</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/ab.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Live A/B metrics</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/storage.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Storage</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/hillclimbing.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Hillclimbing</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Guides</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/webhooks.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Webhooks & custom channels</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/github.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>GitHub</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/slack.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Slack</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/human-in-the-loop.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Human-in-the-loop approvals</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/agent-to-agent.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Agent-to-agent</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/cloud-runtime.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Cloud runtime</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Example agents</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Choose an example</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/weather-agent.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Weather agent</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/slack-agent.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Slack agent</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/concierge.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Concierge</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/benny.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Playbook router</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/oncall.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Alert investigator</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/bugbot.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>PR evidence reviewer</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/approval-buddy.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Approval Buddy</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/security-reviewer.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Security Reviewer</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/fsd.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Remote PR coordinator</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/knowledge-base.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Knowledge base</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/codebase-wiki.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Codebase wiki</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/codeowners-review.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Codeowners review</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Operating</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/deployment.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Deployment</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/troubleshooting.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Fix common problems</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0 collapsible" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Reference</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-b6893b1b><span class="vpi-chevron-right caret-icon" data-v-b6893b1b></span></div></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/project-layout.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Project layout</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/agent-config.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Agent config</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/instructions.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Instructions</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/tools.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Tools</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/prompt.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>prompt</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/skills.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Skills</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/connections.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>MCP Connections</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/subagents.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Subagents</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/channels.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Channels</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/schedules.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Schedules & reminders</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/hooks.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Hooks</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/sessions.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Sessions & streaming</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/playground.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Playground</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/cli.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>CLI</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/http-api.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>HTTP API</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-05085060 data-v-8eedf2ac><div class="VPDoc has-sidebar has-aside" data-v-8eedf2ac data-v-53b9fda6><!--[--><!--]--><div class="container" data-v-53b9fda6><div class="aside" data-v-53b9fda6><div class="aside-curtain" data-v-53b9fda6></div><div class="aside-container" data-v-53b9fda6><div class="aside-content" data-v-53b9fda6><div class="VPDocAside" data-v-53b9fda6 data-v-e448ecab><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-e448ecab data-v-b0b42374><div class="content" data-v-b0b42374><div class="outline-marker" data-v-b0b42374></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-b0b42374>On this page</div><ul class="VPDocOutlineItem root" data-v-b0b42374 data-v-ae03bd52><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-e448ecab></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-53b9fda6><div class="content-container" data-v-53b9fda6><!--[--><!--]--><main class="main" data-v-53b9fda6><div style="position:relative;" class="vp-doc _docs_ab" data-v-53b9fda6><div><h1 id="live-a-b-metrics" tabindex="-1">Live A/B metrics <a class="header-anchor" href="#live-a-b-metrics" aria-label="Permalink to &quot;Live A/B metrics&quot;">​</a></h1><p>Use <code>defineAB</code> to compare variants on live agent sessions. New sessions receive a sticky assignment in each enrolled experiment. The Agent SDK folds their durable event streams into tool, token, failure, and wall-time metrics. You can send cumulative samples to your metrics backend and inspect aggregates in the playground.</p><p><code>defineAB</code> compares live variants through sticky assignment, instruction overlays, optional tool branches, and cumulative metrics. Metric callbacks observe the result without approving, rejecting, or failing a turn. Use <a href="./evals.html">evals</a> for pass/fail regression checks on fixed inputs.</p><div class="note custom-block github-alert"><p class="custom-block-title">NOTE</p><p>Import paths here use <code>@cursor/july/ab</code>. On projects still using <code>@cursor/july</code>, swap the import. See <a href="./README.html#run-the-cli">Run the CLI</a> for the full rename table.</p></div><h2 id="choose-live-a-b-metrics-or-evals" tabindex="-1">Choose live A/B metrics or evals <a class="header-anchor" href="#choose-live-a-b-metrics-or-evals" aria-label="Permalink to &quot;Choose live A/B metrics or evals&quot;">​</a></h2><p>Both features read the session event stream, but they answer different questions.</p><table tabindex="0"><thead><tr><th></th><th>Live A/B metrics</th><th>Evals</th></tr></thead><tbody><tr><td>Question</td><td>How do variants compare on live sessions?</td><td>Does the agent still meet a fixed contract?</td></tr><tr><td>Location</td><td><code>agent/ab.ts</code> or <code>agent/ab/&lt;name&gt;.ts</code></td><td><code>evals/**/*.eval.ts</code></td></tr><tr><td>Input</td><td>Dev or production traffic</td><td>Frozen prompts and fixtures</td></tr><tr><td>Output</td><td>Cumulative metrics by session and arm</td><td>Pass/fail assertions</td></tr><tr><td>How it runs</td><td>Automatically on new live sessions</td><td><code>agent-sdk eval</code></td></tr></tbody></table><p>There is no <code>agent-sdk ab</code> command or assertion API.</p><h2 id="define-an-experiment" tabindex="-1">Define an experiment <a class="header-anchor" href="#define-an-experiment" aria-label="Permalink to &quot;Define an experiment&quot;">​</a></h2><p>Author one experiment in <code>agent/ab.ts</code>, add more under <code>agent/ab/&lt;name&gt;.ts</code>, or use both forms. Each file defines one experiment. The experiment name comes from <code>name</code> when set. Otherwise, The Agent SDK uses <code>ab</code> for <code>agent/ab.ts</code> and the file stem for files under <code>agent/ab/</code>.</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/ab/concise-weather.ts</span></span>
21
+ <div id="app"><div class="Layout" data-v-05085060><!--[--><!--]--><!--[--><span tabindex="-1" data-v-30dc752a></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-30dc752a>Skip to content</a><!--]--><!----><header class="VPNav" data-v-05085060 data-v-cbe59881><div class="VPNavBar" data-v-cbe59881 data-v-dd8a1864><div class="wrapper" data-v-dd8a1864><div class="container" data-v-dd8a1864><div class="title" data-v-dd8a1864><div class="VPNavBarTitle has-sidebar" data-v-dd8a1864 data-v-f9346b2b><a class="title" href="/docs/" data-v-f9346b2b><!--[--><!--]--><!----><span data-v-f9346b2b>Agent SDK</span><!--[--><!--]--></a></div></div><div class="content" data-v-dd8a1864><div class="content-body" data-v-dd8a1864><!--[--><!--]--><div class="VPNavBarSearch search" data-v-dd8a1864><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-dd8a1864 data-v-7ed6e5ac><span id="main-nav-aria-label" class="visually-hidden" data-v-7ed6e5ac> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/quickstart.html" tabindex="0" data-v-7ed6e5ac data-v-65720067><!--[--><span data-v-65720067>Quickstart</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/guides/webhooks.html" tabindex="0" data-v-7ed6e5ac data-v-65720067><!--[--><span data-v-65720067>Guides</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/example-agents/" tabindex="0" data-v-7ed6e5ac data-v-65720067><!--[--><span data-v-65720067>Examples</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/reference/project-layout.html" tabindex="0" data-v-7ed6e5ac data-v-65720067><!--[--><span data-v-65720067>Reference</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-dd8a1864 data-v-2b2b395e><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-2b2b395e data-v-182deabf data-v-2562b538><span class="check" data-v-2562b538><span class="icon" data-v-2562b538><!--[--><span class="vpi-sun sun" data-v-182deabf></span><span class="vpi-moon moon" data-v-182deabf></span><!--]--></span></span></button></div><!----><div class="VPFlyout VPNavBarExtra extra" data-v-dd8a1864 data-v-f3b584b7 data-v-82133de6><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-82133de6><span class="vpi-more-horizontal icon" data-v-82133de6></span></button><div class="menu" data-v-82133de6><div class="VPMenu" data-v-82133de6 data-v-759c9e19><!----><!--[--><!--[--><!----><div class="group" data-v-f3b584b7><div class="item appearance" data-v-f3b584b7><p class="label" data-v-f3b584b7>Appearance</p><div class="appearance-action" data-v-f3b584b7><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-f3b584b7 data-v-182deabf data-v-2562b538><span class="check" data-v-2562b538><span class="icon" data-v-2562b538><!--[--><span class="vpi-sun sun" data-v-182deabf></span><span class="vpi-moon moon" data-v-182deabf></span><!--]--></span></span></button></div></div></div><!----><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-dd8a1864 data-v-ab07e844><span class="container" data-v-ab07e844><span class="top" data-v-ab07e844></span><span class="middle" data-v-ab07e844></span><span class="bottom" data-v-ab07e844></span></span></button></div></div></div></div><div class="divider" data-v-dd8a1864><div class="divider-line" data-v-dd8a1864></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-05085060 data-v-826b8761><div class="container" data-v-826b8761><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-826b8761><span class="vpi-align-left menu-icon" data-v-826b8761></span><span class="menu-text" data-v-826b8761>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-826b8761 data-v-01af9e73><button data-v-01af9e73>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-05085060 data-v-5cd5b4d8><div class="curtain" data-v-5cd5b4d8></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-5cd5b4d8><span class="visually-hidden" id="sidebar-aria-label" data-v-5cd5b4d8> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Getting started</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Overview</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/quickstart.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Quickstart</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/scaffolding-agents.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Scaffold an agent with Cursor</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/concepts.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Concepts</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0 has-active" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Improving agents</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/building-with-agents.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Building agents with agents</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/evals.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Evals</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/ab.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Live A/B metrics</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/storage.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Storage</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/hillclimbing.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Hillclimbing</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Guides</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/webhooks.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Webhooks & custom channels</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/github.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>GitHub</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/slack.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Slack</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/human-in-the-loop.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Human-in-the-loop approvals</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/agent-to-agent.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Agent-to-agent</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/mcp-oauth.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Host MCP OAuth</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/guides/cloud-runtime.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Cloud runtime</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Example agents</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Choose an example</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/weather-agent.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Weather agent</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/slack-agent.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Slack agent</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/concierge.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Concierge</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/benny.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Playbook router</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/oncall.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Alert investigator</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/bugbot.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>PR evidence reviewer</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/approval-buddy.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Approval Buddy</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/security-reviewer.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Security Reviewer</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/fsd.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Remote PR coordinator</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/knowledge-base.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Knowledge base</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/codebase-wiki.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Codebase wiki</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/example-agents/codeowners-review.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Codeowners review</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Operating</h2><!----></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/deployment.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Deployment</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/troubleshooting.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Fix common problems</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-6b69f472><section class="VPSidebarItem level-0 collapsible" data-v-6b69f472 data-v-b6893b1b><div class="item" role="button" tabindex="0" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><h2 class="text" data-v-b6893b1b>Reference</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-b6893b1b><span class="vpi-chevron-right caret-icon" data-v-b6893b1b></span></div></div><div class="items" data-v-b6893b1b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/project-layout.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Project layout</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/agent-config.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Agent config</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/instructions.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Instructions</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/tools.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Tools</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/prompt.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>prompt</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/skills.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Skills</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/connections.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>MCP Connections</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/subagents.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Subagents</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/channels.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Channels</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/schedules.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Schedules & reminders</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/hooks.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Hooks</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/artifacts.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Artifacts</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/sessions.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Sessions & streaming</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/playground.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>Playground</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/cli.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>CLI</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b6893b1b><div class="item" data-v-b6893b1b><div class="indicator" data-v-b6893b1b></div><a class="VPLink link link" href="/docs/reference/http-api.html" data-v-b6893b1b><!--[--><p class="text" data-v-b6893b1b>HTTP API</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-05085060 data-v-8eedf2ac><div class="VPDoc has-sidebar has-aside" data-v-8eedf2ac data-v-53b9fda6><!--[--><!--]--><div class="container" data-v-53b9fda6><div class="aside" data-v-53b9fda6><div class="aside-curtain" data-v-53b9fda6></div><div class="aside-container" data-v-53b9fda6><div class="aside-content" data-v-53b9fda6><div class="VPDocAside" data-v-53b9fda6 data-v-e448ecab><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-e448ecab data-v-b0b42374><div class="content" data-v-b0b42374><div class="outline-marker" data-v-b0b42374></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-b0b42374>On this page</div><ul class="VPDocOutlineItem root" data-v-b0b42374 data-v-ae03bd52><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-e448ecab></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-53b9fda6><div class="content-container" data-v-53b9fda6><!--[--><!--]--><main class="main" data-v-53b9fda6><div style="position:relative;" class="vp-doc _docs_ab" data-v-53b9fda6><div><h1 id="live-a-b-metrics" tabindex="-1">Live A/B metrics <a class="header-anchor" href="#live-a-b-metrics" aria-label="Permalink to &quot;Live A/B metrics&quot;">​</a></h1><p>Use <code>defineAB</code> to compare variants on live agent sessions. New sessions receive a sticky assignment in each enrolled experiment. The Agent SDK folds their durable event streams into tool, token, failure, and wall-time metrics. You can send cumulative samples to your metrics backend and inspect aggregates in the playground.</p><p><code>defineAB</code> compares live variants through sticky assignment, instruction overlays, optional tool branches, and cumulative metrics. Metric callbacks observe the result without approving, rejecting, or failing a turn. Use <a href="./evals.html">evals</a> for pass/fail regression checks on fixed inputs.</p><div class="note custom-block github-alert"><p class="custom-block-title">NOTE</p><p>Import paths here use <code>@cursor/july/ab</code>. On projects still using <code>@anysphere/agent-serve</code>, swap the import. See <a href="./README.html#run-the-cli">Run the CLI</a> for the full rename table.</p></div><h2 id="choose-live-a-b-metrics-or-evals" tabindex="-1">Choose live A/B metrics or evals <a class="header-anchor" href="#choose-live-a-b-metrics-or-evals" aria-label="Permalink to &quot;Choose live A/B metrics or evals&quot;">​</a></h2><p>Both features read the session event stream, but they answer different questions.</p><table tabindex="0"><thead><tr><th></th><th>Live A/B metrics</th><th>Evals</th></tr></thead><tbody><tr><td>Question</td><td>How do variants compare on live sessions?</td><td>Does the agent still meet a fixed contract?</td></tr><tr><td>Location</td><td><code>agent/ab.ts</code> or <code>agent/ab/&lt;name&gt;.ts</code></td><td><code>evals/**/*.eval.ts</code></td></tr><tr><td>Input</td><td>Dev or production traffic</td><td>Frozen prompts and fixtures</td></tr><tr><td>Output</td><td>Cumulative metrics by session and arm</td><td>Pass/fail assertions</td></tr><tr><td>How it runs</td><td>Automatically on new live sessions</td><td><code>agent-sdk eval</code></td></tr></tbody></table><p>There is no <code>agent-sdk ab</code> command or assertion API.</p><h2 id="define-an-experiment" tabindex="-1">Define an experiment <a class="header-anchor" href="#define-an-experiment" aria-label="Permalink to &quot;Define an experiment&quot;">​</a></h2><p>Author one experiment in <code>agent/ab.ts</code>, add more under <code>agent/ab/&lt;name&gt;.ts</code>, or use both forms. Each file defines one experiment. The experiment name comes from <code>name</code> when set. Otherwise, The Agent SDK uses <code>ab</code> for <code>agent/ab.ts</code> and the file stem for files under <code>agent/ab/</code>.</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/ab/concise-weather.ts</span></span>
22
22
  <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
23
23
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> defineAB,</span></span>
24
24
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> splitBySessionHash,</span></span>
@@ -66,22 +66,13 @@
66
66
  <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> conciseWeatherResult;</span></span>
67
67
  <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
68
68
  <span class="line"></span>
69
- <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> baselineWeatherResult;</span></span></code></pre></div><p>This makes the assignment available to deterministic code as well as the model prompt. Use both patterns together when one experiment must steer the prompt and host code at once.</p><p><code>defineAB</code> does not select a different model or runtime for each arm. Keep those settings in <code>agent/agent.ts</code>, or write explicit host logic when your experiment needs another behavior lever.</p><p>The split and selected arm can affect agent behavior. <code>derive</code> and <code>onSample</code> only observe the resulting event stream. Errors in either callback are logged and never fail the turn.</p><h2 id="collect-built-in-and-custom-metrics" tabindex="-1">Collect built-in and custom metrics <a class="header-anchor" href="#collect-built-in-and-custom-metrics" aria-label="Permalink to &quot;Collect built-in and custom metrics&quot;">​</a></h2><p>Metrics accumulate for each session and experiment. When one session joins several experiments, every enrolled experiment folds the same turn and tool events into its own counters.</p><table tabindex="0"><thead><tr><th>Metric</th><th>How the Agent SDK calculates it</th></tr></thead><tbody><tr><td><code>turns</code></td><td>Adds one on <code>turn.completed</code> or <code>turn.failed</code></td></tr><tr><td><code>turnFailures</code></td><td>Adds one on <code>turn.failed</code></td></tr><tr><td><code>toolCalls</code></td><td>Adds one for each <code>action.result</code></td></tr><tr><td><code>toolErrors</code></td><td>Adds one when <code>action.result.data.isError</code> is true</td></tr><tr><td><code>inputTokens</code>, <code>outputTokens</code></td><td>Adds usage from completed turns</td></tr><tr><td><code>cacheReadTokens</code>, <code>cacheWriteTokens</code></td><td>Adds cache usage from completed turns</td></tr><tr><td><code>wallTimeMs</code></td><td>Sums the time from <code>turn.started</code> to its completed or failed event</td></tr><tr><td><code>custom</code></td><td>Sums finite numeric deltas returned by <code>derive</code></td></tr></tbody></table><p><code>onSample</code> fires after every <code>turn.completed</code> and <code>turn.failed</code> event for an enrolled arm. The sample contains:</p><table tabindex="0"><thead><tr><th>Field</th><th>Value</th></tr></thead><tbody><tr><td><code>experiment</code></td><td>Experiment name</td></tr><tr><td><code>variant</code>, <code>variantLabel?</code></td><td>Sticky arm and optional display label</td></tr><tr><td><code>sessionId</code>, <code>channelId</code></td><td>Source session</td></tr><tr><td><code>metrics</code></td><td>Cumulative metrics through this turn</td></tr><tr><td><code>reason</code></td><td><code>turn.completed</code> or <code>turn.failed</code></td></tr><tr><td><code>at</code></td><td>Terminal event timestamp</td></tr></tbody></table><p>The metrics are cumulative, not per-turn deltas. A second sample from the same session includes the first turn&#39;s counts.</p><p>Each <code>derive</code> extractor runs on every session event for its enrolled experiment, including streamed <code>message.appended</code> events. Keep it synchronous and cheap. Return a finite number to add a delta, or <code>null</code> to skip the event. Send samples to your metrics service from <code>onSample</code>; do not perform network or disk work in <code>derive</code>.</p><p>Skipped sessions never call <code>onSample</code>. Errors from <code>derive</code> or <code>onSample</code> are logged, then metric collection continues.</p><h2 id="inspect-assignments-and-results" tabindex="-1">Inspect assignments and results <a class="header-anchor" href="#inspect-assignments-and-results" aria-label="Permalink to &quot;Inspect assignments and results&quot;">​</a></h2><p>Open the playground&#39;s <strong>A/Bs</strong> tab to see aggregate arm totals and per-session assignments. The tab reads <code>GET /v1/abs</code>.</p><p>The response has two views of the same durable data:</p><table tabindex="0"><thead><tr><th>Field</th><th>Contents</th></tr></thead><tbody><tr><td><code>experiments</code></td><td>Declared variants, skipped-session count, arm session counts, and aggregate metrics</td></tr><tr><td><code>sessions</code></td><td>Visible sessions with their assignments and cumulative metrics</td></tr></tbody></table><p><code>GET /v1/abs</code> returns sessions visible to the current principal by default. In <code>--dev</code>, loopback requests include every session. Add <code>--allow-anonymous</code> to include every session from non-loopback callers too. This include-all behavior can still apply to <code>GET /v1/abs</code> in dev when bearer or custom auth keeps <code>GET /v1/sessions</code> owner-scoped.</p><p>Session <code>events.ndjson</code> is the source of truth for assignment + fold. <code>GET /v1/abs</code> recomputes aggregates from those logs. Use <code>agent/ab.config.ts</code> (and/or each experiment&#39;s <code>onSample</code>) when you want author-controlled sample/snapshot exports — same idea as eval <code>persistRuns</code>.</p><h2 id="configure-retention-and-persistence" tabindex="-1">Configure retention and persistence <a class="header-anchor" href="#configure-retention-and-persistence" aria-label="Permalink to &quot;Configure retention and persistence&quot;">​</a></h2><p>Optional project defaults in <code>agent/ab.config.ts</code>:</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;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
70
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> defineABConfig,</span></span>
71
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> persistABSamplesToDir,</span></span>
72
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> persistABSnapshotsToDir,</span></span>
73
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july/ab&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
69
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> baselineWeatherResult;</span></span></code></pre></div><p>This makes the assignment available to deterministic code as well as the model prompt. Use both patterns together when one experiment must steer the prompt and host code at once.</p><p><code>defineAB</code> does not select a different model or runtime for each arm. Keep those settings in <code>agent/agent.ts</code>, or write explicit host logic when your experiment needs another behavior lever.</p><p>The split and selected arm can affect agent behavior. <code>derive</code> and <code>onSample</code> only observe the resulting event stream. Errors in either callback are logged and never fail the turn.</p><h2 id="collect-built-in-and-custom-metrics" tabindex="-1">Collect built-in and custom metrics <a class="header-anchor" href="#collect-built-in-and-custom-metrics" aria-label="Permalink to &quot;Collect built-in and custom metrics&quot;">​</a></h2><p>Metrics accumulate for each session and experiment. When one session joins several experiments, every enrolled experiment folds the same turn and tool events into its own counters.</p><table tabindex="0"><thead><tr><th>Metric</th><th>How the Agent SDK calculates it</th></tr></thead><tbody><tr><td><code>turns</code></td><td>Adds one on <code>turn.completed</code> or <code>turn.failed</code></td></tr><tr><td><code>turnFailures</code></td><td>Adds one on <code>turn.failed</code></td></tr><tr><td><code>toolCalls</code></td><td>Adds one for each <code>action.result</code></td></tr><tr><td><code>toolErrors</code></td><td>Adds one when <code>action.result.data.isError</code> is true</td></tr><tr><td><code>inputTokens</code>, <code>outputTokens</code></td><td>Adds usage from completed turns</td></tr><tr><td><code>cacheReadTokens</code>, <code>cacheWriteTokens</code></td><td>Adds cache usage from completed turns</td></tr><tr><td><code>costUsd</code></td><td>Sums the estimated turn cost recorded on <code>turn.completed</code> (turns whose model has no known rates contribute 0)</td></tr><tr><td><code>wallTimeMs</code></td><td>Sums the time from <code>turn.started</code> to its completed or failed event</td></tr><tr><td><code>custom</code></td><td>Sums finite numeric deltas returned by <code>derive</code></td></tr></tbody></table><p><code>onSample</code> fires after every <code>turn.completed</code> and <code>turn.failed</code> event for an enrolled arm. The sample contains:</p><table tabindex="0"><thead><tr><th>Field</th><th>Value</th></tr></thead><tbody><tr><td><code>experiment</code></td><td>Experiment name</td></tr><tr><td><code>variant</code>, <code>variantLabel?</code></td><td>Sticky arm and optional display label</td></tr><tr><td><code>sessionId</code>, <code>channelId</code></td><td>Source session</td></tr><tr><td><code>metrics</code></td><td>Cumulative metrics through this turn</td></tr><tr><td><code>reason</code></td><td><code>turn.completed</code> or <code>turn.failed</code></td></tr><tr><td><code>at</code></td><td>Terminal event timestamp</td></tr></tbody></table><p>The metrics are cumulative, not per-turn deltas. A second sample from the same session includes the first turn&#39;s counts.</p><p>Each <code>derive</code> extractor runs on every session event for its enrolled experiment, including streamed <code>message.appended</code> events. Keep it synchronous and cheap. Return a finite number to add a delta, or <code>null</code> to skip the event. Send samples to your metrics service from <code>onSample</code>; do not perform network or disk work in <code>derive</code>.</p><p>Skipped sessions never call <code>onSample</code>. Errors from <code>derive</code> or <code>onSample</code> are logged, then metric collection continues.</p><h2 id="inspect-assignments-and-results" tabindex="-1">Inspect assignments and results <a class="header-anchor" href="#inspect-assignments-and-results" aria-label="Permalink to &quot;Inspect assignments and results&quot;">​</a></h2><p>Open the playground&#39;s <strong>A/Bs</strong> tab to see aggregate arm totals and per-session assignments. The tab reads <code>GET /v1/abs</code>.</p><p>The response has two views of the same durable data:</p><table tabindex="0"><thead><tr><th>Field</th><th>Contents</th></tr></thead><tbody><tr><td><code>experiments</code></td><td>Declared variants, skipped-session count, arm session counts, and aggregate metrics</td></tr><tr><td><code>sessions</code></td><td>Visible sessions with their assignments and cumulative metrics</td></tr></tbody></table><p><code>GET /v1/abs</code> returns sessions visible to the current principal by default. In <code>--dev</code>, loopback requests include every session. Add <code>--allow-anonymous</code> to include every session from non-loopback callers too. This include-all behavior can still apply to <code>GET /v1/abs</code> in dev when bearer or custom auth keeps <code>GET /v1/sessions</code> owner-scoped.</p><p>Session <code>events.ndjson</code> is the source of truth for assignment + fold. <code>GET /v1/abs</code> recomputes aggregates from those logs. For durable sample and snapshot export, declare an <code>abs</code> table in <code>agent/storage.ts</code> — same idea as the eval-runs table. See <a href="./storage.html#eval-and-ab-tables">Storage</a>.</p><h2 id="configure-the-playground-fold-window" tabindex="-1">Configure the playground fold window <a class="header-anchor" href="#configure-the-playground-fold-window" aria-label="Permalink to &quot;Configure the playground fold window&quot;">​</a></h2><p>Assignments and foldable metrics already persist in each session&#39;s <code>events.ndjson</code> under <code>--state-root</code>. The optional <code>agent/ab.config.ts</code> only caps how many sessions the playground and <code>GET /v1/abs</code> fold:</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;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineABConfig } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;@cursor/july/ab&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
74
70
  <span class="line"></span>
75
71
  <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;"> defineABConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
76
72
  <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Optional — defaults to 200. Only affects GET /v1/abs / A/Bs tab.</span></span>
77
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // maxPlaygroundSessions: 200,</span></span>
78
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // retainSnapshots: 20,</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // prune budget for persistABSnapshotsToDir</span></span>
79
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Append onSample payloads (in addition to each experiment&#39;s onSample)</span></span>
80
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> persistSamples: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">persistABSamplesToDir</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;.agent-serve/ab-samples&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
81
- <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Save aggregate snapshots whenever GET /v1/abs runs</span></span>
82
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> persistSnapshots: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">persistABSnapshotsToDir</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;.agent-serve/ab-snapshots&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
83
- <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><table tabindex="0"><thead><tr><th>Option</th><th>Default</th><th>Meaning</th></tr></thead><tbody><tr><td><code>maxPlaygroundSessions</code></td><td><code>200</code></td><td>Max newest sessions folded into the playground / <code>GET /v1/abs</code> (not session logs or <code>persistSamples</code>)</td></tr><tr><td><code>persistSamples</code></td><td>unset</td><td>Durable sink for metric samples (<code>save(sample, ctx)</code>)</td></tr><tr><td><code>persistSnapshots</code></td><td>unset</td><td>Durable store for aggregate snapshots (<code>load</code> / <code>save</code> / optional <code>delete</code>)</td></tr><tr><td><code>retainSnapshots</code></td><td><code>20</code> when snapshots persist</td><td>Snapshot files kept after prune (<code>persistABSnapshotsToDir</code> honors this)</td></tr></tbody></table><p>Implement your own <code>{ save }</code> / <code>{ load, save, delete? }</code> for S3, a DB, or your metrics vendor. Without <code>persistSamples</code> / <code>persistSnapshots</code>, samples only go where each experiment&#39;s <code>onSample</code> sends them, and aggregates exist only as a live fold over session logs.</p><h2 id="keep-assignments-durable" tabindex="-1">Keep assignments durable <a class="header-anchor" href="#keep-assignments-durable" aria-label="Permalink to &quot;Keep assignments durable&quot;">​</a></h2><p>The append-only <code>events.ndjson</code> stream is the source of truth. Each <code>ab.assigned</code> event persists a variant key or null skip. Built-in metrics come from the turn and tool events that follow it.</p><p>After a server restart or a parked session resumes, the live collector replays the stream to rebuild cumulative counters. Replay does not call <code>onSample</code> (or <code>persistSamples</code>) for historical turns. Only a new completed or failed turn emits another sample.</p><p>The snapshot API also replays <code>derive</code> across the full stream, so custom totals match the current extractor. Changing a derive function can change historical snapshot totals. Treat metric definitions as versioned experiment code.</p><h2 id="keep-eval-traffic-separate" tabindex="-1">Keep eval traffic separate <a class="header-anchor" href="#keep-eval-traffic-separate" aria-label="Permalink to &quot;Keep eval traffic separate&quot;">​</a></h2><p>Sessions created by <code>agent-sdk eval</code> and the playground Evals runner use <code>purpose: &quot;eval&quot;</code>. They skip A/B enrollment entirely:</p><ul><li>No split function runs.</li><li>No <code>ab.assigned</code> event is recorded.</li><li>No <code>onSample</code> callback fires.</li><li>The session is omitted from <code>GET /v1/abs</code>.</li></ul><p>Ordinary chat, <code>agent-sdk run</code>, Slack, GitHub, and other channel sessions use the live purpose. You do not need <code>splitIf</code> to exclude eval traffic.</p><h2 id="know-the-boundaries" tabindex="-1">Know the boundaries <a class="header-anchor" href="#know-the-boundaries" aria-label="Permalink to &quot;Know the boundaries&quot;">​</a></h2><p><code>defineAB</code> provides sticky assignment, variant instructions, <code>session.abs</code> for tools, cumulative metrics, and local inspection. It does not provide:</p><ul><li>A test command, assertion API, or pass/fail result</li><li>Statistical significance calculations</li><li>An experiment rollout or lifecycle service</li><li>Per-variant model or runtime configuration</li><li>A built-in analytics warehouse (bring your own via <code>persistSamples</code> / <code>persistSnapshots</code> / <code>onSample</code>)</li></ul><p>Use <a href="./evals.html">evals</a> to protect known behavior. Configure <code>agent/ab.config.ts</code> (or <code>onSample</code>) when you need sample/snapshot exports beyond the session event log.</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><p>Continue with these pages:</p><ul><li><a href="./evals.html">Evals</a>: pass/fail regression checks on fixed inputs</li><li><a href="./hillclimbing.html">Hillclimbing</a>: improve an agent against fixed fixtures</li><li><a href="./reference/hooks.html">Hooks</a>: other event-stream consumers</li><li><a href="./reference/sessions.html">Sessions and streaming</a>: the <code>ab.assigned</code> event and durable log</li><li><a href="./reference/playground.html">Playground</a>: the A/Bs tab</li><li><a href="./reference/http-api.html">HTTP API</a>: <code>GET /v1/abs</code></li><li><a href="./../skills/ab/SKILL.html">Live A/B metrics skill</a>: have a coding agent wire an experiment</li></ul></div></div></main><footer class="VPDocFooter" data-v-53b9fda6 data-v-3958cc3f><!--[--><!--]--><!----><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-3958cc3f><span class="visually-hidden" id="doc-footer-aria-label" data-v-3958cc3f>Pager</span><div class="pager" data-v-3958cc3f><a class="VPLink link pager-link prev" href="/docs/evals.html" data-v-3958cc3f><!--[--><span class="desc" data-v-3958cc3f>Previous page</span><span class="title" data-v-3958cc3f>Evals</span><!--]--></a></div><div class="pager" data-v-3958cc3f><a class="VPLink link pager-link next" href="/docs/storage.html" data-v-3958cc3f><!--[--><span class="desc" data-v-3958cc3f>Next page</span><span class="title" data-v-3958cc3f>Storage</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
84
- <script>window.__VP_HASH_MAP__=JSON.parse("{\"ab.md\":\"DAQoJ-up\",\"building-with-agents.md\":\"CnHqvYDd\",\"concepts.md\":\"DFaQEFkA\",\"deployment.md\":\"9MYBuKM1\",\"evals.md\":\"BIUoVZ6X\",\"example-agents_approval-buddy.md\":\"BhEfleVx\",\"example-agents_benny.md\":\"2Et1qa8f\",\"example-agents_bugbot.md\":\"ByUexi5i\",\"example-agents_codebase-wiki.md\":\"B4y-7ZVW\",\"example-agents_codeowners-review.md\":\"D6ay4nvf\",\"example-agents_concierge.md\":\"lL8rhYlj\",\"example-agents_fsd.md\":\"DfNKQTHz\",\"example-agents_index.md\":\"DgGBwckv\",\"example-agents_knowledge-base.md\":\"CzyZ2DCr\",\"example-agents_oncall.md\":\"wFFXXEyW\",\"example-agents_security-reviewer.md\":\"Dkf1gyo6\",\"example-agents_slack-agent.md\":\"DvgvT4nn\",\"example-agents_weather-agent.md\":\"BADkPqxQ\",\"guides_agent-to-agent.md\":\"Bmbxy-FA\",\"guides_cloud-runtime.md\":\"CDJGvVC4\",\"guides_github.md\":\"R2QlpR75\",\"guides_human-in-the-loop.md\":\"BWvT7UqY\",\"guides_mcp-oauth.md\":\"C7G7IykG\",\"guides_slack.md\":\"zriQpU_9\",\"guides_webhooks.md\":\"DiAwSR42\",\"hillclimbing.md\":\"D9Y1_bYh\",\"index.md\":\"CZqbBJPB\",\"quickstart.md\":\"TnEXYgYW\",\"reference_agent-config.md\":\"kuN6-OxK\",\"reference_channels.md\":\"CDhTRfUz\",\"reference_cli.md\":\"sD-IUWjg\",\"reference_connections.md\":\"DGqAsFXb\",\"reference_hooks.md\":\"DyLVfE1O\",\"reference_http-api.md\":\"CfVM_ICa\",\"reference_instructions.md\":\"CgoV-YEb\",\"reference_playground.md\":\"CPZhfYaO\",\"reference_project-layout.md\":\"D8E6ZmHJ\",\"reference_prompt.md\":\"BaiweQxE\",\"reference_schedules.md\":\"gmfYzf_I\",\"reference_sessions.md\":\"C_ouF_uf\",\"reference_skills.md\":\"B_jHN7JL\",\"reference_subagents.md\":\"zWAMNfi1\",\"reference_tools.md\":\"BswAQM41\",\"scaffolding-agents.md\":\"Bsr9Pwzu\",\"storage.md\":\"xZoiGM58\",\"troubleshooting.md\":\"B5RVX_tL\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Agent SDK\",\"description\":\"Filesystem-first framework for building and serving Cursor agents.\",\"base\":\"/docs/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Guides\",\"link\":\"/guides/webhooks\"},{\"text\":\"Examples\",\"link\":\"/example-agents/\"},{\"text\":\"Reference\",\"link\":\"/reference/project-layout\"}],\"search\":{\"provider\":\"local\"},\"outline\":{\"level\":[2,3]},\"sidebar\":[{\"text\":\"Getting started\",\"items\":[{\"text\":\"Overview\",\"link\":\"/\"},{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Scaffold an agent with Cursor\",\"link\":\"/scaffolding-agents\"},{\"text\":\"Concepts\",\"link\":\"/concepts\"}]},{\"text\":\"Improving agents\",\"items\":[{\"text\":\"Building agents with agents\",\"link\":\"/building-with-agents\"},{\"text\":\"Evals\",\"link\":\"/evals\"},{\"text\":\"Live A/B metrics\",\"link\":\"/ab\"},{\"text\":\"Storage\",\"link\":\"/storage\"},{\"text\":\"Hillclimbing\",\"link\":\"/hillclimbing\"}]},{\"text\":\"Guides\",\"items\":[{\"text\":\"Webhooks & custom channels\",\"link\":\"/guides/webhooks\"},{\"text\":\"GitHub\",\"link\":\"/guides/github\"},{\"text\":\"Slack\",\"link\":\"/guides/slack\"},{\"text\":\"Human-in-the-loop approvals\",\"link\":\"/guides/human-in-the-loop\"},{\"text\":\"Agent-to-agent\",\"link\":\"/guides/agent-to-agent\"},{\"text\":\"Cloud runtime\",\"link\":\"/guides/cloud-runtime\"}]},{\"text\":\"Example agents\",\"items\":[{\"text\":\"Choose an example\",\"link\":\"/example-agents/\"},{\"text\":\"Weather agent\",\"link\":\"/example-agents/weather-agent\"},{\"text\":\"Slack agent\",\"link\":\"/example-agents/slack-agent\"},{\"text\":\"Concierge\",\"link\":\"/example-agents/concierge\"},{\"text\":\"Playbook router\",\"link\":\"/example-agents/benny\"},{\"text\":\"Alert investigator\",\"link\":\"/example-agents/oncall\"},{\"text\":\"PR evidence reviewer\",\"link\":\"/example-agents/bugbot\"},{\"text\":\"Approval Buddy\",\"link\":\"/example-agents/approval-buddy\"},{\"text\":\"Security Reviewer\",\"link\":\"/example-agents/security-reviewer\"},{\"text\":\"Remote PR coordinator\",\"link\":\"/example-agents/fsd\"},{\"text\":\"Knowledge base\",\"link\":\"/example-agents/knowledge-base\"},{\"text\":\"Codebase wiki\",\"link\":\"/example-agents/codebase-wiki\"},{\"text\":\"Codeowners review\",\"link\":\"/example-agents/codeowners-review\"}]},{\"text\":\"Operating\",\"items\":[{\"text\":\"Deployment\",\"link\":\"/deployment\"},{\"text\":\"Fix common problems\",\"link\":\"/troubleshooting\"}]},{\"text\":\"Reference\",\"collapsed\":false,\"items\":[{\"text\":\"Project layout\",\"link\":\"/reference/project-layout\"},{\"text\":\"Agent config\",\"link\":\"/reference/agent-config\"},{\"text\":\"Instructions\",\"link\":\"/reference/instructions\"},{\"text\":\"Tools\",\"link\":\"/reference/tools\"},{\"text\":\"prompt\",\"link\":\"/reference/prompt\"},{\"text\":\"Skills\",\"link\":\"/reference/skills\"},{\"text\":\"MCP Connections\",\"link\":\"/reference/connections\"},{\"text\":\"Subagents\",\"link\":\"/reference/subagents\"},{\"text\":\"Channels\",\"link\":\"/reference/channels\"},{\"text\":\"Schedules & reminders\",\"link\":\"/reference/schedules\"},{\"text\":\"Hooks\",\"link\":\"/reference/hooks\"},{\"text\":\"Sessions & streaming\",\"link\":\"/reference/sessions\"},{\"text\":\"Playground\",\"link\":\"/reference/playground\"},{\"text\":\"CLI\",\"link\":\"/reference/cli\"},{\"text\":\"HTTP API\",\"link\":\"/reference/http-api\"}]}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
73
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> maxPlaygroundSessions: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">500</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
74
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p><code>maxPlaygroundSessions</code> keeps the newest sessions in the fold. It does not prune session logs or change assignment. For export to S3, a DB, or your metrics vendor, send samples from <code>onSample</code> or declare a storage <code>abs</code> table.</p><h2 id="keep-assignments-durable" tabindex="-1">Keep assignments durable <a class="header-anchor" href="#keep-assignments-durable" aria-label="Permalink to &quot;Keep assignments durable&quot;">​</a></h2><p>The append-only <code>events.ndjson</code> stream is the source of truth. Each <code>ab.assigned</code> event persists a variant key or null skip. Built-in metrics come from the turn and tool events that follow it.</p><p>After a server restart or a parked session resumes, the live collector replays the stream to rebuild cumulative counters. Replay does not call <code>onSample</code> (or write to the storage <code>abs</code> table) for historical turns. Only a new completed or failed turn emits another sample.</p><p>The snapshot API also replays <code>derive</code> across the full stream, so custom totals match the current extractor. Changing a derive function can change historical snapshot totals. Treat metric definitions as versioned experiment code.</p><h2 id="keep-eval-traffic-separate" tabindex="-1">Keep eval traffic separate <a class="header-anchor" href="#keep-eval-traffic-separate" aria-label="Permalink to &quot;Keep eval traffic separate&quot;">​</a></h2><p>Sessions created by <code>agent-sdk eval</code> and the playground Evals runner use <code>purpose: &quot;eval&quot;</code>. They skip A/B enrollment entirely:</p><ul><li>No split function runs.</li><li>No <code>ab.assigned</code> event is recorded.</li><li>No <code>onSample</code> callback fires.</li><li>The session is omitted from <code>GET /v1/abs</code>.</li></ul><p>Ordinary chat, <code>agent-sdk run</code>, Slack, GitHub, and other channel sessions use the live purpose. You do not need <code>splitIf</code> to exclude eval traffic.</p><h2 id="know-the-boundaries" tabindex="-1">Know the boundaries <a class="header-anchor" href="#know-the-boundaries" aria-label="Permalink to &quot;Know the boundaries&quot;">​</a></h2><p><code>defineAB</code> provides sticky assignment, variant instructions, <code>session.abs</code> for tools, cumulative metrics, and local inspection. It does not provide:</p><ul><li>A test command, assertion API, or pass/fail result</li><li>Statistical significance calculations</li><li>An experiment rollout or lifecycle service</li><li>Per-variant model or runtime configuration</li><li>A built-in analytics warehouse (bring your own via <code>onSample</code> or the storage <code>abs</code> table)</li></ul><p>Use <a href="./evals.html">evals</a> to protect known behavior. Use <code>onSample</code> or a storage <code>abs</code> table when you need sample/snapshot exports beyond the session event log.</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><p>Continue with these pages:</p><ul><li><a href="./evals.html">Evals</a>: pass/fail regression checks on fixed inputs</li><li><a href="./hillclimbing.html">Hillclimbing</a>: improve an agent against fixed fixtures</li><li><a href="./reference/hooks.html">Hooks</a>: other event-stream consumers</li><li><a href="./reference/sessions.html">Sessions and streaming</a>: the <code>ab.assigned</code> event and durable log</li><li><a href="./reference/playground.html">Playground</a>: the A/Bs tab</li><li><a href="./reference/http-api.html">HTTP API</a>: <code>GET /v1/abs</code></li><li><a href="./../skills/ab/SKILL.html">Live A/B metrics skill</a>: have a coding agent wire an experiment</li></ul></div></div></main><footer class="VPDocFooter" data-v-53b9fda6 data-v-3958cc3f><!--[--><!--]--><!----><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-3958cc3f><span class="visually-hidden" id="doc-footer-aria-label" data-v-3958cc3f>Pager</span><div class="pager" data-v-3958cc3f><a class="VPLink link pager-link prev" href="/docs/evals.html" data-v-3958cc3f><!--[--><span class="desc" data-v-3958cc3f>Previous page</span><span class="title" data-v-3958cc3f>Evals</span><!--]--></a></div><div class="pager" data-v-3958cc3f><a class="VPLink link pager-link next" href="/docs/storage.html" data-v-3958cc3f><!--[--><span class="desc" data-v-3958cc3f>Next page</span><span class="title" data-v-3958cc3f>Storage</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
75
+ <script>window.__VP_HASH_MAP__=JSON.parse("{\"ab.md\":\"6cLOW7--\",\"building-with-agents.md\":\"txrcGU2B\",\"concepts.md\":\"CqOsxbMU\",\"deployment.md\":\"CuK5SNjN\",\"evals.md\":\"BQXI3rXy\",\"example-agents_approval-buddy.md\":\"CIiZ9coo\",\"example-agents_benny.md\":\"l7JTmm8X\",\"example-agents_bugbot.md\":\"Dp5JqHSQ\",\"example-agents_codebase-wiki.md\":\"D-lteFf0\",\"example-agents_codeowners-review.md\":\"BU2ZXLf-\",\"example-agents_concierge.md\":\"DA2al_NK\",\"example-agents_fsd.md\":\"DPz9ezO4\",\"example-agents_index.md\":\"DgGBwckv\",\"example-agents_knowledge-base.md\":\"IneynQSR\",\"example-agents_oncall.md\":\"ZE0n6ZFN\",\"example-agents_security-reviewer.md\":\"Dkf1gyo6\",\"example-agents_slack-agent.md\":\"06jQXTAI\",\"example-agents_weather-agent.md\":\"CrGZ0SqR\",\"guides_agent-to-agent.md\":\"Bmbxy-FA\",\"guides_cloud-runtime.md\":\"V5igN4Sq\",\"guides_github.md\":\"R2QlpR75\",\"guides_human-in-the-loop.md\":\"BWvT7UqY\",\"guides_mcp-oauth.md\":\"C7G7IykG\",\"guides_slack.md\":\"zriQpU_9\",\"guides_webhooks.md\":\"BERuBSJW\",\"hillclimbing.md\":\"yXqdlv2R\",\"index.md\":\"CmhptOmN\",\"quickstart.md\":\"C_b6ESpD\",\"reference_agent-config.md\":\"CRmkoxd6\",\"reference_artifacts.md\":\"BGG4bZo-\",\"reference_channels.md\":\"BIabFUAI\",\"reference_cli.md\":\"Byvrg8eu\",\"reference_connections.md\":\"DGqAsFXb\",\"reference_hooks.md\":\"BGDw4VLm\",\"reference_http-api.md\":\"DGrw_wOu\",\"reference_instructions.md\":\"CgoV-YEb\",\"reference_playground.md\":\"CPZhfYaO\",\"reference_project-layout.md\":\"_XdeMahr\",\"reference_prompt.md\":\"BaiweQxE\",\"reference_schedules.md\":\"gmfYzf_I\",\"reference_sessions.md\":\"DBVFi2Sx\",\"reference_skills.md\":\"B_jHN7JL\",\"reference_subagents.md\":\"DSrGLIuB\",\"reference_tools.md\":\"lSrsTxYJ\",\"scaffolding-agents.md\":\"mkc3B_ZW\",\"storage.md\":\"mQDtIULc\",\"troubleshooting.md\":\"B5RVX_tL\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Agent SDK\",\"description\":\"Filesystem-first framework for building and serving Cursor agents.\",\"base\":\"/docs/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Guides\",\"link\":\"/guides/webhooks\"},{\"text\":\"Examples\",\"link\":\"/example-agents/\"},{\"text\":\"Reference\",\"link\":\"/reference/project-layout\"}],\"search\":{\"provider\":\"local\"},\"outline\":{\"level\":[2,3]},\"sidebar\":[{\"text\":\"Getting started\",\"items\":[{\"text\":\"Overview\",\"link\":\"/\"},{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Scaffold an agent with Cursor\",\"link\":\"/scaffolding-agents\"},{\"text\":\"Concepts\",\"link\":\"/concepts\"}]},{\"text\":\"Improving agents\",\"items\":[{\"text\":\"Building agents with agents\",\"link\":\"/building-with-agents\"},{\"text\":\"Evals\",\"link\":\"/evals\"},{\"text\":\"Live A/B metrics\",\"link\":\"/ab\"},{\"text\":\"Storage\",\"link\":\"/storage\"},{\"text\":\"Hillclimbing\",\"link\":\"/hillclimbing\"}]},{\"text\":\"Guides\",\"items\":[{\"text\":\"Webhooks & custom channels\",\"link\":\"/guides/webhooks\"},{\"text\":\"GitHub\",\"link\":\"/guides/github\"},{\"text\":\"Slack\",\"link\":\"/guides/slack\"},{\"text\":\"Human-in-the-loop approvals\",\"link\":\"/guides/human-in-the-loop\"},{\"text\":\"Agent-to-agent\",\"link\":\"/guides/agent-to-agent\"},{\"text\":\"Host MCP OAuth\",\"link\":\"/guides/mcp-oauth\"},{\"text\":\"Cloud runtime\",\"link\":\"/guides/cloud-runtime\"}]},{\"text\":\"Example agents\",\"items\":[{\"text\":\"Choose an example\",\"link\":\"/example-agents/\"},{\"text\":\"Weather agent\",\"link\":\"/example-agents/weather-agent\"},{\"text\":\"Slack agent\",\"link\":\"/example-agents/slack-agent\"},{\"text\":\"Concierge\",\"link\":\"/example-agents/concierge\"},{\"text\":\"Playbook router\",\"link\":\"/example-agents/benny\"},{\"text\":\"Alert investigator\",\"link\":\"/example-agents/oncall\"},{\"text\":\"PR evidence reviewer\",\"link\":\"/example-agents/bugbot\"},{\"text\":\"Approval Buddy\",\"link\":\"/example-agents/approval-buddy\"},{\"text\":\"Security Reviewer\",\"link\":\"/example-agents/security-reviewer\"},{\"text\":\"Remote PR coordinator\",\"link\":\"/example-agents/fsd\"},{\"text\":\"Knowledge base\",\"link\":\"/example-agents/knowledge-base\"},{\"text\":\"Codebase wiki\",\"link\":\"/example-agents/codebase-wiki\"},{\"text\":\"Codeowners review\",\"link\":\"/example-agents/codeowners-review\"}]},{\"text\":\"Operating\",\"items\":[{\"text\":\"Deployment\",\"link\":\"/deployment\"},{\"text\":\"Fix common problems\",\"link\":\"/troubleshooting\"}]},{\"text\":\"Reference\",\"collapsed\":false,\"items\":[{\"text\":\"Project layout\",\"link\":\"/reference/project-layout\"},{\"text\":\"Agent config\",\"link\":\"/reference/agent-config\"},{\"text\":\"Instructions\",\"link\":\"/reference/instructions\"},{\"text\":\"Tools\",\"link\":\"/reference/tools\"},{\"text\":\"prompt\",\"link\":\"/reference/prompt\"},{\"text\":\"Skills\",\"link\":\"/reference/skills\"},{\"text\":\"MCP Connections\",\"link\":\"/reference/connections\"},{\"text\":\"Subagents\",\"link\":\"/reference/subagents\"},{\"text\":\"Channels\",\"link\":\"/reference/channels\"},{\"text\":\"Schedules & reminders\",\"link\":\"/reference/schedules\"},{\"text\":\"Hooks\",\"link\":\"/reference/hooks\"},{\"text\":\"Artifacts\",\"link\":\"/reference/artifacts\"},{\"text\":\"Sessions & streaming\",\"link\":\"/reference/sessions\"},{\"text\":\"Playground\",\"link\":\"/reference/playground\"},{\"text\":\"CLI\",\"link\":\"/reference/cli\"},{\"text\":\"HTTP API\",\"link\":\"/reference/http-api\"}]}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
85
76
 
86
77
  </body>
87
78
  </html>