@cursor/july 0.1.29 → 0.1.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/README.md +10 -5
- package/dist/bin/agent-serve.js +4 -4
- package/dist/channels/github/index.d.ts +1 -1
- package/dist/channels/github/index.js +1 -1
- package/dist/channels/slack/bot-mentions.d.ts +1 -1
- package/dist/channels/slack/bot-mentions.d.ts.map +1 -1
- package/dist/channels/slack/bot-mentions.js +1 -1
- package/dist/channels/slack/eval-directive.js +1 -1
- package/dist/channels/slack/external-policy.d.ts +1 -1
- package/dist/channels/slack/external-policy.js +1 -1
- package/dist/channels/slack/log.d.ts +1 -1
- package/dist/channels/slack/log.js +1 -1
- package/dist/channels/slack/setup.js +1 -1
- package/dist/channels/slack/socket-mode.js +1 -1
- package/dist/docs/404.html +3 -3
- package/dist/docs/ab.html +11 -11
- package/dist/docs/assets/{ab.md.BMCZ6Hd7.js → ab.md.DAQoJ-up.js} +6 -6
- package/dist/docs/assets/{ab.md.BMCZ6Hd7.lean.js → ab.md.DAQoJ-up.lean.js} +1 -1
- package/dist/docs/assets/{app.QdunVQKg.js → app.DigB_9cQ.js} +1 -1
- package/dist/docs/assets/building-with-agents.md.CnHqvYDd.js +13 -0
- package/dist/docs/assets/{building-with-agents.md.CJCtZCyi.lean.js → building-with-agents.md.CnHqvYDd.lean.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CnFFl07y.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.B6EpUXYf.js → VPLocalSearchBox.BCMX25Bv.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BOTJVqh7.js → theme.BDDWeELx.js} +2 -2
- package/dist/docs/assets/concepts.md.DFaQEFkA.js +4 -0
- package/dist/docs/assets/concepts.md.DFaQEFkA.lean.js +1 -0
- package/dist/docs/assets/deployment.md.9MYBuKM1.js +55 -0
- package/dist/docs/assets/deployment.md.9MYBuKM1.lean.js +1 -0
- package/dist/docs/assets/{evals.md.DYOjkRCX.js → evals.md.BIUoVZ6X.js} +13 -13
- package/dist/docs/assets/evals.md.BIUoVZ6X.lean.js +1 -0
- package/dist/docs/assets/{example-agents_approval-buddy.md.DFGBYLcc.js → example-agents_approval-buddy.md.BhEfleVx.js} +4 -4
- package/dist/docs/assets/{example-agents_approval-buddy.md.DFGBYLcc.lean.js → example-agents_approval-buddy.md.BhEfleVx.lean.js} +1 -1
- package/dist/docs/assets/example-agents_benny.md.2Et1qa8f.js +7 -0
- package/dist/docs/assets/{example-agents_bugbot.md.DelIdhxB.js → example-agents_bugbot.md.ByUexi5i.js} +5 -5
- package/dist/docs/assets/{example-agents_codebase-wiki.md.DC6sgwn0.js → example-agents_codebase-wiki.md.B4y-7ZVW.js} +6 -6
- package/dist/docs/assets/{example-agents_codebase-wiki.md.DC6sgwn0.lean.js → example-agents_codebase-wiki.md.B4y-7ZVW.lean.js} +1 -1
- package/dist/docs/assets/{example-agents_codeowners-review.md.Ku_tG2RY.js → example-agents_codeowners-review.md.D6ay4nvf.js} +6 -6
- package/dist/docs/assets/{example-agents_codeowners-review.md.Ku_tG2RY.lean.js → example-agents_codeowners-review.md.D6ay4nvf.lean.js} +1 -1
- package/dist/docs/assets/{example-agents_concierge.md.4rQTSMXt.js → example-agents_concierge.md.lL8rhYlj.js} +7 -7
- package/dist/docs/assets/{example-agents_fsd.md.CzgUrDfi.js → example-agents_fsd.md.DfNKQTHz.js} +5 -5
- package/dist/docs/assets/example-agents_index.md.DgGBwckv.js +2 -0
- package/dist/docs/assets/example-agents_index.md.DgGBwckv.lean.js +1 -0
- package/dist/docs/assets/{example-agents_knowledge-base.md.BPJiVueF.js → example-agents_knowledge-base.md.CzyZ2DCr.js} +5 -5
- package/dist/docs/assets/{example-agents_knowledge-base.md.BPJiVueF.lean.js → example-agents_knowledge-base.md.CzyZ2DCr.lean.js} +1 -1
- package/dist/docs/assets/example-agents_oncall.md.wFFXXEyW.js +10 -0
- package/dist/docs/assets/{example-agents_security-reviewer.md.Dhj_m7_B.js → example-agents_security-reviewer.md.Dkf1gyo6.js} +8 -8
- package/dist/docs/assets/example-agents_slack-agent.md.DvgvT4nn.js +5 -0
- package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.js +24 -0
- package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.lean.js +1 -0
- package/dist/docs/assets/{guides_agent-to-agent.md.Bpzgq2Pq.js → guides_agent-to-agent.md.Bmbxy-FA.js} +4 -4
- package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.js +9 -0
- package/dist/docs/assets/{guides_github.md.DOOCpqsW.js → guides_github.md.R2QlpR75.js} +5 -5
- package/dist/docs/assets/{guides_human-in-the-loop.md.DlUqsp1S.js → guides_human-in-the-loop.md.BWvT7UqY.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.Dd8EgSem.js → guides_mcp-oauth.md.C7G7IykG.js} +5 -5
- package/dist/docs/assets/guides_mcp-oauth.md.C7G7IykG.lean.js +1 -0
- package/dist/docs/assets/guides_slack.md.zriQpU_9.js +47 -0
- package/dist/docs/assets/guides_slack.md.zriQpU_9.lean.js +1 -0
- package/dist/docs/assets/{guides_webhooks.md.wSOYas3X.js → guides_webhooks.md.DiAwSR42.js} +1 -1
- package/dist/docs/assets/{hillclimbing.md.DHNast08.js → hillclimbing.md.D9Y1_bYh.js} +1 -1
- package/dist/docs/assets/index.md.CZqbBJPB.js +20 -0
- package/dist/docs/assets/index.md.CZqbBJPB.lean.js +1 -0
- package/dist/docs/assets/{quickstart.md.BU6Iwi_9.js → quickstart.md.TnEXYgYW.js} +12 -12
- package/dist/docs/assets/{reference_agent-config.md.DrW2JUM8.js → reference_agent-config.md.kuN6-OxK.js} +1 -1
- package/dist/docs/assets/reference_cli.md.sD-IUWjg.js +73 -0
- package/dist/docs/assets/{reference_cli.md.ccoKOoXt.lean.js → reference_cli.md.sD-IUWjg.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.B9Q3TOve.js → reference_connections.md.DGqAsFXb.js} +3 -3
- package/dist/docs/assets/reference_http-api.md.CfVM_ICa.js +11 -0
- package/dist/docs/assets/{reference_project-layout.md.Bd_CKtNS.js → reference_project-layout.md.D8E6ZmHJ.js} +4 -4
- package/dist/docs/assets/{reference_project-layout.md.Bd_CKtNS.lean.js → reference_project-layout.md.D8E6ZmHJ.lean.js} +1 -1
- package/dist/docs/assets/{reference_schedules.md.w_F2mXB6.js → reference_schedules.md.gmfYzf_I.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.DLd6mvbv.js → reference_sessions.md.C_ouF_uf.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.BRSDnTbN.js → reference_tools.md.BswAQM41.js} +3 -3
- package/dist/docs/assets/{scaffolding-agents.md.C3pTrmoE.js → scaffolding-agents.md.Bsr9Pwzu.js} +1 -1
- package/dist/docs/assets/{scaffolding-agents.md.C3pTrmoE.lean.js → scaffolding-agents.md.Bsr9Pwzu.lean.js} +1 -1
- package/dist/docs/assets/{storage.md.DRTdnFvd.js → storage.md.xZoiGM58.js} +3 -3
- package/dist/docs/assets/storage.md.xZoiGM58.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.B5RVX_tL.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.CmQkmnzC.lean.js → troubleshooting.md.B5RVX_tL.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +12 -12
- package/dist/docs/concepts.html +6 -6
- package/dist/docs/deployment.html +32 -32
- package/dist/docs/evals.html +19 -19
- package/dist/docs/example-agents/approval-buddy.html +9 -9
- package/dist/docs/example-agents/benny.html +11 -11
- package/dist/docs/example-agents/bugbot.html +10 -10
- package/dist/docs/example-agents/codebase-wiki.html +11 -11
- package/dist/docs/example-agents/codeowners-review.html +11 -11
- package/dist/docs/example-agents/concierge.html +12 -12
- package/dist/docs/example-agents/fsd.html +10 -10
- package/dist/docs/example-agents/index.html +7 -7
- package/dist/docs/example-agents/knowledge-base.html +10 -10
- package/dist/docs/example-agents/oncall.html +10 -10
- package/dist/docs/example-agents/security-reviewer.html +13 -13
- package/dist/docs/example-agents/slack-agent.html +10 -10
- package/dist/docs/example-agents/weather-agent.html +16 -16
- package/dist/docs/guides/agent-to-agent.html +9 -9
- package/dist/docs/guides/cloud-runtime.html +7 -7
- package/dist/docs/guides/github.html +10 -10
- package/dist/docs/guides/human-in-the-loop.html +7 -7
- package/dist/docs/guides/mcp-oauth.html +11 -11
- package/dist/docs/guides/slack.html +22 -17
- package/dist/docs/guides/webhooks.html +7 -7
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +7 -7
- package/dist/docs/index.html +9 -9
- package/dist/docs/quickstart.html +17 -17
- package/dist/docs/reference/agent-config.html +7 -7
- package/dist/docs/reference/channels.html +5 -5
- package/dist/docs/reference/cli.html +56 -48
- package/dist/docs/reference/connections.html +9 -9
- package/dist/docs/reference/hooks.html +5 -5
- package/dist/docs/reference/http-api.html +7 -7
- package/dist/docs/reference/instructions.html +5 -5
- package/dist/docs/reference/playground.html +5 -5
- package/dist/docs/reference/project-layout.html +9 -9
- package/dist/docs/reference/prompt.html +5 -5
- package/dist/docs/reference/schedules.html +7 -7
- package/dist/docs/reference/sessions.html +8 -8
- package/dist/docs/reference/skills.html +5 -5
- package/dist/docs/reference/subagents.html +5 -5
- package/dist/docs/reference/tools.html +9 -9
- package/dist/docs/scaffolding-agents.html +6 -6
- package/dist/docs/storage.html +9 -9
- package/dist/docs/troubleshooting.html +6 -6
- package/dist/evals/reporters.d.ts +1 -1
- package/dist/evals/reporters.js +1 -1
- package/dist/evals.d.ts +2 -2
- package/dist/files-backends/agent-store-presigned-url.d.ts +100 -0
- package/dist/files-backends/agent-store-presigned-url.d.ts.map +1 -0
- package/dist/files-backends/agent-store-presigned-url.js +347 -0
- package/dist/files-backends/cursor-hosted.d.ts +87 -0
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -0
- package/dist/files-backends/cursor-hosted.js +540 -0
- package/dist/files-backends/local-fs.d.ts +33 -0
- package/dist/files-backends/local-fs.d.ts.map +1 -0
- package/dist/files-backends/local-fs.js +199 -0
- package/dist/files.d.ts +139 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +89 -0
- package/dist/internal/ab-collector.js +2 -2
- package/dist/internal/ab-fold.js +1 -1
- package/dist/internal/cli-ax.d.ts +2 -2
- package/dist/internal/cli-ax.js +2 -2
- package/dist/internal/cli-deploy.d.ts +1 -1
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +7 -2
- package/dist/internal/cli-docs.d.ts +1 -1
- package/dist/internal/cli-docs.js +1 -1
- package/dist/internal/cli-github.js +13 -13
- package/dist/internal/cli-mcp-oauth.d.ts +1 -1
- package/dist/internal/cli-mcp-oauth.js +2 -2
- package/dist/internal/cli-mcp.d.ts +3 -3
- package/dist/internal/cli-mcp.js +4 -4
- package/dist/internal/cli-skills.js +1 -1
- package/dist/internal/cloud-turn-cost.d.ts +9 -1
- package/dist/internal/cloud-turn-cost.d.ts.map +1 -1
- package/dist/internal/cloud-turn-cost.js +14 -4
- package/dist/internal/cursor/account-mcp.js +5 -5
- package/dist/internal/cursor/backend-client.js +1 -1
- package/dist/internal/cursor/github-credentials.js +3 -3
- package/dist/internal/cursor-account-mcp-auth.d.ts +1 -1
- package/dist/internal/cursor-account-mcp-auth.js +1 -1
- package/dist/internal/cursor-event-relay.js +1 -1
- package/dist/internal/cursor-relay-core.d.ts +1 -1
- package/dist/internal/cursor-relay-core.d.ts.map +1 -1
- package/dist/internal/cursor-slack-relay.js +1 -1
- package/dist/internal/deploy-client.d.ts +6 -1
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +3 -2
- package/dist/internal/deploy-source.d.ts +2 -2
- package/dist/internal/deploy-source.js +2 -2
- package/dist/internal/discovery.js +2 -2
- package/dist/internal/distribution.d.ts +5 -5
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +6 -6
- package/dist/internal/docs-site.js +5 -5
- package/dist/internal/eval-run-store.js +8 -8
- package/dist/internal/evals-client.d.ts +1 -1
- package/dist/internal/evals-client.js +1 -1
- package/dist/internal/github-fanout.js +2 -2
- package/dist/internal/host-files.d.ts +29 -0
- package/dist/internal/host-files.d.ts.map +1 -0
- package/dist/internal/host-files.js +283 -0
- package/dist/internal/host-platforms.js +5 -5
- package/dist/internal/hosting.d.ts +1 -1
- package/dist/internal/hosting.js +1 -1
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +26 -0
- package/dist/internal/install-cursor-skills.d.ts +1 -1
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +33 -4
- package/dist/internal/local-control-plane.js +2 -2
- package/dist/internal/logs-client.d.ts +2 -2
- package/dist/internal/logs-client.js +2 -2
- package/dist/internal/mcp-endpoint.js +1 -1
- package/dist/internal/mcp-oauth.js +2 -2
- package/dist/internal/platform-schedule-sync.js +2 -2
- package/dist/internal/playground/toolchain.js +6 -6
- package/dist/internal/reminder-runner.js +13 -13
- package/dist/internal/resolved-connections.js +6 -6
- package/dist/internal/schedule-runner.js +1 -1
- package/dist/internal/sdk-runner.js +5 -5
- package/dist/internal/server.js +16 -16
- package/dist/internal/session-cost.d.ts +3 -2
- package/dist/internal/session-cost.d.ts.map +1 -1
- package/dist/internal/session-cost.js +7 -6
- package/dist/internal/session-engine.d.ts +31 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +119 -31
- package/dist/internal/slack-provision-client.js +1 -1
- package/dist/internal/storage-coordinator.js +7 -7
- package/dist/internal/trajectory.js +2 -2
- package/dist/internal/turn-cost.d.ts +27 -0
- package/dist/internal/turn-cost.d.ts.map +1 -0
- package/dist/internal/turn-cost.js +83 -0
- package/dist/internal/update-check.d.ts +3 -3
- package/dist/internal/update-check.d.ts.map +1 -1
- package/dist/internal/update-check.js +5 -5
- package/dist/memory.d.ts +1 -1
- package/dist/memory.js +1 -1
- package/dist/playground/assets/index-50PKeJlG.css +1 -0
- package/dist/playground/assets/index-C0f2Wl1q.js +85 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +1 -1
- package/dist/types.d.ts +120 -16
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +23 -23
- package/docs/ab.md +12 -12
- package/docs/building-with-agents.md +9 -9
- package/docs/concepts.md +11 -11
- package/docs/deployment.md +55 -43
- package/docs/evals.md +20 -20
- package/docs/example-agents/approval-buddy.md +9 -9
- package/docs/example-agents/benny.md +13 -13
- package/docs/example-agents/bugbot.md +6 -6
- package/docs/example-agents/codebase-wiki.md +8 -8
- package/docs/example-agents/codeowners-review.md +8 -8
- package/docs/example-agents/concierge.md +10 -10
- package/docs/example-agents/fsd.md +7 -7
- package/docs/example-agents/index.md +8 -8
- package/docs/example-agents/knowledge-base.md +9 -9
- package/docs/example-agents/oncall.md +7 -7
- package/docs/example-agents/security-reviewer.md +12 -12
- package/docs/example-agents/slack-agent.md +10 -10
- package/docs/example-agents/weather-agent.md +30 -26
- package/docs/guides/agent-to-agent.md +4 -4
- package/docs/guides/cloud-runtime.md +3 -3
- package/docs/guides/github.md +6 -6
- package/docs/guides/human-in-the-loop.md +1 -1
- package/docs/guides/mcp-oauth.md +9 -9
- package/docs/guides/slack.md +94 -21
- package/docs/guides/webhooks.md +1 -1
- package/docs/hillclimbing.md +3 -3
- package/docs/quickstart.md +18 -18
- package/docs/reference/agent-config.md +1 -1
- package/docs/reference/cli.md +110 -79
- package/docs/reference/connections.md +3 -3
- package/docs/reference/http-api.md +2 -2
- package/docs/reference/project-layout.md +7 -7
- package/docs/reference/schedules.md +1 -1
- package/docs/reference/sessions.md +7 -7
- package/docs/reference/tools.md +3 -3
- package/docs/scaffolding-agents.md +2 -2
- package/docs/storage.md +5 -5
- package/docs/troubleshooting.md +11 -10
- package/package.json +3 -1
- package/skills/ab/SKILL.md +5 -5
- package/skills/create-agent/SKILL.md +17 -17
- package/skills/debug/SKILL.md +10 -10
- package/skills/evals/SKILL.md +13 -13
- package/skills/framework-map/SKILL.md +3 -3
- package/skills/github/SKILL.md +11 -11
- package/skills/hillclimb/SKILL.md +9 -9
- package/skills/mcp-auth/SKILL.md +11 -11
- package/skills/setup-slack/SKILL.md +28 -28
- package/src/bin/agent-serve.ts +4 -4
- package/src/channels/github/index.ts +1 -1
- package/src/channels/slack/bot-mentions.ts +1 -1
- package/src/channels/slack/eval-directive.ts +1 -1
- package/src/channels/slack/external-policy.ts +1 -1
- package/src/channels/slack/log.ts +1 -1
- package/src/channels/slack/setup.ts +1 -1
- package/src/channels/slack/socket-mode.ts +1 -1
- package/src/evals/reporters.ts +1 -1
- package/src/evals.ts +2 -2
- package/src/files-backends/agent-store-presigned-url.ts +402 -0
- package/src/files-backends/cursor-hosted.ts +698 -0
- package/src/files-backends/local-fs.ts +178 -0
- package/src/files.ts +195 -0
- package/src/internal/ab-collector.ts +2 -2
- package/src/internal/ab-fold.ts +1 -1
- package/src/internal/cli-ax.ts +2 -2
- package/src/internal/cli-deploy.ts +7 -2
- package/src/internal/cli-docs.ts +1 -1
- package/src/internal/cli-github.ts +13 -13
- package/src/internal/cli-mcp-oauth.ts +2 -2
- package/src/internal/cli-mcp.ts +4 -4
- package/src/internal/cli-skills.ts +1 -1
- package/src/internal/cloud-turn-cost.ts +20 -4
- package/src/internal/cursor/account-mcp.ts +5 -5
- package/src/internal/cursor/backend-client.ts +1 -1
- package/src/internal/cursor/github-credentials.ts +3 -3
- package/src/internal/cursor-account-mcp-auth.ts +1 -1
- package/src/internal/cursor-event-relay.ts +1 -1
- package/src/internal/cursor-relay-core.ts +1 -1
- package/src/internal/cursor-slack-relay.ts +1 -1
- package/src/internal/deploy-client.ts +8 -2
- package/src/internal/deploy-source.ts +2 -2
- package/src/internal/discovery.ts +2 -2
- package/src/internal/distribution.ts +6 -6
- package/src/internal/docs-site.ts +5 -5
- package/src/internal/eval-run-store.ts +8 -8
- package/src/internal/evals-client.ts +1 -1
- package/src/internal/github-fanout.ts +2 -2
- package/src/internal/host-files.ts +372 -0
- package/src/internal/host-platforms.ts +5 -5
- package/src/internal/hosting.ts +1 -1
- package/src/internal/http-channel.ts +30 -0
- package/src/internal/install-cursor-skills.ts +31 -3
- package/src/internal/local-control-plane.ts +2 -2
- package/src/internal/logs-client.ts +2 -2
- package/src/internal/mcp-endpoint.ts +1 -1
- package/src/internal/mcp-oauth.ts +2 -2
- package/src/internal/platform-schedule-sync.ts +2 -2
- package/src/internal/playground/toolchain.ts +6 -6
- package/src/internal/reminder-runner.ts +13 -13
- package/src/internal/resolved-connections.ts +6 -6
- package/src/internal/schedule-runner.ts +1 -1
- package/src/internal/sdk-runner.ts +5 -5
- package/src/internal/server.ts +16 -16
- package/src/internal/session-cost.ts +7 -6
- package/src/internal/session-engine.ts +141 -28
- package/src/internal/slack-provision-client.ts +1 -1
- package/src/internal/storage-coordinator.ts +7 -7
- package/src/internal/trajectory.ts +2 -2
- package/src/internal/turn-cost.ts +110 -0
- package/src/internal/update-check.ts +6 -6
- package/src/memory.ts +1 -1
- package/src/storage.ts +1 -1
- package/src/types.ts +148 -16
- package/dist/docs/assets/building-with-agents.md.CJCtZCyi.js +0 -13
- package/dist/docs/assets/chunks/@localSearchIndexroot.DGe61XHA.js +0 -1
- package/dist/docs/assets/concepts.md.Cfb9b-k1.js +0 -4
- package/dist/docs/assets/concepts.md.Cfb9b-k1.lean.js +0 -1
- package/dist/docs/assets/deployment.md.TecHo0_2.js +0 -55
- package/dist/docs/assets/deployment.md.TecHo0_2.lean.js +0 -1
- package/dist/docs/assets/evals.md.DYOjkRCX.lean.js +0 -1
- package/dist/docs/assets/example-agents_benny.md.B0gjhI-p.js +0 -7
- package/dist/docs/assets/example-agents_index.md.D2PEVSXl.js +0 -2
- package/dist/docs/assets/example-agents_index.md.D2PEVSXl.lean.js +0 -1
- package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.js +0 -10
- package/dist/docs/assets/example-agents_slack-agent.md.buLbgvBf.js +0 -5
- package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.js +0 -24
- package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.lean.js +0 -1
- package/dist/docs/assets/guides_cloud-runtime.md.gVzabdQL.js +0 -9
- package/dist/docs/assets/guides_mcp-oauth.md.Dd8EgSem.lean.js +0 -1
- package/dist/docs/assets/guides_slack.md.CjmJSvZS.js +0 -42
- package/dist/docs/assets/guides_slack.md.CjmJSvZS.lean.js +0 -1
- package/dist/docs/assets/index.md.CH_s5uZe.js +0 -20
- package/dist/docs/assets/index.md.CH_s5uZe.lean.js +0 -1
- package/dist/docs/assets/reference_cli.md.ccoKOoXt.js +0 -65
- package/dist/docs/assets/reference_http-api.md.BncLd3PZ.js +0 -11
- package/dist/docs/assets/storage.md.DRTdnFvd.lean.js +0 -1
- package/dist/docs/assets/troubleshooting.md.CmQkmnzC.js +0 -1
- package/dist/internal/model-pricing.d.ts +0 -49
- package/dist/internal/model-pricing.d.ts.map +0 -1
- package/dist/internal/model-pricing.js +0 -377
- package/dist/playground/assets/index-CquRB-l0.js +0 -85
- package/dist/playground/assets/index-Dj0bWpkn.css +0 -1
- package/src/internal/model-pricing.ts +0 -426
- /package/dist/docs/assets/{example-agents_benny.md.B0gjhI-p.lean.js → example-agents_benny.md.2Et1qa8f.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_bugbot.md.DelIdhxB.lean.js → example-agents_bugbot.md.ByUexi5i.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_concierge.md.4rQTSMXt.lean.js → example-agents_concierge.md.lL8rhYlj.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_fsd.md.CzgUrDfi.lean.js → example-agents_fsd.md.DfNKQTHz.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_oncall.md.BG_sUMly.lean.js → example-agents_oncall.md.wFFXXEyW.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_security-reviewer.md.Dhj_m7_B.lean.js → example-agents_security-reviewer.md.Dkf1gyo6.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_slack-agent.md.buLbgvBf.lean.js → example-agents_slack-agent.md.DvgvT4nn.lean.js} +0 -0
- /package/dist/docs/assets/{guides_agent-to-agent.md.Bpzgq2Pq.lean.js → guides_agent-to-agent.md.Bmbxy-FA.lean.js} +0 -0
- /package/dist/docs/assets/{guides_cloud-runtime.md.gVzabdQL.lean.js → guides_cloud-runtime.md.BZ2GA7Es.lean.js} +0 -0
- /package/dist/docs/assets/{guides_github.md.DOOCpqsW.lean.js → guides_github.md.R2QlpR75.lean.js} +0 -0
- /package/dist/docs/assets/{guides_human-in-the-loop.md.DlUqsp1S.lean.js → guides_human-in-the-loop.md.BWvT7UqY.lean.js} +0 -0
- /package/dist/docs/assets/{guides_webhooks.md.wSOYas3X.lean.js → guides_webhooks.md.DiAwSR42.lean.js} +0 -0
- /package/dist/docs/assets/{hillclimbing.md.DHNast08.lean.js → hillclimbing.md.D9Y1_bYh.lean.js} +0 -0
- /package/dist/docs/assets/{quickstart.md.BU6Iwi_9.lean.js → quickstart.md.TnEXYgYW.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.DrW2JUM8.lean.js → reference_agent-config.md.kuN6-OxK.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.B9Q3TOve.lean.js → reference_connections.md.DGqAsFXb.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.BncLd3PZ.lean.js → reference_http-api.md.CfVM_ICa.lean.js} +0 -0
- /package/dist/docs/assets/{reference_schedules.md.w_F2mXB6.lean.js → reference_schedules.md.gmfYzf_I.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.DLd6mvbv.lean.js → reference_sessions.md.C_ouF_uf.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.BRSDnTbN.lean.js → reference_tools.md.BswAQM41.lean.js} +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{_ as t,c as a,o as r,ag as o}from"./chunks/framework.CAZyNGu9.js";const m=JSON.parse('{"title":"Choose the right Agent SDK example","description":"Compare all twelve example agents by runtime, channels, tools, state, and the framework pattern each one teaches.","frontmatter":{"title":"Choose the right Agent SDK example","description":"Compare all twelve example agents by runtime, channels, tools, state, and the framework pattern each one teaches."},"headers":[],"relativePath":"example-agents/index.md","filePath":"example-agents/index.md"}'),s={name:"example-agents/index.md"};function n(i,e,d,l,h,c){return r(),a("div",null,[...e[0]||(e[0]=[o(`<h1 id="choose-the-right-agent-sdk-example" tabindex="-1">Choose the right Agent SDK example <a class="header-anchor" href="#choose-the-right-agent-sdk-example" aria-label="Permalink to "Choose the right Agent SDK example""></a></h1><p>The examples progress from one-channel assistants to durable, event-driven workflows. Start with the smallest agent for your use case. Each guide explains its request flow, framework features, verification path, and reusable design.</p><p>The source projects live under <a href="./../../examples/"><code>examples/</code></a>. Run the commands below from <code>packages/agent-serve</code>. See <a href="./../README.html#run-the-cli">Run the CLI</a> if the <code>agent-sdk</code> command isn't installed.</p><h2 id="compare-the-examples" tabindex="-1">Compare the examples <a class="header-anchor" href="#compare-the-examples" aria-label="Permalink to "Compare the examples""></a></h2><table tabindex="0"><thead><tr><th>Agent</th><th>Runtime</th><th>Intake</th><th>Framework focus</th><th>What sets it apart</th></tr></thead><tbody><tr><td><a href="./weather-agent.html">Weather agent</a></td><td>Local</td><td>HTTP and two Slack transports</td><td>Tools, stdio MCP, approvals, skill, subagent, schedule, hook, A/B, and evals</td><td>It demonstrates the broad local-runtime surface in one domain.</td></tr><tr><td><a href="./slack-agent.html">Slack agent</a></td><td>Local</td><td>Account-linked Slack</td><td>Channel identity, threads, and suggested prompts</td><td>It reaches Slack without authored tools.</td></tr><tr><td><a href="./concierge.html">Concierge</a></td><td>Local</td><td>Built-in HTTP</td><td>Peer MCP and multi-agent serving</td><td>It delegates to a separate agent with its own tools, sessions, and context.</td></tr><tr><td><a href="./benny.html">Playbook router</a></td><td>Local with repo context</td><td>Two Slack transports</td><td>Channel watching, inherited skills, custom cwd, and an eval</td><td>An allowlisted Slack channel becomes an intake queue for repo playbooks.</td></tr><tr><td><a href="./oncall.html">Alert investigator</a></td><td>Local</td><td>Watched Slack alerts channel</td><td>Bot-post channel watching, per-thread debounce, reminder tools, and host Slack calls</td><td>Every alert gets a thread-pinned investigation that schedules its own re-checks.</td></tr><tr><td><a href="./bugbot.html">PR evidence reviewer</a></td><td>Local</td><td>Custom HTTP and Slack</td><td>Host tool, skill, seeded workspaces, and an eval</td><td>The model receives a prepared diff-first evidence tree instead of a checkout.</td></tr><tr><td><a href="./approval-buddy.html">Approval Buddy</a></td><td>Local</td><td>GitHub and Slack</td><td>Policy tools, two subagents, durable storage, and evals</td><td>Code decides whether a PR may be approved. Reviews stay informational.</td></tr><tr><td><a href="./security-reviewer.html">Security Reviewer</a></td><td>Local host pipeline</td><td>GitHub and chat</td><td>Staged tools, parallel SDK agents, progress UI, durable storage, A/B, and evals</td><td>Lives in <code>factory/security-reviewer/</code>. Reviewers and triage overlap while the playground shows every stage.</td></tr><tr><td><a href="./fsd.html">Remote PR coordinator</a></td><td>Local coordinator and remote PR sessions</td><td>HTTP, GitHub, and Slack</td><td>Remote handoff, hooks, affinity, buffering, reminders, and workflow MCP</td><td>One remote conversation follows a PR across chat, webhooks, and timed wakes.</td></tr><tr><td><a href="./knowledge-base.html">Knowledge base</a></td><td>Local</td><td>Built-in HTTP chat</td><td>Durable host-side state, a conventions skill, a schedule, unit tests, and evals</td><td>People curate shared facts in chat, and fresh sessions retrieve them from markdown.</td></tr><tr><td><a href="./codebase-wiki.html">Codebase wiki</a></td><td>Local</td><td>GitHub and chat</td><td>Task-dispatch webhooks, seeded digests, a mapping skill, a schedule, and evals</td><td>Merged PRs accumulate into per-feature wiki pages with a daily digest.</td></tr><tr><td><a href="./codeowners-review.html">Codeowners review</a></td><td>Local</td><td>GitHub, chat, and fixtures</td><td>Ownership routing in code, playbook data files, parallel subagents, and evals</td><td>Each product area reviews with its own playbook, and verdicts aggregate mechanically.</td></tr></tbody></table><h2 id="pick-a-learning-path" tabindex="-1">Pick a learning path <a class="header-anchor" href="#pick-a-learning-path" aria-label="Permalink to "Pick a learning path""></a></h2><p>Use this order when you want to learn the Agent SDK one capability at a time:</p><ol><li>Start with <a href="./weather-agent.html">Weather agent</a> to explore the filesystem conventions and local runtime.</li><li>Strip the project back to <a href="./slack-agent.html">Slack agent</a> to see the minimum channel surface.</li><li>Read <a href="./benny.html">Playbook router</a> when Slack should route requests into repo playbooks.</li><li>Continue to <a href="./oncall.html">Alert investigator</a> when the intake is bot posts and the agent must pace its own engagement and re-checks.</li><li>Add composition with <a href="./concierge.html">Concierge</a>.</li><li>Study <a href="./bugbot.html">PR evidence reviewer</a> before giving a model repository evidence.</li><li>Move policy into code with <a href="./approval-buddy.html">Approval Buddy</a>.</li><li>Compare <a href="./security-reviewer.html">Security Reviewer</a> and <a href="./fsd.html">Remote PR coordinator</a> for host-side versus remote PR work.</li><li>See parallel subagent delegation carry team judgment in <a href="./codeowners-review.html">Codeowners review</a>.</li><li>Curate team context through conversation with <a href="./knowledge-base.html">Knowledge base</a>, then let GitHub events maintain product documentation in <a href="./codebase-wiki.html">Codebase wiki</a>.</li></ol><h2 id="common-prerequisites" tabindex="-1">Common prerequisites <a class="header-anchor" href="#common-prerequisites" aria-label="Permalink to "Common prerequisites""></a></h2><p>All examples require:</p><ul><li>Node 22.13 or newer. Don't run the Agent SDK under Bun.</li><li>Workspace dependencies installed.</li><li>An agent-runtime credential for model turns.</li></ul><p>Several examples need more:</p><ul><li>Account-linked Slack channels require a connected host account.</li><li>Alert investigator needs a dedicated Socket Mode app with channel-post events and membership in the watched alerts channel.</li><li>GitHub examples require access to the target repository. Codebase wiki and Codeowners review call the host <code>gh</code> CLI for PR data; the codeowners fixtures run without network.</li><li>Example agents use <code>cursorHostedStorage</code> (<code>agent/storage.ts</code>) for Cursor-hosted session storage (control-plane proxy).</li><li>Remote PR coordinator starts remote agent sessions and needs access to its workflow backend.</li></ul><p>Each guide lists its own credentials, services, and side effects.</p><h2 id="validate-any-example" tabindex="-1">Validate any example <a class="header-anchor" href="#validate-any-example" aria-label="Permalink to "Validate any example""></a></h2><p>Discovery commands don't start a model turn:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span></code></pre></div><p>Start one development server with <code>agent-sdk dev examples/<name></code>. Concierge depends on Weather agent, so its guide creates an isolated two-project mount. Don't mount the whole examples directory to test one agent; several advanced examples subscribe to live GitHub events.</p><h2 id="read-by-framework-feature" tabindex="-1">Read by framework feature <a class="header-anchor" href="#read-by-framework-feature" aria-label="Permalink to "Read by framework feature""></a></h2><ul><li><a href="./../concepts.html">Concepts</a> explains filesystem discovery and runtime boundaries.</li><li><a href="./../reference/project-layout.html">Project layout</a> lists every authored folder.</li><li><a href="./../reference/tools.html">Tools</a>, <a href="./../reference/channels.html">channels</a>, and <a href="./../reference/connections.html">MCP connections</a> cover the core extension points.</li><li><a href="./../evals.html">Evals</a> and <a href="./../ab.html">live A/B metrics</a> cover measured iteration.</li><li><a href="./../deployment.html">Deployment</a> covers credentials, auth, storage, and hosting.</li></ul>`,20)])])}const u=t(s,[["render",n]]);export{m as __pageData,u as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as t,c as a,o as r,ag as o}from"./chunks/framework.CAZyNGu9.js";const m=JSON.parse('{"title":"Choose the right Agent SDK example","description":"Compare all twelve example agents by runtime, channels, tools, state, and the framework pattern each one teaches.","frontmatter":{"title":"Choose the right Agent SDK example","description":"Compare all twelve example agents by runtime, channels, tools, state, and the framework pattern each one teaches."},"headers":[],"relativePath":"example-agents/index.md","filePath":"example-agents/index.md"}'),s={name:"example-agents/index.md"};function n(i,e,d,l,h,c){return r(),a("div",null,[...e[0]||(e[0]=[o("",20)])])}const u=t(s,[["render",n]]);export{m as __pageData,u as default};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import{_ as a,c as s,o as t,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Build a team knowledge base through conversation","description":"Teach an agent about people, systems, decisions, and preferences; store that knowledge as markdown and retrieve it in fresh sessions.","frontmatter":{"title":"Build a team knowledge base through conversation","description":"Teach an agent about people, systems, decisions, and preferences; store that knowledge as markdown and retrieve it in fresh sessions."},"headers":[],"relativePath":"example-agents/knowledge-base.md","filePath":"example-agents/knowledge-base.md"}'),n={name:"example-agents/knowledge-base.md"};function l(o,e,r,
|
|
2
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
1
|
+
import{_ as a,c as s,o as t,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Build a team knowledge base through conversation","description":"Teach an agent about people, systems, decisions, and preferences; store that knowledge as markdown and retrieve it in fresh sessions.","frontmatter":{"title":"Build a team knowledge base through conversation","description":"Teach an agent about people, systems, decisions, and preferences; store that knowledge as markdown and retrieve it in fresh sessions."},"headers":[],"relativePath":"example-agents/knowledge-base.md","filePath":"example-agents/knowledge-base.md"}'),n={name:"example-agents/knowledge-base.md"};function l(o,e,d,r,h,p){return t(),s("div",null,[...e[0]||(e[0]=[i(`<h1 id="build-a-team-knowledge-base-through-conversation" tabindex="-1">Build a team knowledge base through conversation <a class="header-anchor" href="#build-a-team-knowledge-base-through-conversation" aria-label="Permalink to "Build a team knowledge base through conversation""></a></h1><p>Knowledge base turns conversations into shared team context. Teach the agent about people, systems, decisions, and standing preferences. Three server tools read, search, and write human-readable markdown pages; a conventions skill shapes each write; and a daily schedule merges duplicates and rebuilds the index. A fresh session retrieves what an earlier conversation captured.</p><p>Use this project when people should curate organizational knowledge through chat. Use <a href="./codebase-wiki.html">Codebase wiki</a> when merged PRs should maintain feature documentation instead.</p><p><a href="./../../examples/knowledge-base/">Browse the knowledge base source.</a></p><h2 id="keep-shared-knowledge-on-the-filesystem" tabindex="-1">Keep shared knowledge on the filesystem <a class="header-anchor" href="#keep-shared-knowledge-on-the-filesystem" aria-label="Permalink to "Keep shared knowledge on the filesystem""></a></h2><p>The knowledge base lives outside any session workspace, in <code>.agent-serve/wiki/</code> by default. <code>KNOWLEDGE_BASE_DIR</code> overrides the location, and the tools resolve it on every call, so tests and evals can point the same code at a temp directory.</p><p>The store enforces its own safety:</p><ul><li>Page ids are one to three lowercase kebab-case segments, so a page id can't escape the wiki directory.</li><li>Pages cap at 64 KiB. Oversized writes fail with instructions to split the page.</li><li><code>wiki_write</code> replaces whole pages. The instructions require reading a page before updating it, so rewrites carry existing facts forward.</li></ul><p>Every page is plain markdown. You can open the wiki in an editor, review it in a PR, or grep it.</p><h2 id="follow-a-fact-through-the-agent" tabindex="-1">Follow a fact through the agent <a class="header-anchor" href="#follow-a-fact-through-the-agent" aria-label="Permalink to "Follow a fact through the agent""></a></h2><ol><li>You tell the agent something durable: a system, an owner, a standing preference.</li><li>The instructions require a <code>wiki_search</code> before claiming knowledge and a <code>wiki_write</code> after learning something worth keeping.</li><li>The <code>wiki-conventions</code> skill picks the page id (<code>staging-database</code>, <code>people/jane-doe</code>), the page shape, and the dated fact format.</li><li>The tool writes the page under the durable wiki root and returns whether it created or updated the page.</li><li>A later session, on any channel, finds the fact with <code>wiki_search</code> and cites the knowledge-base page in its answer.</li></ol><p>Ephemeral chatter stays out. The instructions tell the model to skip one-off questions and to ask before saving anything borderline.</p><h2 id="map-the-knowledge-base-files" tabindex="-1">Map the knowledge-base files <a class="header-anchor" href="#map-the-knowledge-base-files" aria-label="Permalink to "Map the knowledge-base files""></a></h2><table tabindex="0"><thead><tr><th>File</th><th>Purpose</th></tr></thead><tbody><tr><td><a href="../../examples/knowledge-base/agent/agent.ts"><code>agent/agent.ts</code></a></td><td>Selects the cloud runtime and model.</td></tr><tr><td><a href="./../../examples/knowledge-base/agent/instructions.html"><code>agent/instructions.md</code></a></td><td>Sets the read-before-answer and save-after-learning policy.</td></tr><tr><td><a href="../../examples/knowledge-base/agent/lib/wiki-store.ts"><code>agent/lib/wiki-store.ts</code></a></td><td>Validates page ids, lists, reads, writes, and searches the knowledge base.</td></tr><tr><td><a href="../../examples/knowledge-base/agent/tools/wiki_read.ts"><code>agent/tools/wiki_read.ts</code></a></td><td>Reads one page or lists every page with titles and timestamps.</td></tr><tr><td><a href="../../examples/knowledge-base/agent/tools/wiki_search.ts"><code>agent/tools/wiki_search.ts</code></a></td><td>Searches titles and bodies with per-page match lines.</td></tr><tr><td><a href="../../examples/knowledge-base/agent/tools/wiki_write.ts"><code>agent/tools/wiki_write.ts</code></a></td><td>Creates or replaces a page and reports created versus updated.</td></tr><tr><td><a href="./../../examples/knowledge-base/agent/skills/wiki-conventions.html"><code>agent/skills/wiki-conventions.md</code></a></td><td>Names pages, shapes them, and dates every fact.</td></tr><tr><td><a href="./../../examples/knowledge-base/agent/schedules/gardener.html"><code>agent/schedules/gardener.md</code></a></td><td>Merges duplicates, rebuilds the index, and flags stale facts daily.</td></tr><tr><td><a href="../../examples/knowledge-base/agent/lib/wiki-store.test.ts"><code>agent/lib/wiki-store.test.ts</code></a></td><td>Unit-tests slug safety and store round-trips.</td></tr><tr><td><a href="../../examples/knowledge-base/evals/knowledge.eval.ts"><code>evals/knowledge.eval.ts</code></a></td><td>Seeds a temp knowledge base and gates recall, save, and no-write decisions.</td></tr></tbody></table><p>There is no authored channel, MCP connection, subagent, hook, A/B experiment, or custom storage. The wiki directory is the durable state.</p><h2 id="prepare-the-example" tabindex="-1">Prepare the example <a class="header-anchor" href="#prepare-the-example" aria-label="Permalink to "Prepare the example""></a></h2><p>You need:</p><ul><li>Node 22.13 or newer.</li><li>An agent-runtime credential for model turns.</li></ul><p>Nothing else. The wiki is created on first write.</p><h2 id="validate-the-surface" tabindex="-1">Validate the surface <a class="header-anchor" href="#validate-the-surface" aria-label="Permalink to "Validate the surface""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/knowledge-base</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/knowledge-base</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span></code></pre></div><p>The manifest should report three server tools, one skill, and one schedule.</p><h2 id="exercise-the-store-without-a-model-turn" tabindex="-1">Exercise the store without a model turn <a class="header-anchor" href="#exercise-the-store-without-a-model-turn" aria-label="Permalink to "Exercise the store without a model turn""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> wiki_write</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/knowledge-base</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
4
4
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"page":"staging-database","content":"# Staging database\\n\\n- Port: 6432 (recorded 2026-07-19)\\n"}'</span></span>
|
|
5
5
|
<span class="line"></span>
|
|
6
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
6
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> wiki_search</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
7
7
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/knowledge-base</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
8
8
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"query":"6432"}'</span></span>
|
|
9
9
|
<span class="line"></span>
|
|
10
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
11
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
10
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> wiki_read</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/knowledge-base</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{}'</span></span></code></pre></div><p>Invalid page ids fail fast. Try <code>{"page":"../escape"}</code> and the tool returns the validation error instead of touching the filesystem.</p><h2 id="prove-recall-across-sessions" tabindex="-1">Prove recall across sessions <a class="header-anchor" href="#prove-recall-across-sessions" aria-label="Permalink to "Prove recall across sessions""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/knowledge-base</span></span></code></pre></div><p>Teach it something in the playground:</p><blockquote><p>Remember: our staging database is Postgres at staging-db.internal.example.com, port 6432 via PgBouncer. Jane Doe owns it.</p></blockquote><p>The trace shows the conventions skill load, then <code>wiki_write</code> calls for <code>staging-database</code>, <code>people/jane-doe</code>, and <code>index</code>. Start a new session and ask:</p><blockquote><p>What port does our staging database use, and who owns it?</p></blockquote><p>The fresh session finds the answer with <code>wiki_search</code> and <code>wiki_read</code> and cites the pages. The conversation history is empty; the wiki is the source of truth.</p><h2 id="run-the-gardener" tabindex="-1">Run the gardener <a class="header-anchor" href="#run-the-gardener" aria-label="Permalink to "Run the gardener""></a></h2><p>The <code>gardener</code> schedule fires at 06:00 UTC and rewrites the wiki for consistency: merge near-duplicate pages, rebuild <code>index</code>, and flag facts older than 90 days. Under <code>agent-sdk dev</code>, timers don't auto-fire. Trigger it by hand:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -s</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/knowledge-base/v1/dev/schedules/gardener</span></span></code></pre></div><h2 id="run-the-evals" tabindex="-1">Run the evals <a class="header-anchor" href="#run-the-evals" aria-label="Permalink to "Run the evals""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/knowledge-base</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --list</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/knowledge-base</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> knowledge/recall</span></span></code></pre></div><p>The eval file seeds a temp directory through <code>KNOWLEDGE_BASE_DIR</code> inside the cases, so the durable knowledge base never sees test data. <code>knowledge/recall</code> proves the fact comes from disk, not the conversation. <code>knowledge/save</code> gates the write decision, and <code>knowledge/no-write-on-ephemera</code> proves small talk stays out of the knowledge base.</p><h2 id="reuse-the-knowledge-base-pattern" tabindex="-1">Reuse the knowledge-base pattern <a class="header-anchor" href="#reuse-the-knowledge-base-pattern" aria-label="Permalink to "Reuse the knowledge-base pattern""></a></h2><p>Copy this shape when an agent needs durable, inspectable team knowledge:</p><ul><li>Resolve the storage root lazily behind an environment override.</li><li>Validate identifiers in the store, not in the prompt.</li><li>Put naming and structure conventions in a skill so writes stay consistent.</li><li>Add a consolidation schedule instead of letting pages rot.</li></ul><h2 id="where-to-go-next" tabindex="-1">Where to go next <a class="header-anchor" href="#where-to-go-next" aria-label="Permalink to "Where to go next""></a></h2><ul><li><a href="./../reference/tools.html">Tools</a></li><li><a href="./../reference/skills.html">Skills</a></li><li><a href="./../reference/schedules.html">Schedules</a></li><li><a href="./../evals.html">Evals</a></li></ul>`,43)])])}const g=a(n,[["render",l]]);export{k as __pageData,g as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as a,c as s,o as t,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Build a team knowledge base through conversation","description":"Teach an agent about people, systems, decisions, and preferences; store that knowledge as markdown and retrieve it in fresh sessions.","frontmatter":{"title":"Build a team knowledge base through conversation","description":"Teach an agent about people, systems, decisions, and preferences; store that knowledge as markdown and retrieve it in fresh sessions."},"headers":[],"relativePath":"example-agents/knowledge-base.md","filePath":"example-agents/knowledge-base.md"}'),n={name:"example-agents/knowledge-base.md"};function l(o,e,r,
|
|
1
|
+
import{_ as a,c as s,o as t,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Build a team knowledge base through conversation","description":"Teach an agent about people, systems, decisions, and preferences; store that knowledge as markdown and retrieve it in fresh sessions.","frontmatter":{"title":"Build a team knowledge base through conversation","description":"Teach an agent about people, systems, decisions, and preferences; store that knowledge as markdown and retrieve it in fresh sessions."},"headers":[],"relativePath":"example-agents/knowledge-base.md","filePath":"example-agents/knowledge-base.md"}'),n={name:"example-agents/knowledge-base.md"};function l(o,e,d,r,h,p){return t(),s("div",null,[...e[0]||(e[0]=[i("",43)])])}const g=a(n,[["render",l]]);export{k as __pageData,g as default};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{_ as t,c as a,o as s,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Investigate every alert in its own Slack thread","description":"Watch a bot-fed alerts channel, react when the agent locks in, coalesce thread chatter behind a quiet window, and let the agent schedule its own re-checks.","frontmatter":{"title":"Investigate every alert in its own Slack thread","description":"Watch a bot-fed alerts channel, react when the agent locks in, coalesce thread chatter behind a quiet window, and let the agent schedule its own re-checks."},"headers":[],"relativePath":"example-agents/oncall.md","filePath":"example-agents/oncall.md"}'),n={name:"example-agents/oncall.md"};function l(o,e,h,r,d,c){return s(),a("div",null,[...e[0]||(e[0]=[i(`<h1 id="investigate-every-alert-in-its-own-slack-thread" tabindex="-1">Investigate every alert in its own Slack thread <a class="header-anchor" href="#investigate-every-alert-in-its-own-slack-thread" aria-label="Permalink to "Investigate every alert in its own Slack thread""></a></h1><p>This agent is an on-call teammate. Alert feeds post into an alerts channel as bots. Each new alert dispatches an investigation session pinned to that post's thread: the agent reacts 👀 the moment it locks in, investigates immediately, and posts brief findings backed by evidence it observed. Replies in the thread reach it only after the thread has been quiet for about a minute, and reminder tools let it wake itself later to re-check a baseline or confirm an alert cleared.</p><p>Use this example when alerts land in Slack and you want one thread-scoped investigation per alert, with an agent that paces its own engagement instead of answering every message.</p><p><a href="./../../examples/oncall/">Browse the current alert-investigator source.</a></p><h2 id="follow-an-alert" tabindex="-1">Follow an alert <a class="header-anchor" href="#follow-an-alert" aria-label="Permalink to "Follow an alert""></a></h2><ol><li>An alert feed (Alertmanager, PagerDuty, Datadog) posts a new top-level message in the watched alerts channel.</li><li>The channel watch accepts it. <code>includeBotPosts</code> lets bot authors through; the agent's own posts always stay dropped.</li><li>The handler reacts 👀 on the alert post and sets "Investigating…" typing. The reaction is the lock-in signal: this alert has an owner.</li><li>The Agent SDK creates a session keyed to the alert's thread and dispatches immediately. New alerts get no debounce.</li><li>The agent reads the alert, gathers evidence, and posts findings to the thread once it has a hypothesis.</li><li>People discuss in the thread. Replies buffer per thread and dispatch as one coalesced follow-up after roughly a minute of quiet.</li><li>The agent arms reminders for anything that needs time and posts interim updates when new evidence changes the picture.</li></ol><p>Mentions and DMs skip the watch entirely and behave like ordinary chat.</p><h2 id="map-the-files" tabindex="-1">Map the files <a class="header-anchor" href="#map-the-files" aria-label="Permalink to "Map the files""></a></h2><table tabindex="0"><thead><tr><th>File</th><th>Purpose</th></tr></thead><tbody><tr><td><a href="../../examples/oncall/agent/agent.ts"><code>agent/agent.ts</code></a></td><td>Names the agent and keeps harness workspaces outside any monorepo checkout.</td></tr><tr><td><a href="./../../examples/oncall/agent/instructions.html"><code>agent/instructions.md</code></a></td><td>Engagement rules, the investigation loop, and the message discipline.</td></tr><tr><td><a href="../../examples/oncall/agent/channels/slack-app.ts"><code>agent/channels/slack-app.ts</code></a></td><td>Dedicated Socket Mode app: watch configuration and handler wiring.</td></tr><tr><td><a href="../../examples/oncall/agent/lib/alert-watch.ts"><code>agent/lib/alert-watch.ts</code></a></td><td>The engagement policy: lock in on new alerts, coalesce replies.</td></tr><tr><td><a href="../../examples/oncall/agent/lib/thread-debounce.ts"><code>agent/lib/thread-debounce.ts</code></a></td><td>Per-thread quiet window.</td></tr><tr><td><a href="../../examples/oncall/agent/lib/alerts.ts"><code>agent/lib/alerts.ts</code></a></td><td>Dispatch classification, prompt building, and thread addressing.</td></tr><tr><td><a href="../../examples/oncall/agent/lib/slack-api.ts"><code>agent/lib/slack-api.ts</code></a></td><td>Reactions and thread posts on this agent's own token pair.</td></tr><tr><td><a href="../../examples/oncall/agent/tools/reminders_create.ts"><code>agent/tools/reminders_create.ts</code></a></td><td>Self-scheduled wakes bound to the thread (plus <code>reminders_list</code> and <code>reminders_cancel</code>).</td></tr><tr><td><a href="../../examples/oncall/agent/tools/post_thread_update.ts"><code>agent/tools/post_thread_update.ts</code></a></td><td>Interim updates to the thread mid-turn.</td></tr><tr><td><a href="../../examples/oncall/evals/smoke.eval.ts"><code>evals/smoke.eval.ts</code></a></td><td>Checks identity and the reminder-tool route.</td></tr></tbody></table><h2 id="let-bot-posts-through-the-watch" tabindex="-1">Let bot posts through the watch <a class="header-anchor" href="#let-bot-posts-through-the-watch" aria-label="Permalink to "Let bot posts through the watch""></a></h2><p>Channel watching drops bot-authored posts by default so two agents can never feed each other. Alert channels invert the assumption: the posts worth watching come from bots. <code>channelPosts.includeBotPosts</code> opts in per channel:</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:#6F42C1;--shiki-dark:#B392F0;">engagement</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> channelPosts</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> allow</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"#alerts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> posts</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"all"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> includeBotPosts</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
6
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
7
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">},</span></span></code></pre></div><p>Loop safety survives the opt-in. The pack matches the watching app's own posts by the <code>bot_id</code> and bot user id from <code>auth.test</code> and drops them, so the agent's findings never re-dispatch it. Posts that mention the bot stay on the mention path.</p><p><code>posts: "all"</code> also delivers thread replies. The handler, not the pack, decides their pace.</p><h2 id="pace-the-engagement" tabindex="-1">Pace the engagement <a class="header-anchor" href="#pace-the-engagement" aria-label="Permalink to "Pace the engagement""></a></h2><p>The example runs two rhythms:</p><ul><li>A new alert dispatches immediately.</li><li>Thread replies produce one engagement per lull.</li></ul><p>The pack's <code>debounceMs</code> is per message; it exists to let edits settle. This agent needs a per-thread window instead, so the handler owns it (<a href="../../examples/oncall/agent/lib/thread-debounce.ts"><code>lib/thread-debounce.ts</code></a>). Every reply restarts a 60-second timer keyed by thread. Superseded waiters resolve <code>null</code> and the handler returns <code>null</code> for them. When the thread goes quiet, the newest waiter receives the whole batch and dispatches one follow-up that lists every message with mentionable attribution.</p><p>Two details make the window matter. A follow-up that arrives while a turn runs preempts that turn (latest message wins), so engaging per message would keep cancelling the investigation. And @mentions bypass the window through Slack's mention path, so a person who needs the agent now still gets it now.</p><h2 id="schedule-your-own-re-checks" tabindex="-1">Schedule your own re-checks <a class="header-anchor" href="#schedule-your-own-re-checks" aria-label="Permalink to "Schedule your own re-checks""></a></h2><p>Investigations rarely finish in one pass. A baseline comparison needs 20 minutes of data. An alert that cleared may re-fire. The example hands the model three tools over <code>host.reminders</code>:</p><ul><li><code>reminders_create</code> arms a one-shot (<code>delay: "20m"</code>) or recurring (<code>every: "30m"</code> with a plain-language stop condition) wake bound to the thread's conversation.</li><li><code>reminders_list</code> shows the thread's standing watches.</li><li><code>reminders_cancel</code> disarms one, and refuses ids that belong to another thread's conversation.</li></ul><p>When a reminder fires, its prompt returns to the same session as a follow-up turn, and the reply lands in the alert thread. The instructions keep wake prompts generic (re-read live state instead of replaying stale numbers) and wake replies to one line, for example "re-checked p99 on api-gateway: 120ms, back at baseline, cancelling the watch."</p><p>Keep these tool filenames if you copy the design: the framework's reminder fire prompt tells the model to call <code>reminders_cancel</code> by name when a stop condition is set.</p><h2 id="alert-people-mid-investigation" tabindex="-1">Alert people mid-investigation <a class="header-anchor" href="#alert-people-mid-investigation" aria-label="Permalink to "Alert people mid-investigation""></a></h2><p>The final reply of each turn posts to the thread on its own. <code>post_thread_update</code> covers evidence that shouldn't wait for the turn to finish: it posts a one-or-two-sentence update through the agent's token, with <code><@USERID></code> mentions for the people who need to act. The instructions restrict it to changes in hypothesis, severity, or blast radius. Progress narration doesn't qualify.</p><h2 id="connect-the-slack-app" tabindex="-1">Connect the Slack app <a class="header-anchor" href="#connect-the-slack-app" aria-label="Permalink to "Connect the Slack app""></a></h2><p>Channel watching is Socket Mode only, so this example uses a dedicated app:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> init</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/oncall</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --name</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Oncall"</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --channel-posts</span></span>
|
|
8
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> doctor</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prefix</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ONCALL</span></span></code></pre></div><p>The generated manifest subscribes to <code>message.channels</code> and <code>message.groups</code> and includes <code>reactions:write</code> for the lock-in reaction. Install the app, export <code>ONCALL_SLACK_BOT_TOKEN</code> and <code>ONCALL_SLACK_APP_TOKEN</code>, and invite the bot to each watched channel.</p><p><code>ONCALL_ALERTS_CHANNELS</code> sets the watch list as comma-separated ids or <code>#names</code>. It defaults to <code>#alerts</code>.</p><p>Wire observability MCP servers under <code>agent/mcp-connections/</code> so evidence gathering reaches your logs, metrics, and dashboards. The example ships none; without them the agent works from the alert text, its links, and the thread.</p><h2 id="validate-and-start-the-server" tabindex="-1">Validate and start the server <a class="header-anchor" href="#validate-and-start-the-server" aria-label="Permalink to "Validate and start the server""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/oncall</span></span>
|
|
9
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/oncall</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/oncall</span></span></code></pre></div><p>The info output lists four server tools and the watched channel on the <code>slack-app</code> channel. Missing tokens leave that channel idle without stopping the server.</p><p>In dev mode, reminder timers don't auto-fire. List and fire them by hand through the dev routes described in <a href="./../reference/schedules.html#dispatch-and-dev-mode">Schedules and reminders</a>.</p><h2 id="test-the-policy-without-slack" tabindex="-1">Test the policy without Slack <a class="header-anchor" href="#test-the-policy-without-slack" aria-label="Permalink to "Test the policy without Slack""></a></h2><p>The engagement policy is plain code with unit tests:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pnpm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> exec</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> vitest</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/oncall</span></span></code></pre></div><p>The integration test drives a synthetic Events API delivery through the real parse, watch, and dispatch plumbing. It asserts a bot alert dispatches pinned to its thread after the lock-in reaction, the agent's own posts never loop, and replies coalesce behind the quiet window.</p><p>The smoke eval spends a model turn:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/oncall</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> smoke</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span></code></pre></div><p>It checks identity and the reminder-tool route lexically. It doesn't prove Slack delivery or reaction behavior; the unit tests cover the dispatch side, and a live check needs the dedicated app connected.</p><h2 id="build-an-alert-investigator" tabindex="-1">Build an alert investigator <a class="header-anchor" href="#build-an-alert-investigator" aria-label="Permalink to "Build an alert investigator""></a></h2><p>Use this structure when a bot feed should drive thread-scoped work:</p><ol><li>Watch the feed channel with <code>includeBotPosts: true</code> and a narrow allowlist.</li><li>Acknowledge on the triggering post before dispatching, so people see ownership without opening the thread.</li><li>Dispatch new items immediately; coalesce thread chatter behind a per-thread quiet window.</li><li>Give the agent reminder tools for anything that needs time, and make cancel discipline part of the instructions.</li><li>Keep every posted message brief and tied to evidence the agent saw.</li></ol><h2 id="where-to-go-next" tabindex="-1">Where to go next <a class="header-anchor" href="#where-to-go-next" aria-label="Permalink to "Where to go next""></a></h2><ul><li><a href="./../guides/slack.html">Slack</a></li><li><a href="./../reference/schedules.html">Schedules and reminders</a></li><li><a href="./../reference/tools.html">Tools</a></li><li><a href="./benny.html">Playbook router</a> for the human-post variant of channel watching</li></ul>`,48)])])}const g=t(n,[["render",l]]);export{k as __pageData,g as default};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import{_ as t,c as s,o as a,ag as i}from"./chunks/framework.CAZyNGu9.js";const u=JSON.parse('{"title":"Run staged security reviews from GitHub events","description":"Orchestrate parallel reviewer agents, streamed triage, deterministic stages, live playground progress, durable sessions, and severity A/B metrics.","frontmatter":{"title":"Run staged security reviews from GitHub events","description":"Orchestrate parallel reviewer agents, streamed triage, deterministic stages, live playground progress, durable sessions, and severity A/B metrics."},"headers":[],"relativePath":"example-agents/security-reviewer.md","filePath":"example-agents/security-reviewer.md"}'),r={name:"example-agents/security-reviewer.md"};function n(o,e,l,d,h,p){return a(),s("div",null,[...e[0]||(e[0]=[i(`<h1 id="run-staged-security-reviews-from-github-events" tabindex="-1">Run staged security reviews from GitHub events <a class="header-anchor" href="#run-staged-security-reviews-from-github-events" aria-label="Permalink to "Run staged security reviews from GitHub events""></a></h1><p>Security Reviewer turns a pull request into a staged host-side review. One tool prepares the diff and selects modules. A second fans out specialized reviewers and triages candidates as they arrive. A third deduplicates the confirmed findings, writes artifacts, and may publish a GitHub review.</p><p>Use this example when the workflow needs several model workers, but the host must own orchestration, progress, artifacts, and the final write.</p><p>Source lives under <a href="./../../../../factory/security-reviewer/"><code>factory/security-reviewer/</code></a> (factory agent, not under <code>examples/</code>).</p><p><a href="./../../../../factory/security-reviewer/">Browse the Security Reviewer source.</a></p><h2 id="run-a-three-stage-host-pipeline" tabindex="-1">Run a three-stage host pipeline <a class="header-anchor" href="#run-a-three-stage-host-pipeline" aria-label="Permalink to "Run a three-stage host pipeline""></a></h2><p>Security Reviewer is a pipeline, not one long agent turn:</p><table tabindex="0"><thead><tr><th>Stage</th><th>Tool</th><th>Result</th></tr></thead><tbody><tr><td>Prepare</td><td><code>prepare_review</code></td><td>Fetch metadata and diff, create a <code>runId</code>, and select security modules.</td></tr><tr><td>Review and triage</td><td><code>run_reviewers</code></td><td>Run module reviewers in parallel and start triage as each candidate arrives.</td></tr><tr><td>Finalize</td><td><code>finalize_review</code></td><td>Apply thresholds, deduplicate findings, write artifacts, and optionally post a review.</td></tr></tbody></table><p><code>run_triage</code> remains available as a compatibility stage. In the normal flow, triage has already completed inside <code>run_reviewers</code>, so it reports existing results. If candidates exist without triage output, it starts triage workers and writes their state.</p><p>The configured root agent chooses and sequences tools in chat. The review workers use a model selected by the host pipeline. They are created programmatically with the agent SDK, not discovered from <code>agent/subagents/</code>.</p><h2 id="follow-a-github-wake" tabindex="-1">Follow a GitHub wake <a class="header-anchor" href="#follow-a-github-wake" aria-label="Permalink to "Follow a GitHub wake""></a></h2><ol><li>A non-draft <code>pull_request.opened</code> or <code>pull_request.synchronize</code> event arrives for an allowlisted repository.</li><li>The GitHub channel returns a host <code>{ task }</code>, so the webhook gets a 202 response before the long review starts.</li><li>Host code tries to post a pending commit status and creates a playground session.</li><li>The root model sends one acknowledgement. It doesn't run review tools on this path.</li><li>The task calls <code>prepare_review</code>, <code>run_reviewers</code>, and <code>finalize_review</code> deterministically inside that session.</li><li>Reviewer candidates stream into duplicate gating and triage.</li><li>Finalization writes artifacts and tries to post the GitHub review.</li><li>The host tries to set a success commit status when no findings remain, a failure status when findings remain, or an error status when the pipeline throws.</li><li>The final response is appended to the session as an assistant message.</li></ol><p>The session records each stage as a normal tool event, even though host code selected the tools.</p><p>Review and status posting are best-effort. The channel chooses its final status from the finding count even when the review posting result says <code>posted: false</code>.</p><h2 id="map-the-framework-features" tabindex="-1">Map the framework features <a class="header-anchor" href="#map-the-framework-features" aria-label="Permalink to "Map the framework features""></a></h2><table tabindex="0"><thead><tr><th>Capability</th><th>Source</th><th>Role</th></tr></thead><tbody><tr><td>Root agent</td><td><a href="../../../../factory/security-reviewer/agent/agent.ts"><code>agent/agent.ts</code></a>, <a href="./../../../../factory/security-reviewer/agent/instructions.html"><code>agent/instructions.md</code></a></td><td>Configure local chat and explain the three-stage contract.</td></tr><tr><td>Server tools</td><td><a href="./../../../../factory/security-reviewer/agent/tools/"><code>agent/tools/</code></a></td><td>Expose each review stage to chat and host orchestration.</td></tr><tr><td>GitHub channel</td><td><a href="../../../../factory/security-reviewer/agent/channels/github.ts"><code>agent/channels/github.ts</code></a></td><td>Filter wakes, run background tasks, and publish status.</td></tr><tr><td>Progress channel</td><td><a href="../../../../factory/security-reviewer/agent/channels/asr-progress.ts"><code>agent/channels/asr-progress.ts</code></a></td><td>Serve live reviewer and triage state by <code>runId</code>.</td></tr><tr><td>Playground renderer</td><td><a href="./../../../../factory/security-reviewer/agent/playground/tools/run_reviewers.tsx.html"><code>agent/playground/tools/run_reviewers.tsx</code></a></td><td>Replace the generic tool chip with live module rows.</td></tr><tr><td>SDK review pipeline</td><td><a href="../../../../factory/security-reviewer/agent/lib/review-stages.ts"><code>review-stages.ts</code></a>, <a href="../../../../packages/security-review-lib/src/index.ts"><code>@anysphere/security-review-lib</code></a></td><td>Select modules, call model workers, triage, deduplicate, and write artifacts.</td></tr><tr><td>Storage</td><td><a href="../../../../factory/security-reviewer/agent/storage.ts"><code>agent/storage.ts</code></a></td><td>Persist framework sessions with <code>cursorHostedStorage</code> (lazy restore).</td></tr><tr><td>A/B</td><td><a href="../../../../factory/security-reviewer/agent/ab.ts"><code>agent/ab.ts</code></a></td><td>Compare all-severity versus high-only GitHub comments.</td></tr><tr><td>Eval</td><td><a href="./../../../../factory/security-reviewer/evals/"><code>evals/</code></a></td><td>Check stage-tool presence against a pinned sample.</td></tr></tbody></table><p>There is no Slack channel, authored skill, discovered subagent, MCP connection, schedule, reminder, hook, tool approval, or cloud runtime.</p><h2 id="prepare-the-host" tabindex="-1">Prepare the host <a class="header-anchor" href="#prepare-the-host" aria-label="Permalink to "Prepare the host""></a></h2><p>You need:</p><ul><li>Node 22.13 or newer.</li><li>An agent-runtime credential for the root turn and review workers.</li><li>GitHub read access for preparation.</li><li>GitHub write access for webhook-driven reviews and commit statuses.</li></ul><p>The pipeline exposes settings for:</p><ul><li>the worker model,</li><li>reviewer and triage parallelism,</li><li>reviewer, triage, duplicate-gate, and final-dedupe timeouts, and</li><li>prior-comment loading.</li></ul><p>The active names live beside the orchestration in <a href="../../../../factory/security-reviewer/agent/lib/review-stages.ts"><code>review-stages.ts</code></a>.</p><h2 id="validate-the-discovered-agent" tabindex="-1">Validate the discovered agent <a class="header-anchor" href="#validate-the-discovered-agent" aria-label="Permalink to "Validate the discovered agent""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
2
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
3
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
1
|
+
import{_ as t,c as s,o as a,ag as i}from"./chunks/framework.CAZyNGu9.js";const u=JSON.parse('{"title":"Run staged security reviews from GitHub events","description":"Orchestrate parallel reviewer agents, streamed triage, deterministic stages, live playground progress, durable sessions, and severity A/B metrics.","frontmatter":{"title":"Run staged security reviews from GitHub events","description":"Orchestrate parallel reviewer agents, streamed triage, deterministic stages, live playground progress, durable sessions, and severity A/B metrics."},"headers":[],"relativePath":"example-agents/security-reviewer.md","filePath":"example-agents/security-reviewer.md"}'),r={name:"example-agents/security-reviewer.md"};function n(o,e,l,d,h,p){return a(),s("div",null,[...e[0]||(e[0]=[i(`<h1 id="run-staged-security-reviews-from-github-events" tabindex="-1">Run staged security reviews from GitHub events <a class="header-anchor" href="#run-staged-security-reviews-from-github-events" aria-label="Permalink to "Run staged security reviews from GitHub events""></a></h1><p>Security Reviewer turns a pull request into a staged host-side review. One tool prepares the diff and selects modules. A second fans out specialized reviewers and triages candidates as they arrive. A third deduplicates the confirmed findings, writes artifacts, and may publish a GitHub review.</p><p>Use this example when the workflow needs several model workers, but the host must own orchestration, progress, artifacts, and the final write.</p><p>Source lives under <a href="./../../../../factory/security-reviewer/"><code>factory/security-reviewer/</code></a> (factory agent, not under <code>examples/</code>).</p><p><a href="./../../../../factory/security-reviewer/">Browse the Security Reviewer source.</a></p><h2 id="run-a-three-stage-host-pipeline" tabindex="-1">Run a three-stage host pipeline <a class="header-anchor" href="#run-a-three-stage-host-pipeline" aria-label="Permalink to "Run a three-stage host pipeline""></a></h2><p>Security Reviewer is a pipeline, not one long agent turn:</p><table tabindex="0"><thead><tr><th>Stage</th><th>Tool</th><th>Result</th></tr></thead><tbody><tr><td>Prepare</td><td><code>prepare_review</code></td><td>Fetch metadata and diff, create a <code>runId</code>, and select security modules.</td></tr><tr><td>Review and triage</td><td><code>run_reviewers</code></td><td>Run module reviewers in parallel and start triage as each candidate arrives.</td></tr><tr><td>Finalize</td><td><code>finalize_review</code></td><td>Apply thresholds, deduplicate findings, write artifacts, and optionally post a review.</td></tr></tbody></table><p><code>run_triage</code> remains available as a compatibility stage. In the normal flow, triage has already completed inside <code>run_reviewers</code>, so it reports existing results. If candidates exist without triage output, it starts triage workers and writes their state.</p><p>The configured root agent chooses and sequences tools in chat. The review workers use a model selected by the host pipeline. They are created programmatically with the agent SDK, not discovered from <code>agent/subagents/</code>.</p><h2 id="follow-a-github-wake" tabindex="-1">Follow a GitHub wake <a class="header-anchor" href="#follow-a-github-wake" aria-label="Permalink to "Follow a GitHub wake""></a></h2><ol><li>A non-draft <code>pull_request.opened</code> or <code>pull_request.synchronize</code> event arrives for an allowlisted repository.</li><li>The GitHub channel returns a host <code>{ task }</code>, so the webhook gets a 202 response before the long review starts.</li><li>Host code tries to post a pending commit status and creates a playground session.</li><li>The root model sends one acknowledgement. It doesn't run review tools on this path.</li><li>The task calls <code>prepare_review</code>, <code>run_reviewers</code>, and <code>finalize_review</code> deterministically inside that session.</li><li>Reviewer candidates stream into duplicate gating and triage.</li><li>Finalization writes artifacts and tries to post the GitHub review.</li><li>The host tries to set a success commit status when no findings remain, a failure status when findings remain, or an error status when the pipeline throws.</li><li>The final response is appended to the session as an assistant message.</li></ol><p>The session records each stage as a normal tool event, even though host code selected the tools.</p><p>Review and status posting are best-effort. The channel chooses its final status from the finding count even when the review posting result says <code>posted: false</code>.</p><h2 id="map-the-framework-features" tabindex="-1">Map the framework features <a class="header-anchor" href="#map-the-framework-features" aria-label="Permalink to "Map the framework features""></a></h2><table tabindex="0"><thead><tr><th>Capability</th><th>Source</th><th>Role</th></tr></thead><tbody><tr><td>Root agent</td><td><a href="../../../../factory/security-reviewer/agent/agent.ts"><code>agent/agent.ts</code></a>, <a href="./../../../../factory/security-reviewer/agent/instructions.html"><code>agent/instructions.md</code></a></td><td>Configure local chat and explain the three-stage contract.</td></tr><tr><td>Server tools</td><td><a href="./../../../../factory/security-reviewer/agent/tools/"><code>agent/tools/</code></a></td><td>Expose each review stage to chat and host orchestration.</td></tr><tr><td>GitHub channel</td><td><a href="../../../../factory/security-reviewer/agent/channels/github.ts"><code>agent/channels/github.ts</code></a></td><td>Filter wakes, run background tasks, and publish status.</td></tr><tr><td>Progress channel</td><td><a href="../../../../factory/security-reviewer/agent/channels/asr-progress.ts"><code>agent/channels/asr-progress.ts</code></a></td><td>Serve live reviewer and triage state by <code>runId</code>.</td></tr><tr><td>Playground renderer</td><td><a href="./../../../../factory/security-reviewer/agent/playground/tools/run_reviewers.tsx.html"><code>agent/playground/tools/run_reviewers.tsx</code></a></td><td>Replace the generic tool chip with live module rows.</td></tr><tr><td>SDK review pipeline</td><td><a href="../../../../factory/security-reviewer/agent/lib/review-stages.ts"><code>review-stages.ts</code></a>, <a href="../../../../packages/security-review-lib/src/index.ts"><code>@anysphere/security-review-lib</code></a></td><td>Select modules, call model workers, triage, deduplicate, and write artifacts.</td></tr><tr><td>Storage</td><td><a href="../../../../factory/security-reviewer/agent/storage.ts"><code>agent/storage.ts</code></a></td><td>Persist framework sessions with <code>cursorHostedStorage</code> (lazy restore).</td></tr><tr><td>A/B</td><td><a href="../../../../factory/security-reviewer/agent/ab.ts"><code>agent/ab.ts</code></a></td><td>Compare all-severity versus high-only GitHub comments.</td></tr><tr><td>Eval</td><td><a href="./../../../../factory/security-reviewer/evals/"><code>evals/</code></a></td><td>Check stage-tool presence against a pinned sample.</td></tr></tbody></table><p>There is no Slack channel, authored skill, discovered subagent, MCP connection, schedule, reminder, hook, tool approval, or cloud runtime.</p><h2 id="prepare-the-host" tabindex="-1">Prepare the host <a class="header-anchor" href="#prepare-the-host" aria-label="Permalink to "Prepare the host""></a></h2><p>You need:</p><ul><li>Node 22.13 or newer.</li><li>An agent-runtime credential for the root turn and review workers.</li><li>GitHub read access for preparation.</li><li>GitHub write access for webhook-driven reviews and commit statuses.</li></ul><p>The pipeline exposes settings for:</p><ul><li>the worker model,</li><li>reviewer and triage parallelism,</li><li>reviewer, triage, duplicate-gate, and final-dedupe timeouts, and</li><li>prior-comment loading.</li></ul><p>The active names live beside the orchestration in <a href="../../../../factory/security-reviewer/agent/lib/review-stages.ts"><code>review-stages.ts</code></a>.</p><h2 id="validate-the-discovered-agent" tabindex="-1">Validate the discovered agent <a class="header-anchor" href="#validate-the-discovered-agent" aria-label="Permalink to "Validate the discovered agent""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --list</span></span></code></pre></div><p>The manifest should show four server tools, two authored channels, one storage definition, and one A/B experiment. The eval listing should show one case.</p><h2 id="know-the-chat-path-s-write-boundary" tabindex="-1">Know the chat path's write boundary <a class="header-anchor" href="#know-the-chat-path-s-write-boundary" aria-label="Permalink to "Know the chat path's write boundary""></a></h2><p>In chat, the root instructions ask the model to use this order:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>prepare_review -> run_reviewers -> finalize_review</span></span></code></pre></div><p>They also ask the model to set <code>postComment: true</code> only on request. This is prompt policy, not a deterministic safety gate. The model chooses tool arguments, and <code>finalize_review</code> has no human approval. Use the direct stage calls below when a no-post proof must be enforced.</p><h2 id="call-stages-directly-without-publishing" tabindex="-1">Call stages directly without publishing <a class="header-anchor" href="#call-stages-directly-without-publishing" aria-label="Permalink to "Call stages directly without publishing""></a></h2><p>Call each stage and pass <code>postComment: false</code> yourself:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> prepare_review</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
4
4
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
5
5
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"prUrl":"https://github.com/owner/repo/pull/123"}'</span></span>
|
|
6
6
|
<span class="line"></span>
|
|
7
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
7
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run_reviewers</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
8
8
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
9
9
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"runId":"<run-id>"}'</span></span>
|
|
10
10
|
<span class="line"></span>
|
|
11
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
11
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> finalize_review</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
12
12
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
13
|
-
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"runId":"<run-id>","postComment":false}'</span></span></code></pre></div><p>Review state lives under the project's run-artifact directory, so later stages can open the prepared <code>runId</code>.</p><div class="caution custom-block github-alert"><p class="custom-block-title">CAUTION</p><p><code>finalize_review</code> with <code>postComment: true</code> writes to GitHub. The webhook path always requests that write. Chat instructions alone don't prevent it.</p></div><h2 id="watch-parallel-work-in-the-playground" tabindex="-1">Watch parallel work in the playground <a class="header-anchor" href="#watch-parallel-work-in-the-playground" aria-label="Permalink to "Watch parallel work in the playground""></a></h2><p>Run the dev server:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
13
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"runId":"<run-id>","postComment":false}'</span></span></code></pre></div><p>Review state lives under the project's run-artifact directory, so later stages can open the prepared <code>runId</code>.</p><div class="caution custom-block github-alert"><p class="custom-block-title">CAUTION</p><p><code>finalize_review</code> with <code>postComment: true</code> writes to GitHub. The webhook path always requests that write. Chat instructions alone don't prevent it.</p></div><h2 id="watch-parallel-work-in-the-playground" tabindex="-1">Watch parallel work in the playground <a class="header-anchor" href="#watch-parallel-work-in-the-playground" aria-label="Permalink to "Watch parallel work in the playground""></a></h2><p>Run the dev server:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span></span></code></pre></div><p>Open the printed playground and start a review. The custom <code>run_reviewers</code> renderer polls the progress channel's <code>GET /:runId</code> route.</p><p>It refreshes every 500 ms while the stage runs. Each row shows a reviewer module's state, candidates, reviewed areas, and failure. A second section shows triage jobs and confirmed or rejected counts.</p><p>This is an authored playground extension. The Agent SDK discovers it by the tool name, so the generic <code>run_reviewers</code> chip becomes a domain-specific view without changing the framework playground.</p><h2 id="fan-out-reviewers-while-triage-starts" tabindex="-1">Fan out reviewers while triage starts <a class="header-anchor" href="#fan-out-reviewers-while-triage-starts" aria-label="Permalink to "Fan out reviewers while triage starts""></a></h2><p>Module selection uses repository and path rules. The current module set covers:</p><ul><li>agent tooling trust boundaries,</li><li>privileged service RPCs,</li><li>product-specific security risks,</li><li>dependency and supply-chain changes,</li><li>deployment and infrastructure code,</li><li>filesystem and workspace boundaries,</li><li>privacy, and</li><li>general security review.</li></ul><p>Selected modules may run more than once. Candidates pass through a duplicate gate, then bounded triage. Reviewer or triage failures can produce partial results. A final dedupe failure stops finalization.</p><p>The pipeline writes JSONL journals as work completes. Final artifacts include the review bundle, patch, reviewer outputs, candidates, triage decisions, findings, accounting, and audit events.</p><h2 id="separate-session-storage-from-review-artifacts" tabindex="-1">Separate session storage from review artifacts <a class="header-anchor" href="#separate-session-storage-from-review-artifacts" aria-label="Permalink to "Separate session storage from review artifacts""></a></h2><p><code>defineStorage</code> + <code>cursorHostedStorage</code> sends Agent SDK session and event records to Cursor-hosted Bugbot storage through the control-plane proxy. Security Reviewer sets <code>restore: "off"</code> so startup doesn't load old review sessions in bulk. A continuation lookup can still fetch a needed session.</p><p>The staged review files are separate from session storage. Session-store durability doesn't preserve those files. All stages for one <code>runId</code> must see the same filesystem.</p><p>This split is useful when conversation history needs shared durability but large review artifacts belong on attached storage or an object store.</p><h2 id="compare-live-comment-variants" tabindex="-1">Compare live comment variants <a class="header-anchor" href="#compare-live-comment-variants" aria-label="Permalink to "Compare live comment variants""></a></h2><p>The comment-severity experiment uses sticky session assignment with a 5% holdout:</p><ul><li><code>control</code> posts every finding.</li><li><code>treatment</code> posts only high and critical findings.</li></ul><p>Finalization enforces the comment filter. The treatment also adds an instruction overlay asking chat and playground summaries to lead with high and critical findings. Full artifacts, <code>finalResponse</code>, finding counts, and status still include every finding. Stage-tool counters appear in the playground A/B view. Local sample and snapshot files persist under <code>.agent-serve/</code>.</p><p>When a treatment session has only low or medium findings, the filtered review body currently says no vulnerabilities were found even though artifacts and status retain findings. Account for that mismatch before using this experiment as a publishing policy.</p><p>Eval sessions skip A/B enrollment.</p><h2 id="test-the-github-channel-carefully" tabindex="-1">Test the GitHub channel carefully <a class="header-anchor" href="#test-the-github-channel-carefully" aria-label="Permalink to "Test the GitHub channel carefully""></a></h2><p>The channel currently accepts two configured repositories. It wakes on <code>opened</code> and <code>synchronize</code>, skips drafts, and requests <code>pr-write</code> access.</p><p>Inspect its event surface:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> github</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> events</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
14
14
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
15
15
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span></code></pre></div><p>Replay reaches the full publishing path:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">TEST_PR_URL</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">https://github.com/your-org/allowlisted-test-repo/pull/123</span></span>
|
|
16
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
16
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> github</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> replay</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
17
17
|
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">$TEST_PR_URL</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
18
18
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
19
|
-
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --action</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> opened</span></span></code></pre></div><p>Set <code>TEST_PR_URL</code> to a PR in the channel's configured repository allowlist. Run the command only against a PR intended for test reviews. It posts a commit status and may post findings.</p><h2 id="inspect-the-eval-before-running-it" tabindex="-1">Inspect the eval before running it <a class="header-anchor" href="#inspect-the-eval-before-running-it" aria-label="Permalink to "Inspect the eval before running it""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">
|
|
19
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --action</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> opened</span></span></code></pre></div><p>Set <code>TEST_PR_URL</code> to a PR in the channel's configured repository allowlist. Run the command only against a PR intended for test reviews. It posts a commit status and may post findings.</p><h2 id="inspect-the-eval-before-running-it" tabindex="-1">Inspect the eval before running it <a class="header-anchor" href="#inspect-the-eval-before-running-it" aria-label="Permalink to "Inspect the eval before running it""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ../../factory/security-reviewer</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --list</span></span></code></pre></div><p>The case reads pinned metadata from the committed fixture and checks for all three tool names. It doesn't assert their order. The current <code>prepare_review</code> still fetches the live PR, so the case needs GitHub access and isn't fully offline. It also doesn't assert finding location, severity, agreement with <code>gold.json</code>, or <code>postComment: false</code>.</p><p>Don't use this committed case as a no-post proof with write-capable GitHub credentials. The prompt asks for no comment, but the model can still pass <code>postComment: true</code>.</p><p>When you adapt the pipeline, add assertions for confirmed findings and make the prepare stage accept a materialized fixture if repeatable offline evals matter.</p><h2 id="build-another-staged-pipeline" tabindex="-1">Build another staged pipeline <a class="header-anchor" href="#build-another-staged-pipeline" aria-label="Permalink to "Build another staged pipeline""></a></h2><p>Use staged host orchestration when:</p><ul><li>each phase needs its own timeout and artifact,</li><li>model workers should run in bounded parallel,</li><li>later work can start as soon as partial results arrive,</li><li>a webhook must acknowledge before the work finishes, or</li><li>operators need live progress beyond one tool spinner.</li></ul><p>Keep external writes in finalization. Pass a <code>runId</code> between stages, journal progress before publishing, and make partial-worker failures visible in the result.</p><h2 id="where-to-go-next" tabindex="-1">Where to go next <a class="header-anchor" href="#where-to-go-next" aria-label="Permalink to "Where to go next""></a></h2><ul><li><a href="./../guides/github.html">GitHub</a></li><li><a href="./../reference/tools.html">Tools</a></li><li><a href="./../reference/channels.html">Channels</a></li><li><a href="./../reference/playground.html">Playground</a></li><li><a href="./../storage.html">Storage</a></li><li><a href="./../ab.html">Live A/B metrics</a></li><li><a href="./../evals.html">Evals</a></li></ul>`,74)])])}const g=t(r,[["render",n]]);export{u as __pageData,g as default};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{_ as a,c as t,o as s,ag as n}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Put a minimal agent in Slack","description":"Use account-linked Slack routing, thread continuity, identity, and suggested prompts with one small channel.","frontmatter":{"title":"Put a minimal agent in Slack","description":"Use account-linked Slack routing, thread continuity, identity, and suggested prompts with one small channel."},"headers":[],"relativePath":"example-agents/slack-agent.md","filePath":"example-agents/slack-agent.md"}'),i={name:"example-agents/slack-agent.md"};function l(o,e,h,r,d,c){return s(),t("div",null,[...e[0]||(e[0]=[n(`<h1 id="put-a-minimal-agent-in-slack" tabindex="-1">Put a minimal agent in Slack <a class="header-anchor" href="#put-a-minimal-agent-in-slack" aria-label="Permalink to "Put a minimal agent in Slack""></a></h1><p>Slack agent is the smallest channel example. It has one runtime config, one instruction file, and one authored channel. A teammate mentions the agent, the local runtime harness runs a turn, and the answer returns to the same Slack thread.</p><p>Use it to learn the minimum needed for a Slack agent before adding tools, workflows, or a dedicated app.</p><p><a href="./../../examples/slack-agent/">Browse the Slack agent source.</a></p><h2 id="keep-the-slack-channel-small" tabindex="-1">Keep the Slack channel small <a class="header-anchor" href="#keep-the-slack-channel-small" aria-label="Permalink to "Keep the Slack channel small""></a></h2><p>Slack agent delegates transport details to the host connection. The authored file selects the account-linked transport, gives the agent a single-token router name and icon, and supplies suggested prompts.</p><p>The complete channel lives in <a href="../../examples/slack-agent/agent/channels/slack.ts"><code>agent/channels/slack.ts</code></a>. The framework supplies message intake, thread-scoped sessions, delivery, status updates, and suggested prompts.</p><h2 id="follow-a-slack-message" tabindex="-1">Follow a Slack message <a class="header-anchor" href="#follow-a-slack-message" aria-label="Permalink to "Follow a Slack message""></a></h2><ol><li>A user mentions the agent or sends the host app a direct message naming it.</li><li>The Slack relay selects this channel by its single-token <code>agentName</code>.</li><li>The Agent SDK maps the Slack channel and thread timestamp to a continuation key.</li><li>The local harness runs with <a href="./../../examples/slack-agent/agent/instructions.html"><code>instructions.md</code></a>.</li><li>The response returns to the triggering thread.</li><li>A later message in the same thread resumes the durable session.</li></ol><p>The prompt asks for concise threaded replies. It doesn't define domain policy or tool routing.</p><h2 id="map-the-slack-agent-files" tabindex="-1">Map the Slack agent files <a class="header-anchor" href="#map-the-slack-agent-files" aria-label="Permalink to "Map the Slack agent files""></a></h2><table tabindex="0"><thead><tr><th>File</th><th>Purpose</th></tr></thead><tbody><tr><td><a href="../../examples/slack-agent/package.json"><code>package.json</code></a></td><td>Declares the example package and Agent SDK dependency.</td></tr><tr><td><a href="../../examples/slack-agent/agent/agent.ts"><code>agent/agent.ts</code></a></td><td>Names the agent and selects the model. The omitted <code>runtime</code> defaults to local.</td></tr><tr><td><a href="./../../examples/slack-agent/agent/instructions.html"><code>agent/instructions.md</code></a></td><td>Sets the always-on response style.</td></tr><tr><td><a href="../../examples/slack-agent/agent/channels/slack.ts"><code>agent/channels/slack.ts</code></a></td><td>Connects the signed-in host account to Slack.</td></tr></tbody></table><p>There are no authored tools, skills, MCP connections, subagents, schedules, hooks, A/B experiments, or evals. This small surface is the lesson.</p><h2 id="connect-the-host" tabindex="-1">Connect the host <a class="header-anchor" href="#connect-the-host" aria-label="Permalink to "Connect the host""></a></h2><p>You need:</p><ul><li>Node 22.13 or newer.</li><li>An agent-runtime credential.</li><li>Slack connected through the selected channel transport.</li></ul><p>Sign in and confirm the active account:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> login</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> whoami</span></span></code></pre></div><p>The selected transport owns Slack credential setup. See the <a href="./../guides/slack.html">Slack guide</a> for account-linked and dedicated-app options.</p><h2 id="validate-and-start-the-server" tabindex="-1">Validate and start the server <a class="header-anchor" href="#validate-and-start-the-server" aria-label="Permalink to "Validate and start the server""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/slack-agent</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/slack-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/slack-agent</span></span></code></pre></div><p>The dev command prints the playground URL. It also mounts the Slack channel and waits for relayed messages.</p><p>In Slack, address the configured host app and router name, then send:</p><blockquote><p><code><host-app mention> <router name></code> Explain the Agent SDK in three bullets.</p></blockquote><p>Reply in the generated thread:</p><blockquote><p>Make the second bullet simpler.</p></blockquote><p>The second message reaches the same session. You can open that session in the playground to inspect the received message, model events, final reply, and usage.</p><h2 id="test-without-slack" tabindex="-1">Test without Slack <a class="header-anchor" href="#test-without-slack" aria-label="Permalink to "Test without Slack""></a></h2><p>Every project gets the built-in HTTP channel even when no HTTP file exists. Run a one-shot turn through it:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/slack-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --message</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Explain the Agent SDK simply."</span></span></code></pre></div><p>The same project also exposes an MCP endpoint. Since this agent has no server tools, its MCP surface contains <code>ask</code> and <code>check</code>, but not <code>call_tool</code>.</p><p>These automatic surfaces let you test the prompt from the CLI and let another agent delegate to it later. The authored Slack channel only changes how work arrives and where replies go.</p><h2 id="know-when-to-add-a-dedicated-app" tabindex="-1">Know when to add a dedicated app <a class="header-anchor" href="#know-when-to-add-a-dedicated-app" aria-label="Permalink to "Know when to add a dedicated app""></a></h2><p>An account-linked Slack transport is a fit for mentions, direct messages, thread continuity, and agent-branded replies. Move to a dedicated Socket Mode channel when you need:</p><ul><li>top-level channel watching,</li><li>interactive approval buttons,</li><li>a separate bot identity, or</li><li>Slack app events unsupported by the account-linked relay.</li></ul><p>Compare this example with <a href="./benny.html">Playbook router</a>, which adds allowlisted channel watching, and <a href="./weather-agent.html">Weather agent</a>, which adds approval buttons through a second Slack channel.</p><h2 id="turn-the-channel-into-your-own-slack-agent" tabindex="-1">Turn the channel into your own Slack agent <a class="header-anchor" href="#turn-the-channel-into-your-own-slack-agent" aria-label="Permalink to "Turn the channel into your own Slack agent""></a></h2><p>Copy the three authored files, then change:</p><ul><li><code>name</code> in <code>agent.ts</code> for the harness identity,</li><li><code>agentName</code> in <code>slack.ts</code> for the single-token router name,</li><li>the instructions for your domain, and</li><li>suggested prompts for the tasks teammates should try.</li></ul><p>Keep <code>agentName</code> free of whitespace. Use PascalCase for multiword names.</p><h2 id="where-to-go-next" tabindex="-1">Where to go next <a class="header-anchor" href="#where-to-go-next" aria-label="Permalink to "Where to go next""></a></h2><ul><li><a href="./../guides/slack.html">Slack</a></li><li><a href="./../reference/channels.html">Channels</a></li><li><a href="./../reference/sessions.html">Sessions and streaming</a></li><li><a href="./../reference/playground.html">Playground</a></li></ul>`,42)])])}const g=a(i,[["render",l]]);export{k as __pageData,g as default};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import{_ as s,c as a,o as t,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Explore the full Agent SDK surface with a weather agent","description":"Trace tools, MCP, channels, approvals, skills, subagents, schedules, hooks, A/B metrics, and evals through one local agent.","frontmatter":{"title":"Explore the full Agent SDK surface with a weather agent","description":"Trace tools, MCP, channels, approvals, skills, subagents, schedules, hooks, A/B metrics, and evals through one local agent."},"headers":[],"relativePath":"example-agents/weather-agent.md","filePath":"example-agents/weather-agent.md"}'),n={name:"example-agents/weather-agent.md"};function h(o,e,l,r,p,d){return t(),a("div",null,[...e[0]||(e[0]=[i(`<h1 id="explore-the-full-agent-sdk-surface-with-a-weather-agent" tabindex="-1">Explore the full Agent SDK surface with a weather agent <a class="header-anchor" href="#explore-the-full-agent-sdk-surface-with-a-weather-agent" aria-label="Permalink to "Explore the full Agent SDK surface with a weather agent""></a></h1><p>The weather agent is the broadest small example in the repository. It fetches live conditions and forecasts, converts units through MCP, writes notes in a session workspace, and pauses an alert tool for human approval. The same agent also runs from HTTP, Slack, a schedule, and the MCP endpoint.</p><p>Use this project when you want to see how the Agent SDK's filesystem pieces fit together before you design a larger agent.</p><p><a href="./../../examples/weather-agent/">Browse the weather agent source.</a></p><h2 id="see-every-local-runtime-feature-together" tabindex="-1">See every local runtime feature together <a class="header-anchor" href="#see-every-local-runtime-feature-together" aria-label="Permalink to "See every local runtime feature together""></a></h2><p>Most examples focus on one architecture. Weather agent puts the major local runtime features side by side:</p><table tabindex="0"><thead><tr><th>Capability</th><th>Source</th><th>Role</th></tr></thead><tbody><tr><td>Root config and instructions</td><td><a href="../../examples/weather-agent/agent/agent.ts"><code>agent/agent.ts</code></a>, <a href="./../../examples/weather-agent/agent/instructions.html"><code>agent/instructions.md</code></a></td><td>Select the local runtime and route each request.</td></tr><tr><td>Server tools</td><td><a href="./../../examples/weather-agent/agent/tools/"><code>agent/tools/</code></a></td><td>Fetch Open-Meteo data, call MCP, and model an approval-gated action.</td></tr><tr><td>Agent tool</td><td><a href="../../examples/weather-agent/agent/tools/save_weather_note.ts"><code>save_weather_note.ts</code></a></td><td>Run a Python script inside the session workspace.</td></tr><tr><td>Stdio MCP</td><td><a href="../../examples/weather-agent/agent/mcp-connections/units.ts"><code>units.ts</code></a></td><td>Expose conversion tools to the model, host tools, and channel handlers.</td></tr><tr><td>Custom HTTP</td><td><a href="../../examples/weather-agent/agent/channels/webhook.ts"><code>webhook.ts</code></a></td><td>Start a turn or call MCP without a model turn.</td></tr><tr><td>Slack</td><td><a href="../../examples/weather-agent/agent/channels/slack.ts"><code>slack.ts</code></a>, <a href="../../examples/weather-agent/agent/channels/slack-app.ts"><code>slack-app.ts</code></a></td><td>Compare account-linked chat with a dedicated app offering approval buttons.</td></tr><tr><td>Skill and subagent</td><td><a href="./../../examples/weather-agent/agent/skills/forecast.html"><code>forecast.md</code></a>, <a href="./../../examples/weather-agent/agent/subagents/researcher/"><code>researcher/</code></a></td><td>Load a procedure on demand or delegate broad research.</td></tr><tr><td>Schedule and hook</td><td><a href="./../../examples/weather-agent/agent/schedules/heartbeat.html"><code>heartbeat.md</code></a>, <a href="../../examples/weather-agent/agent/hooks/audit.ts"><code>audit.ts</code></a></td><td>Start recurring task sessions and observe completed turns.</td></tr><tr><td>A/B and evals</td><td><a href="../../examples/weather-agent/agent/ab.ts"><code>agent/ab.ts</code></a>, <a href="./../../examples/weather-agent/evals/"><code>evals/</code></a></td><td>Compare a sticky variant and protect tool routing with regression cases.</td></tr></tbody></table><h2 id="follow-one-request" tabindex="-1">Follow one request <a class="header-anchor" href="#follow-one-request" aria-label="Permalink to "Follow one request""></a></h2><p>A current-weather question takes this path:</p><ol><li>The built-in HTTP channel, Slack, or the custom <code>/report</code> route creates a durable session.</li><li><code>instructions.md</code> tells the model to call <code>get_weather</code> instead of guessing.</li><li>The server tool geocodes the city, fetches Open-Meteo, validates the response, and returns normalized fields.</li><li>The agent writes a short answer. The Agent SDK records every event in the session stream.</li><li>The audit hook observes <code>turn.completed</code>. If the session joined the A/B experiment, the collector updates its metrics too.</li></ol><p>Forecasts route to <code>get_forecast</code>. Unit conversions route to <code>convert_temperature</code>, which calls the <code>units</code> MCP server through <code>ctx.host.mcp</code>. Climate history and broad comparisons route to the <code>researcher</code> subagent.</p><h2 id="prepare-the-example" tabindex="-1">Prepare the example <a class="header-anchor" href="#prepare-the-example" aria-label="Permalink to "Prepare the example""></a></h2><p>You need:</p><ul><li>Node 22.13 or newer.</li><li>An agent-runtime credential.</li><li>Network access to Open-Meteo.</li><li>Python 3 for <code>save_weather_note</code>.</li></ul><p>The project mounts an account-linked Slack channel. The Agent SDK checks the connection at startup, so sign in even when you plan to call a deterministic tool.</p><p>The optional approval-enabled Slack app also needs a token pair. <code>agent-sdk slack create --dir examples/weather-agent</code> provisions the app and writes the tokens for you (see the <a href="./../guides/slack.html#set-it-up">Slack guide</a>); with hand-minted tokens, export them instead:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> WEATHER_AGENT_SLACK_BOT_TOKEN</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">xoxb-...</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> WEATHER_AGENT_SLACK_APP_TOKEN</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">xapp-...</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> doctor</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prefix</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> WEATHER_AGENT</span></span></code></pre></div><p>Without those two tokens, the dedicated channel stays idle. The account-linked channel still works.</p><h2 id="inspect-before-running" tabindex="-1">Inspect before running <a class="header-anchor" href="#inspect-before-running" aria-label="Permalink to "Inspect before running""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> validate</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> info</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --list</span></span></code></pre></div><p>The manifest should report five tools, one skill, one MCP connection, one subagent, three authored channels, one schedule, one hook, and one A/B experiment. The eval listing should report eight cases.</p><h2 id="call-the-typed-tools" tabindex="-1">Call the typed tools <a class="header-anchor" href="#call-the-typed-tools" aria-label="Permalink to "Call the typed tools""></a></h2><p>Start with the current-weather server tool:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> get_weather</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
6
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
7
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"city":"New York City"}'</span></span></code></pre></div><p><code>defineTool</code> gives the input a Zod schema. The Agent SDK validates the JSON before <code>execute</code> runs. The result includes the matched place, condition, temperature, humidity, wind, gusts, and precipitation.</p><p>Try the forecast:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> get_forecast</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
8
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
9
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"city":"Lisbon","days":5}'</span></span></code></pre></div><p>The tool accepts one to seven days. Shared Open-Meteo code lives under <code>agent/lib/</code>, so the Agent SDK imports it without discovering another tool.</p><h2 id="compare-server-and-agent-execution" tabindex="-1">Compare server and agent execution <a class="header-anchor" href="#compare-server-and-agent-execution" aria-label="Permalink to "Compare server and agent execution""></a></h2><p>Most weather tools use the default <code>execution: "server"</code>. Their TypeScript runs inside the serve host and can reach <code>ctx.host</code> services.</p><p><code>save_weather_note</code> uses <code>execution: "agent"</code> instead. The Agent SDK materializes its script into the agent environment. The script reads JSON from stdin and appends to <code>weather-notes.md</code> in that session's workspace:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --message</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Save a note that Boston is cold and windy."</span></span></code></pre></div><p>Each session gets its own workspace. Saving a note doesn't edit the authored example.</p><p>This split matters on cloud. Server tools are local-runtime only. For a cloud turn, the Agent SDK includes an agent tool's catalog and script body in the first prompt. The cloud model writes and invokes the script in its VM; the serve host doesn't materialize it there.</p><h2 id="use-one-mcp-connection-in-three-places" tabindex="-1">Use one MCP connection in three places <a class="header-anchor" href="#use-one-mcp-connection-in-three-places" aria-label="Permalink to "Use one MCP connection in three places""></a></h2><p><code>agent/mcp-connections/units.ts</code> starts a local stdio server. The filename makes its server name <code>units</code>. The Agent SDK exposes it to:</p><ul><li>the model as MCP tools,</li><li>server tools through <code>ctx.host.mcp</code>, and</li><li>channel handlers through <code>host.mcp</code>.</li></ul><p><code>convert_temperature</code> demonstrates the server-tool path:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> call</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> convert_temperature</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --input</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"value":72,"from":"F"}'</span></span></code></pre></div><p>The custom channel demonstrates the handler path. Start the dev server:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span></span></code></pre></div><p>Then call MCP deterministically through <code>/convert</code>:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -s</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
13
|
+
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/weather-agent/v1/channels/webhook/convert</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'content-type: application/json'</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
15
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"value":20,"from":"C"}'</span></span></code></pre></div><p>No model chooses a tool in this route. The handler calls the MCP server and returns its result.</p><h2 id="keep-conversation-state-in-a-custom-channel" tabindex="-1">Keep conversation state in a custom channel <a class="header-anchor" href="#keep-conversation-state-in-a-custom-channel" aria-label="Permalink to "Keep conversation state in a custom channel""></a></h2><p><code>POST /report</code> starts a model turn and waits for it:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -s</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
16
|
+
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/weather-agent/v1/channels/webhook/report</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
17
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'content-type: application/json'</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
18
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"message":"What is the weather in Paris?"}'</span></span></code></pre></div><p>The response includes a <code>key</code>. Send it back on the next request to continue the same session:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -s</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
19
|
+
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/weather-agent/v1/channels/webhook/report</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
20
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'content-type: application/json'</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
21
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"message":"How about tomorrow?","key":"<key>"}'</span></span></code></pre></div><p>This is the custom-channel version of a continuation token. See <a href="./../guides/webhooks.html">webhooks and custom channels</a> for route schemas, authentication, and asynchronous handlers.</p><h2 id="pause-a-tool-for-human-approval" tabindex="-1">Pause a tool for human approval <a class="header-anchor" href="#pause-a-tool-for-human-approval" aria-label="Permalink to "Pause a tool for human approval""></a></h2><p><code>post_weather_alert</code> sets <code>needsApproval: true</code>. Ask for an ops alert in the playground and the model's tool call parks before <code>execute</code>:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span></span></code></pre></div><p>Open the printed playground URL, ask:</p><blockquote><p>Alert ops that severe weather is approaching Boston.</p></blockquote><p>Approve or deny the call in the transcript. The dedicated Socket Mode Slack channel can show the same buttons when <code>toolApprovals: true</code> and Slack interactivity are configured.</p><p>The example tool returns a placeholder success object. It doesn't contact Slack, PagerDuty, or an ops board. Replace its <code>execute</code> body with your own sink before adapting it.</p><p>Use a model turn for this proof. A deterministic <code>agent-sdk call</code> runs the tool body directly and doesn't demonstrate the parked approval flow.</p><h2 id="load-procedures-and-delegate-research" tabindex="-1">Load procedures and delegate research <a class="header-anchor" href="#load-procedures-and-delegate-research" aria-label="Permalink to "Load procedures and delegate research""></a></h2><p>The forecast skill gives the root agent an on-demand procedure. The Agent SDK advertises the skill's description, then the harness loads its content when the request matches.</p><p>The <code>researcher</code> directory is an SDK subagent. Its description tells the parent when to delegate. It inherits the parent's execution surface, but gets its own instructions:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
22
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --message</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Compare record summer temperatures across Paris, London, and Rome."</span></span></code></pre></div><p>Use a skill when the same agent needs a procedure. Use a subagent when the parent should hand a bounded task to a specialist. The <a href="./../reference/subagents.html">subagents reference</a> explains the current inheritance limits.</p><h2 id="trigger-the-schedule-and-inspect-the-hook" tabindex="-1">Trigger the schedule and inspect the hook <a class="header-anchor" href="#trigger-the-schedule-and-inspect-the-hook" aria-label="Permalink to "Trigger the schedule and inspect the hook""></a></h2><p>The heartbeat schedule runs at 09:00 UTC on weekdays. Automatic schedule timers stay off under <code>--dev</code>, so dispatch it manually:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -s</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
23
|
+
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/weather-agent/v1/dev/schedules/heartbeat</span></span></code></pre></div><p>It creates a task session to check San Francisco, New York, and London. The audit hook logs usage after each completed turn. Hooks observe recorded events; their failures don't fail the turn.</p><h2 id="measure-variants-and-regressions" tabindex="-1">Measure variants and regressions <a class="header-anchor" href="#measure-variants-and-regressions" aria-label="Permalink to "Measure variants and regressions""></a></h2><p>The <code>weather-tool-efficiency</code> A/B experiment assigns sessions by a sticky hash:</p><ul><li><code>control</code> returns current conditions in Fahrenheit.</li><li><code>treatment</code> adds a brief Celsius instruction and changes <code>get_weather</code> to return Celsius fields.</li></ul><p>Samples and aggregate snapshots persist under <code>.agent-serve/</code>. The treatment only changes current conditions; <code>get_forecast</code> still returns Fahrenheit. Treat the branch as an example of <code>ctx.session.abs</code>, not a complete unit policy.</p><p>List and run the evals:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --list</span></span>
|
|
24
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> examples/weather-agent</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --json</span></span></code></pre></div><p>Six cases cover current weather and forecasts against live Open-Meteo. Two more cover the local MCP converter and workspace note tool. Together they test model routing, external data, host MCP, and agent-side execution.</p><h2 id="turn-the-weather-tour-into-your-own-agent" tabindex="-1">Turn the weather tour into your own agent <a class="header-anchor" href="#turn-the-weather-tour-into-your-own-agent" aria-label="Permalink to "Turn the weather tour into your own agent""></a></h2><p>Keep the architecture and replace the domain:</p><ul><li>Swap Open-Meteo tools for your typed service clients.</li><li>Keep deterministic transforms behind direct server tools or MCP.</li><li>Use an agent tool only when code must run in the agent workspace.</li><li>Gate side effects with <code>needsApproval</code>.</li><li>Put reusable procedures in skills and narrow specialist work into subagents.</li><li>Add a channel only when the external surface needs its own identity, continuation key, or delivery behavior.</li></ul><h2 id="where-to-go-next" tabindex="-1">Where to go next <a class="header-anchor" href="#where-to-go-next" aria-label="Permalink to "Where to go next""></a></h2><ul><li><a href="./../reference/tools.html">Tools</a></li><li><a href="./../reference/connections.html">MCP connections</a></li><li><a href="./../guides/human-in-the-loop.html">Human-in-the-loop approvals</a></li><li><a href="./../guides/slack.html">Slack</a></li><li><a href="./../reference/schedules.html">Schedules and reminders</a></li><li><a href="./../evals.html">Evals</a></li><li><a href="./../ab.html">Live A/B metrics</a></li></ul>`,79)])])}const u=s(n,[["render",h]]);export{k as __pageData,u as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as s,c as a,o as t,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Explore the full Agent SDK surface with a weather agent","description":"Trace tools, MCP, channels, approvals, skills, subagents, schedules, hooks, A/B metrics, and evals through one local agent.","frontmatter":{"title":"Explore the full Agent SDK surface with a weather agent","description":"Trace tools, MCP, channels, approvals, skills, subagents, schedules, hooks, A/B metrics, and evals through one local agent."},"headers":[],"relativePath":"example-agents/weather-agent.md","filePath":"example-agents/weather-agent.md"}'),n={name:"example-agents/weather-agent.md"};function h(o,e,l,r,p,d){return t(),a("div",null,[...e[0]||(e[0]=[i("",79)])])}const u=s(n,[["render",h]]);export{k as __pageData,u as default};
|