@cursor/bdk 0.2.9 → 0.2.11
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/dist/artifacts.js +3 -5
- package/dist/bin/agent-serve.js +803 -812
- package/dist/channels/bitbucket/api.js +305 -321
- package/dist/channels/bitbucket/binding.js +97 -61
- package/dist/channels/bitbucket/bitbucket-channel.d.ts +15 -1
- package/dist/channels/bitbucket/bitbucket-channel.d.ts.map +1 -1
- package/dist/channels/bitbucket/bitbucket-channel.js +95 -42
- package/dist/channels/bitbucket/bitbucket-webhook.d.ts +11 -0
- package/dist/channels/bitbucket/bitbucket-webhook.d.ts.map +1 -1
- package/dist/channels/bitbucket/bitbucket-webhook.js +214 -204
- package/dist/channels/bitbucket/checks.js +9 -21
- package/dist/channels/bitbucket/cursor-account.js +1 -1
- package/dist/channels/bitbucket/defaults.js +14 -4
- package/dist/channels/bitbucket/events.js +1 -2
- package/dist/channels/bitbucket/index.d.ts +6 -2
- package/dist/channels/bitbucket/index.d.ts.map +1 -1
- package/dist/channels/bitbucket/index.js +6 -2
- package/dist/channels/bitbucket/replay.js +80 -56
- package/dist/channels/bitbucket/state.js +16 -7
- package/dist/channels/bitbucket/types.d.ts +11 -2
- package/dist/channels/bitbucket/types.d.ts.map +1 -1
- package/dist/channels/checks.js +18 -28
- package/dist/channels/deployments/deployments-channel.js +26 -34
- package/dist/channels/github/api.js +216 -210
- package/dist/channels/github/auth.d.ts +5 -1
- package/dist/channels/github/auth.d.ts.map +1 -1
- package/dist/channels/github/auth.js +157 -174
- package/dist/channels/github/binding.js +48 -39
- package/dist/channels/github/checks.js +9 -14
- package/dist/channels/github/cursor-account.js +6 -11
- package/dist/channels/github/defaults.js +105 -130
- package/dist/channels/github/forward.js +13 -17
- package/dist/channels/github/github-channel.d.ts +43 -2
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +1228 -958
- package/dist/channels/github/progress.js +145 -146
- package/dist/channels/github/replay.js +30 -39
- package/dist/channels/github/state.js +40 -16
- package/dist/channels/github/types.d.ts +30 -6
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/gitlab/api.js +100 -114
- package/dist/channels/gitlab/binding.js +52 -33
- package/dist/channels/gitlab/checks.js +28 -29
- package/dist/channels/gitlab/cursor-account.js +1 -1
- package/dist/channels/gitlab/defaults.js +9 -3
- package/dist/channels/gitlab/gitlab-channel.d.ts +16 -1
- package/dist/channels/gitlab/gitlab-channel.d.ts.map +1 -1
- package/dist/channels/gitlab/gitlab-channel.js +95 -42
- package/dist/channels/gitlab/gitlab-webhook.d.ts +10 -1
- package/dist/channels/gitlab/gitlab-webhook.d.ts.map +1 -1
- package/dist/channels/gitlab/gitlab-webhook.js +282 -249
- package/dist/channels/gitlab/index.d.ts +6 -2
- package/dist/channels/gitlab/index.d.ts.map +1 -1
- package/dist/channels/gitlab/index.js +6 -2
- package/dist/channels/gitlab/replay.js +50 -27
- package/dist/channels/gitlab/state.js +14 -6
- package/dist/channels/gitlab/types.d.ts +13 -2
- package/dist/channels/gitlab/types.d.ts.map +1 -1
- package/dist/channels/origin/api.js +100 -116
- package/dist/channels/origin/binding.js +15 -16
- package/dist/channels/origin/checks.js +30 -28
- package/dist/channels/origin/defaults.js +50 -65
- package/dist/channels/origin/origin-channel.js +266 -272
- package/dist/channels/origin/origin-webhook.js +70 -88
- package/dist/channels/origin/reactions.js +9 -21
- package/dist/channels/origin/state.js +13 -5
- package/dist/channels/slack/agentic-delivery.js +426 -478
- package/dist/channels/slack/agentic-posted.js +9 -10
- package/dist/channels/slack/agentic-signals.js +2 -3
- package/dist/channels/slack/api.js +417 -427
- package/dist/channels/slack/approvals.js +1 -1
- package/dist/channels/slack/assistant.js +37 -47
- package/dist/channels/slack/attachments.js +188 -206
- package/dist/channels/slack/auth.js +8 -6
- package/dist/channels/slack/bot-mentions.js +31 -45
- package/dist/channels/slack/channel-watch.js +42 -48
- package/dist/channels/slack/cli-project.js +112 -137
- package/dist/channels/slack/code-fences.js +3 -5
- package/dist/channels/slack/constants.js +2 -2
- package/dist/channels/slack/credentials.js +23 -38
- package/dist/channels/slack/defaults.js +292 -331
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +533 -460
- package/dist/channels/slack/doctor.js +200 -214
- package/dist/channels/slack/eval-directive.js +79 -96
- package/dist/channels/slack/event-id-dedupe.js +1 -1
- package/dist/channels/slack/external-policy.js +26 -39
- package/dist/channels/slack/footer.js +28 -41
- package/dist/channels/slack/inbound.d.ts +1 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +50 -31
- package/dist/channels/slack/init.d.ts +1 -5
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +42 -59
- package/dist/channels/slack/interactive.d.ts +9 -3
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +160 -162
- package/dist/channels/slack/links.js +1 -2
- package/dist/channels/slack/live-delivery.js +172 -190
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +44 -23
- package/dist/channels/slack/message-body.js +2 -2
- package/dist/channels/slack/nudge-carrier.js +30 -42
- package/dist/channels/slack/nudge-store.js +164 -191
- package/dist/channels/slack/paint-start.js +66 -81
- package/dist/channels/slack/placeholder.js +123 -152
- package/dist/channels/slack/pr-ref.js +1 -1
- package/dist/channels/slack/progress-delivery.js +65 -78
- package/dist/channels/slack/reasoning-card.js +36 -49
- package/dist/channels/slack/recording-sink.js +12 -24
- package/dist/channels/slack/reply-options.js +7 -12
- package/dist/channels/slack/self-identity.js +27 -35
- package/dist/channels/slack/sender-name.d.ts +12 -3
- package/dist/channels/slack/sender-name.d.ts.map +1 -1
- package/dist/channels/slack/sender-name.js +57 -61
- package/dist/channels/slack/setup.js +2 -4
- package/dist/channels/slack/slack-channel.d.ts +6 -4
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +441 -308
- package/dist/channels/slack/socket-mode.js +38 -52
- package/dist/channels/slack/thread-context.js +143 -160
- package/dist/channels/slack/tool-approval-events.js +149 -166
- package/dist/channels/slack/tool-cards.js +6 -11
- package/dist/channels/slack/tool-chip.js +1 -2
- package/dist/channels/slack/types.d.ts +15 -17
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/channels/slack/upload.js +84 -97
- package/dist/channels/slack/user-info.js +27 -41
- package/dist/channels.js +9 -20
- package/dist/dashboard-session-url.js +3 -4
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.BNhEdGa8.js → app.DXI7bwox.js} +4 -4
- package/dist/docs/assets/{building-with-agents.md.BPjPFxFg.js → building-with-agents.md.Df87rAe1.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CtLtpWcx.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DIdUV1Ph.js → VPLocalSearchBox.BrbO5mEe.js} +1 -1
- package/dist/docs/assets/chunks/{arc.lELI4_SR.js → arc.BOG1yms8.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.iCMdvuoM.js → architectureDiagram-Q4EWVU46.C0hsMZnZ.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.C1-nDJBf.js → baseUniq.H044KjKs.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.ClemzBox.js → blockDiagram-DXYQGD6D.BsRW6GoB.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.BqTak6cR.js → c4Diagram-AHTNJAMY.B9HV5PFR.js} +1 -1
- package/dist/docs/assets/chunks/channel.CBwrU9rP.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.CUS3qs_R.js → chunk-4BX2VUAB.CPoT_ajl.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.dz5fdHcl.js → chunk-4TB4RGXK.DZBwWuCL.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.D6BEBmve.js → chunk-55IACEB6.CZ3yTiyq.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.B5uK4ID9.js → chunk-EDXVE4YY.6DfvHSd8.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.PgOJgNQs.js → chunk-FMBD7UC4.CpBj8HfK.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.CvkTrCii.js → chunk-OYMX7WX6.BdKo8YqS.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BnSfKYsB.js → chunk-QZHKN3VN.BnXNyxJx.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.MZH6v5UC.js → chunk-YZCP3GAM.Cg1OcF8G.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CbC_mrvB.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CbC_mrvB.js +1 -0
- package/dist/docs/assets/chunks/clone.BTvFyY1a.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.BBbw_YZi.js → cose-bilkent-S5V4N54A.1SP8al9c.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.CNJB2l7E.js → dagre-KV5264BT.DS1L6hJt.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.BQzlnFfq.js → diagram-5BDNPKRD.ChsausbG.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.DkgqqZMz.js → diagram-G4DWMVQ6.3XsptNWj.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.DIT8L7H_.js → diagram-MMDJMWI5.DPA9Dk_P.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.3xLPZWGJ.js → diagram-TYMM5635.BVswXWrB.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.5_IHz8jF.js → erDiagram-SMLLAGMA.BSak5OSP.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.BGUCXz8A.js → flowDiagram-DWJPFMVM.CQgN4TTz.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.DbfFavS1.js → ganttDiagram-T4ZO3ILL.GrT0kA4a.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.D2yKdeNW.js → gitGraphDiagram-UUTBAWPF.CdS7Ucll.js} +1 -1
- package/dist/docs/assets/chunks/{graph.CSCxwHba.js → graph.BVqKRmRo.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.FDeb6xHY.js → infoDiagram-42DDH7IO.C3C9FRto.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DbeYs9VL.js → ishikawaDiagram-UXIWVN3A.2FuAh_Zj.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CWjKINpx.js → journeyDiagram-VCZTEJTY.CaHMfK4b.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.B4FrAlwz.js → kanban-definition-6JOO6SKY.CjhIUwcA.js} +1 -1
- package/dist/docs/assets/chunks/{layout.DFGxQ9ab.js → layout.CGU3gfSf.js} +1 -1
- package/dist/docs/assets/chunks/{linear.BmjZ-G59.js → linear.DaihpW_n.js} +1 -1
- package/dist/docs/assets/chunks/{min.DZSxulMW.js → min.BS-j8kHQ.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.CHLi3-aN.js → mindmap-definition-QFDTVHPH.BVJ1Bbnk.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DteG-CkU.js → pieDiagram-DEJITSTG.Cz1WIv9r.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.D458ipN3.js → quadrantDiagram-34T5L4WZ.DKLFxcjy.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.DcFgUxst.js → requirementDiagram-MS252O5E.BHegiK7x.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.BwQAMmSA.js → sankeyDiagram-XADWPNL6.DYkY6yPc.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.B_Xdsrh9.js → sequenceDiagram-FGHM5R23.DYQ1QUrI.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.CdfDW6-C.js → stateDiagram-FHFEXIEX.Iru8BsFo.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.BYXl4LW6.js +1 -0
- package/dist/docs/assets/chunks/{theme.sfdL3srp.js → theme.DaplWQhQ.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.56-4hXaC.js → timeline-definition-GMOUNBTQ.BwFA8hiX.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CvZSQBO7.js → vennDiagram-DHZGUBPP.CZ60W1C_.js} +1 -1
- package/dist/docs/assets/chunks/{wardley-RL74JXVD.C9qc8k39.js → wardley-RL74JXVD.iXazD3Z7.js} +1 -1
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.D9s0nihi.js → wardleyDiagram-NUSXRM2D.B69D2r8-.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.BVJSpYrC.js → xychartDiagram-5P7HB3ND.CLPZEIU9.js} +1 -1
- package/dist/docs/assets/{deployment.md.BdqTiGdc.js → deployment.md.BYuEcDBv.js} +2 -2
- package/dist/docs/assets/{guides_bitbucket.md.BB6fqD-M.js → guides_bitbucket.md.CKUayYtD.js} +3 -3
- package/dist/docs/assets/{guides_bitbucket.md.BB6fqD-M.lean.js → guides_bitbucket.md.CKUayYtD.lean.js} +1 -1
- package/dist/docs/assets/{guides_github.md.Cr1Xlf-m.js → guides_github.md.TuNiZAOQ.js} +4 -4
- package/dist/docs/assets/{guides_github.md.Cr1Xlf-m.lean.js → guides_github.md.TuNiZAOQ.lean.js} +1 -1
- package/dist/docs/assets/{guides_gitlab.md.CMpmFi4M.js → guides_gitlab.md.CtNI4fSH.js} +4 -4
- package/dist/docs/assets/{guides_gitlab.md.CMpmFi4M.lean.js → guides_gitlab.md.CtNI4fSH.lean.js} +1 -1
- package/dist/docs/assets/guides_migrate.md.sCAvvlC6.js +7 -0
- package/dist/docs/assets/guides_migrate.md.sCAvvlC6.lean.js +1 -0
- package/dist/docs/assets/{reference_cli.md.GwugN3n-.js → reference_cli.md.dYCAL2lB.js} +4 -3
- package/dist/docs/assets/reference_cli.md.dYCAL2lB.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.x-GBa7wN.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.Bscj6ODe.lean.js → troubleshooting.md.x-GBa7wN.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +37 -37
- package/dist/docs/building-with-agents.md +2 -0
- package/dist/docs/deployment.html +38 -38
- package/dist/docs/deployment.md +7 -0
- package/dist/docs/evals.html +36 -36
- package/dist/docs/guides/agent-to-agent.html +35 -35
- package/dist/docs/guides/bitbucket.html +38 -38
- package/dist/docs/guides/bitbucket.md +9 -1
- package/dist/docs/guides/cloud-agents.html +35 -35
- package/dist/docs/guides/convert-automation.html +35 -35
- package/dist/docs/guides/github.html +39 -39
- package/dist/docs/guides/github.md +20 -4
- package/dist/docs/guides/gitlab.html +38 -38
- package/dist/docs/guides/gitlab.md +9 -1
- package/dist/docs/guides/grokbot-agents.html +35 -35
- package/dist/docs/guides/hooks.html +35 -35
- package/dist/docs/guides/improve.html +35 -35
- package/dist/docs/guides/jev.html +35 -35
- package/dist/docs/guides/mcp-oauth.html +35 -35
- package/dist/docs/guides/migrate.html +66 -0
- package/dist/docs/guides/migrate.md +122 -0
- package/dist/docs/guides/opentelemetry.html +35 -35
- package/dist/docs/guides/slack.html +35 -35
- package/dist/docs/guides/webhooks.html +35 -35
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +35 -35
- package/dist/docs/index.html +35 -35
- package/dist/docs/llms-full.txt +214 -6
- package/dist/docs/llms.txt +1 -0
- package/dist/docs/quickstart.html +35 -35
- package/dist/docs/reference/agent-config.html +35 -35
- package/dist/docs/reference/artifacts.html +35 -35
- package/dist/docs/reference/channels.html +35 -35
- package/dist/docs/reference/cli.html +39 -38
- package/dist/docs/reference/cli.md +39 -0
- package/dist/docs/reference/connections.html +35 -35
- package/dist/docs/reference/evals.html +35 -35
- package/dist/docs/reference/extensions.html +35 -35
- package/dist/docs/reference/hooks.html +35 -35
- package/dist/docs/reference/http-api.html +35 -35
- package/dist/docs/reference/instructions.html +35 -35
- package/dist/docs/reference/playground.html +35 -35
- package/dist/docs/reference/project-layout.html +35 -35
- package/dist/docs/reference/prompt.html +35 -35
- package/dist/docs/reference/schedules.html +35 -35
- package/dist/docs/reference/sessions.html +35 -35
- package/dist/docs/reference/skills.html +35 -35
- package/dist/docs/reference/subagents.html +35 -35
- package/dist/docs/reference/tools.html +35 -35
- package/dist/docs/templates/agentic-owners.html +35 -35
- package/dist/docs/templates/grokbot-agents.html +35 -35
- package/dist/docs/templates/security-reviewer.html +35 -35
- package/dist/docs/templates/thermo-quality-review.html +35 -35
- package/dist/docs/templates/thermo-review.html +35 -35
- package/dist/docs/templates/triage.html +35 -35
- package/dist/docs/troubleshooting.html +36 -36
- package/dist/docs/troubleshooting.md +1 -0
- package/dist/evals/assertions.js +20 -34
- package/dist/evals/expect.js +3 -6
- package/dist/evals/judge.js +5 -8
- package/dist/evals/loaders.js +45 -62
- package/dist/evals/matchers.js +2 -3
- package/dist/evals/reporters.js +43 -67
- package/dist/evals/results.js +1 -1
- package/dist/evals/run-facts.js +5 -6
- package/dist/evals.js +27 -15
- package/dist/extensions/cursor-cloud-agents/extension.js +4 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +100 -126
- package/dist/extensions/cursor-cloud-agents/lib/fleet.js +22 -38
- package/dist/extensions/cursor-cloud-agents/lib/repos.js +8 -10
- package/dist/extensions/cursor-cloud-agents/lib/transcript.js +2 -3
- package/dist/extensions/cursor-cloud-agents/lib/watch.js +52 -66
- package/dist/extensions/cursor-cloud-agents/reminders/cloud-agent-stop-watch.js +29 -40
- package/dist/extensions/cursor-cloud-agents/tools/cancel.js +6 -17
- package/dist/extensions/cursor-cloud-agents/tools/dump.js +25 -36
- package/dist/extensions/cursor-cloud-agents/tools/get.js +3 -14
- package/dist/extensions/cursor-cloud-agents/tools/launch.js +13 -21
- package/dist/extensions/cursor-cloud-agents/tools/list.js +8 -19
- package/dist/extensions/cursor-cloud-agents/tools/reply.js +5 -16
- package/dist/extensions/cursor-grokbot-agents/extension.js +4 -1
- package/dist/extensions/cursor-grokbot-agents/lib/agents.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/backend.js +53 -73
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.js +10 -23
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.js +112 -132
- package/dist/extensions/cursor-grokbot-agents/lib/lock.js +1 -2
- package/dist/extensions/cursor-grokbot-agents/tools/ask.js +5 -16
- package/dist/extensions/cursor-grokbot-agents/tools/check.js +4 -15
- package/dist/extensions/cursor-grokbot-agents/tools/interrupt.js +2 -13
- package/dist/extensions/cursor-grokbot-agents/tools/list.js +11 -23
- package/dist/extensions/jev/extension.js +3 -3
- package/dist/extensions/jev/lib/evaluate.js +43 -60
- package/dist/extensions/jev/tools/evaluate.js +6 -17
- package/dist/extensions/slack-communication/tools/post-file.js +1 -1
- package/dist/extensions.js +3 -5
- package/dist/files-backends/cursor-hosted.js +504 -523
- package/dist/files-backends/local-fs.js +72 -134
- package/dist/files.js +3 -3
- package/dist/filesystem.js +562 -861
- package/dist/index.js +16 -35
- package/dist/internal/advertise-tools.js +74 -86
- package/dist/internal/artifacts-store.js +298 -361
- package/dist/internal/as-of.js +2 -4
- package/dist/internal/authored-alias-hooks.js +6 -4
- package/dist/internal/authored-loaders.js +37 -52
- package/dist/internal/bounded-int.js +1 -2
- package/dist/internal/bounded.js +13 -24
- package/dist/internal/brand.js +1 -1
- package/dist/internal/browser-origin-guard.js +4 -4
- package/dist/internal/builtin-tools/artifacts.js +15 -27
- package/dist/internal/builtin-tools/index.js +2 -3
- package/dist/internal/builtin-tools/reminders.js +33 -52
- package/dist/internal/channel-architecture.d.ts +21 -0
- package/dist/internal/channel-architecture.d.ts.map +1 -0
- package/dist/internal/channel-architecture.js +41 -0
- package/dist/internal/channel-dispatch.js +3 -4
- package/dist/internal/channel-route-dispatch.js +40 -51
- package/dist/internal/channel-state.js +1 -1
- package/dist/internal/chat-client.js +319 -340
- package/dist/internal/cli-ax.js +1262 -1294
- package/dist/internal/cli-bitbucket.js +244 -272
- package/dist/internal/cli-convert-automation.js +137 -151
- package/dist/internal/cli-cursor.js +126 -147
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +1457 -1507
- package/dist/internal/cli-docs.js +130 -147
- package/dist/internal/cli-github.js +437 -476
- package/dist/internal/cli-gitlab.js +259 -288
- package/dist/internal/cli-images.js +266 -334
- package/dist/internal/cli-manifest.js +25 -37
- package/dist/internal/cli-mcp-oauth.js +228 -247
- package/dist/internal/cli-mcp.js +358 -383
- package/dist/internal/cli-migrate.js +73 -90
- package/dist/internal/cli-skills.js +35 -47
- package/dist/internal/cli-slack-manual.d.ts +0 -1
- package/dist/internal/cli-slack-manual.d.ts.map +1 -1
- package/dist/internal/cli-slack-manual.js +175 -204
- package/dist/internal/cli-slack.d.ts +1 -1
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +416 -456
- package/dist/internal/cloud-merge.js +7 -3
- package/dist/internal/cloud-turn-cost.js +8 -1
- package/dist/internal/connection-env.js +5 -6
- package/dist/internal/continuation-channel.js +10 -7
- package/dist/internal/continuation-identity.js +85 -67
- package/dist/internal/conversation-mirror.js +112 -131
- package/dist/internal/convert-automation/convert-workflow.js +21 -31
- package/dist/internal/cron.js +3 -3
- package/dist/internal/cursor/account-mcp.js +147 -146
- package/dist/internal/cursor/backend-client.js +290 -320
- package/dist/internal/cursor/bound-secret-file.js +3 -3
- package/dist/internal/cursor/credentials.js +127 -142
- package/dist/internal/cursor/cursor-api-transport.js +4 -8
- package/dist/internal/cursor/github-credentials.js +91 -108
- package/dist/internal/cursor/hosted-bound-secrets.js +3 -4
- package/dist/internal/cursor/hosted-deployment-secrets.js +1 -1
- package/dist/internal/cursor/hosted-store-secrets.js +5 -9
- package/dist/internal/cursor/session-token.js +36 -48
- package/dist/internal/cursor/store-api-client.js +77 -92
- package/dist/internal/cursor-account-mcp-auth.js +132 -149
- package/dist/internal/cursor-agent-template.js +1 -1
- package/dist/internal/cursor-deployment-relay.js +33 -54
- package/dist/internal/cursor-event-relay.js +65 -59
- package/dist/internal/cursor-relay-core.js +258 -286
- package/dist/internal/deferred-channel-session.js +3 -12
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +413 -475
- package/dist/internal/deploy-manifest.d.ts +17 -0
- package/dist/internal/deploy-manifest.d.ts.map +1 -1
- package/dist/internal/deploy-manifest.js +71 -21
- package/dist/internal/deploy-source.js +31 -43
- package/dist/internal/discovery/agent-config.js +45 -59
- package/dist/internal/discovery/agent.js +276 -280
- package/dist/internal/discovery/channels.js +67 -80
- package/dist/internal/discovery/connections.js +286 -296
- package/dist/internal/discovery/context.js +2 -13
- package/dist/internal/discovery/cursor-plugin.js +223 -259
- package/dist/internal/discovery/extension-overlay.js +104 -131
- package/dist/internal/discovery/extensions.js +276 -281
- package/dist/internal/discovery/fs.js +56 -79
- package/dist/internal/discovery/hooks.js +39 -50
- package/dist/internal/discovery/info.js +17 -19
- package/dist/internal/discovery/instructions.js +58 -71
- package/dist/internal/discovery/modules.js +45 -58
- package/dist/internal/discovery/project.d.ts.map +1 -1
- package/dist/internal/discovery/project.js +192 -215
- package/dist/internal/discovery/reminders.js +41 -52
- package/dist/internal/discovery/runtime.js +1 -1
- package/dist/internal/discovery/schedules.js +71 -82
- package/dist/internal/discovery/seed-files.js +21 -32
- package/dist/internal/discovery/services.js +74 -96
- package/dist/internal/discovery/skills.js +77 -94
- package/dist/internal/discovery/subagent.js +79 -95
- package/dist/internal/discovery/tools.js +12 -23
- package/dist/internal/distribution.js +2 -2
- package/dist/internal/docs-site.js +30 -45
- package/dist/internal/duration.js +1 -1
- package/dist/internal/env-file.js +48 -64
- package/dist/internal/eval-judge-model.js +17 -28
- package/dist/internal/eval-run-store.js +265 -254
- package/dist/internal/eval-runner.d.ts +8 -0
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +406 -408
- package/dist/internal/eval-transport.d.ts +24 -0
- package/dist/internal/eval-transport.d.ts.map +1 -0
- package/dist/internal/eval-transport.js +22 -0
- package/dist/internal/evals-client.js +242 -246
- package/dist/internal/event-log.js +72 -120
- package/dist/internal/event-mapper.js +30 -31
- package/dist/internal/factory-resource-channel.js +16 -30
- package/dist/internal/filesystem/errors.js +6 -6
- package/dist/internal/filesystem/format.js +10 -13
- package/dist/internal/filesystem/merge.js +52 -94
- package/dist/internal/filesystem/nearest.js +15 -27
- package/dist/internal/filesystem/scratch.js +65 -85
- package/dist/internal/filesystem/tools.js +221 -241
- package/dist/internal/filesystem/walk.js +76 -143
- package/dist/internal/framework-file-storage.js +118 -139
- package/dist/internal/framework-storage-selection.js +21 -13
- package/dist/internal/frontmatter.js +4 -6
- package/dist/internal/github-fanout.js +50 -64
- package/dist/internal/guest-network.js +96 -109
- package/dist/internal/handleAgentServeTrigger.js +121 -126
- package/dist/internal/host-files.js +73 -88
- package/dist/internal/host-kv.js +21 -36
- package/dist/internal/host-otel.js +22 -19
- package/dist/internal/host-platforms.js +49 -63
- package/dist/internal/hosted-catch-protocol.d.ts +1 -0
- package/dist/internal/hosted-catch-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-catch-protocol.js +1 -0
- package/dist/internal/hosted-catch.d.ts +5 -3
- package/dist/internal/hosted-catch.d.ts.map +1 -1
- package/dist/internal/hosted-catch.js +84 -93
- package/dist/internal/hosted-delivery-protocol.js +32 -8
- package/dist/internal/hosted-delivery.d.ts +13 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +614 -584
- package/dist/internal/hosted-eval-cases.d.ts +21 -0
- package/dist/internal/hosted-eval-cases.d.ts.map +1 -0
- package/dist/internal/hosted-eval-cases.js +162 -0
- package/dist/internal/hosted-execution-diag.js +38 -30
- package/dist/internal/hosted-execution-flush.js +75 -66
- package/dist/internal/hosted-execution-latency.js +16 -8
- package/dist/internal/hosted-managed-automation.js +2 -2
- package/dist/internal/hosting.js +2 -3
- package/dist/internal/http-channel-define.js +4 -1
- package/dist/internal/http-channel.js +101 -112
- package/dist/internal/http-control-plane-session.d.ts +18 -1
- package/dist/internal/http-control-plane-session.d.ts.map +1 -1
- package/dist/internal/http-control-plane-session.js +66 -32
- package/dist/internal/incoming-headers-to-fetch.js +1 -2
- package/dist/internal/init-interview.js +73 -93
- package/dist/internal/init-project.js +182 -214
- package/dist/internal/init-scaffold.js +10 -21
- package/dist/internal/inline-stdio-mcp.js +80 -86
- package/dist/internal/install-cursor-skills.js +231 -273
- package/dist/internal/legacy-command-guard.js +18 -31
- package/dist/internal/listen-port.js +34 -45
- package/dist/internal/local-control-plane.js +293 -307
- package/dist/internal/local-env.js +1 -1
- package/dist/internal/local-ingress.js +15 -9
- package/dist/internal/log-ring.js +1 -2
- package/dist/internal/logs-client.js +207 -227
- package/dist/internal/map-pool.js +24 -38
- package/dist/internal/mcp-endpoint.js +204 -180
- package/dist/internal/mcp-host.js +165 -168
- package/dist/internal/mcp-oauth-on-demand.js +170 -207
- package/dist/internal/mcp-oauth-persist.js +15 -29
- package/dist/internal/mcp-oauth.js +209 -266
- package/dist/internal/named-webhook-secret.d.ts +39 -0
- package/dist/internal/named-webhook-secret.d.ts.map +1 -0
- package/dist/internal/named-webhook-secret.js +47 -0
- package/dist/internal/open-browser.js +2 -3
- package/dist/internal/otel/collector.js +104 -68
- package/dist/internal/otel/config.js +24 -37
- package/dist/internal/otel/http.js +5 -7
- package/dist/internal/otel/mcp.js +3 -12
- package/dist/internal/otel/runtime.js +69 -83
- package/dist/internal/package-inline-stdio.js +57 -65
- package/dist/internal/peer-connections.js +9 -5
- package/dist/internal/platform-schedule-sync.js +39 -54
- package/dist/internal/platform-timers.js +176 -210
- package/dist/internal/playground/static.js +1 -2
- package/dist/internal/playground/toolchain.js +37 -53
- package/dist/internal/playground-proxy.js +230 -270
- package/dist/internal/process-memory-telemetry.js +33 -51
- package/dist/internal/prompt-context.js +3 -6
- package/dist/internal/reminder-control-plane-protocol.js +46 -13
- package/dist/internal/reminder-runner.js +770 -785
- package/dist/internal/reminder-schedule.js +1 -1
- package/dist/internal/reminder-store.js +57 -78
- package/dist/internal/request-error-status.js +1 -3
- package/dist/internal/request-headers.js +2 -2
- package/dist/internal/resolve-prod-target.js +119 -135
- package/dist/internal/resolved-connections.js +16 -6
- package/dist/internal/run-client.js +221 -229
- package/dist/internal/runtime-dispatch-runner.js +18 -43
- package/dist/internal/schedule-runner.js +49 -58
- package/dist/internal/scm/pr-url.js +7 -6
- package/dist/internal/sdk-runner.js +388 -363
- package/dist/internal/serve-restart.js +26 -39
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +1283 -1244
- package/dist/internal/session-cost.js +7 -9
- package/dist/internal/session-engine.d.ts +3 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +2801 -2777
- package/dist/internal/session-links.js +12 -16
- package/dist/internal/session-run-log.js +134 -82
- package/dist/internal/session-store.js +133 -164
- package/dist/internal/sessions-client.js +97 -118
- package/dist/internal/skill-catalog.js +18 -23
- package/dist/internal/skills-sync.js +16 -30
- package/dist/internal/slack-provision-client.js +90 -116
- package/dist/internal/start-log-store.js +48 -67
- package/dist/internal/steering.js +1 -2
- package/dist/internal/storage-coordinator.js +160 -196
- package/dist/internal/store-mirror.js +16 -30
- package/dist/internal/stream-progress.js +6 -8
- package/dist/internal/terminal-style.js +3 -4
- package/dist/internal/testing/scm-continuation-fixtures.js +6 -2
- package/dist/internal/testing/slack-continuation-fixtures.d.ts +26 -0
- package/dist/internal/testing/slack-continuation-fixtures.d.ts.map +1 -0
- package/dist/internal/testing/slack-continuation-fixtures.js +136 -0
- package/dist/internal/tool-catalog.js +11 -5
- package/dist/internal/tool-result.js +1 -1
- package/dist/internal/trajectory.js +19 -22
- package/dist/internal/turn-cost.js +52 -62
- package/dist/internal/turn-governor.js +5 -8
- package/dist/internal/turn-lease-store.js +85 -105
- package/dist/internal/turn-outbox.js +28 -43
- package/dist/internal/update-check.js +231 -259
- package/dist/internal/v2-hosting.js +1 -2
- package/dist/internal/workspace-sync.js +25 -41
- package/dist/internal/workspace.js +111 -139
- package/dist/kv/memory-kv.js +27 -51
- package/dist/memory.js +106 -148
- package/dist/otel.js +5 -8
- package/dist/playground/assets/{index-Co4CUVTQ.js → index-Be0-1hw2.js} +45 -45
- package/dist/playground/assets/index-Clz6uHj9.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/prompt.js +2 -4
- package/dist/storage-backends/cursor-hosted-v2.js +53 -83
- package/dist/storage-backends/cursor-hosted.js +105 -145
- package/dist/storage-backends/file-kv.js +100 -128
- package/dist/storage-protocol.js +3 -5
- package/dist/storage.js +17 -26
- package/dist/types.d.ts +68 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +20 -18
- package/docs/building-with-agents.md +2 -0
- package/docs/deployment.md +7 -0
- package/docs/guides/bitbucket.md +9 -1
- package/docs/guides/github.md +20 -4
- package/docs/guides/gitlab.md +9 -1
- package/docs/guides/migrate.md +127 -0
- package/docs/reference/cli.md +39 -0
- package/docs/troubleshooting.md +1 -0
- package/package.json +1 -1
- package/skills/debug/SKILL.md +1 -0
- package/skills/github/SKILL.md +23 -0
- package/skills/migrate-v2/SKILL.md +51 -10
- package/dist/docs/assets/chunks/@localSearchIndexroot.BJ8UZggu.js +0 -1
- package/dist/docs/assets/chunks/channel.BTJ5J9FI.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.D4BZ3cVV.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.D4BZ3cVV.js +0 -1
- package/dist/docs/assets/chunks/clone.62tX-O-1.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.DkTs1aEU.js +0 -1
- package/dist/docs/assets/reference_cli.md.GwugN3n-.lean.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Bscj6ODe.js +0 -1
- package/dist/playground/assets/index-C1g_PTTZ.css +0 -1
- /package/dist/docs/assets/{building-with-agents.md.BPjPFxFg.lean.js → building-with-agents.md.Df87rAe1.lean.js} +0 -0
- /package/dist/docs/assets/{deployment.md.BdqTiGdc.lean.js → deployment.md.BYuEcDBv.lean.js} +0 -0
|
@@ -5,15 +5,6 @@
|
|
|
5
5
|
* settings; cloud agents use Cursor cloud (`bc-…` ids) with optional
|
|
6
6
|
* `cloud` options from `defineAgent`.
|
|
7
7
|
*/
|
|
8
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
9
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
10
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
11
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
12
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
13
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
14
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15
|
-
});
|
|
16
|
-
};
|
|
17
8
|
import { mkdir } from "node:fs/promises";
|
|
18
9
|
import { Agent, Cursor, createAgentPlatform, } from "@cursor/sdk";
|
|
19
10
|
import { SqliteLocalAgentStore } from "@cursor/sdk/sqlite";
|
|
@@ -35,9 +26,7 @@ export const SERVE_WORKSPACE_SCAN_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
|
35
26
|
* not call `Cursor.configure`" and leave the SDK at its 20s editor default.
|
|
36
27
|
*/
|
|
37
28
|
export function resolveServeWorkspaceScanCacheTtlMs(args) {
|
|
38
|
-
|
|
39
|
-
var _b;
|
|
40
|
-
const raw = (_a = ((_b = args.env) !== null && _b !== void 0 ? _b : process.env).CURSOR_RIPWALK_CACHE_TTL_MS) === null || _a === void 0 ? void 0 : _a.trim();
|
|
29
|
+
const raw = (args.env ?? process.env).CURSOR_RIPWALK_CACHE_TTL_MS?.trim();
|
|
41
30
|
if (raw !== undefined && raw !== "") {
|
|
42
31
|
const parsed = Number(raw);
|
|
43
32
|
if (Number.isFinite(parsed) && parsed > 0) {
|
|
@@ -155,12 +144,11 @@ function modelSettingLabel(model) {
|
|
|
155
144
|
}
|
|
156
145
|
/** Primary model, then authored fallbacks. No fallbacks keeps today's single attempt. */
|
|
157
146
|
function modelAttemptChain(request) {
|
|
158
|
-
|
|
159
|
-
const fallbacks = (_a = request.modelFallbacks) !== null && _a !== void 0 ? _a : [];
|
|
147
|
+
const fallbacks = request.modelFallbacks ?? [];
|
|
160
148
|
if (fallbacks.length === 0) {
|
|
161
149
|
return [request.model];
|
|
162
150
|
}
|
|
163
|
-
return [
|
|
151
|
+
return [request.model ?? DEFAULT_MODEL, ...fallbacks];
|
|
164
152
|
}
|
|
165
153
|
/**
|
|
166
154
|
* A rejected create may already have stored the agent id. Later attempts
|
|
@@ -170,17 +158,21 @@ function modelAttemptChain(request) {
|
|
|
170
158
|
* on create: resuming the framework session id is not a cloud agent.
|
|
171
159
|
*/
|
|
172
160
|
function modelAttemptRequest(request, model, attempt) {
|
|
173
|
-
var _a;
|
|
174
161
|
if (attempt === 0) {
|
|
175
|
-
return model === request.model ? request :
|
|
162
|
+
return model === request.model ? request : { ...request, model };
|
|
176
163
|
}
|
|
177
|
-
const persistedId =
|
|
164
|
+
const persistedId = request.sdkAgentId ?? request.sessionId;
|
|
178
165
|
if (request.runtime === "cloud" &&
|
|
179
166
|
request.isFirstTurn &&
|
|
180
167
|
!isServerMintedCloudAgentId(persistedId)) {
|
|
181
|
-
return
|
|
182
|
-
}
|
|
183
|
-
return
|
|
168
|
+
return { ...request, model };
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
...request,
|
|
172
|
+
model,
|
|
173
|
+
isFirstTurn: false,
|
|
174
|
+
sdkAgentId: persistedId,
|
|
175
|
+
};
|
|
184
176
|
}
|
|
185
177
|
export class CursorSdkRunner {
|
|
186
178
|
constructor(options = {}) {
|
|
@@ -197,49 +189,46 @@ export class CursorSdkRunner {
|
|
|
197
189
|
this.log(`[bdk] workspace scan cache ttl=${options.workspaceScanCacheTtlMs}ms`);
|
|
198
190
|
}
|
|
199
191
|
}
|
|
200
|
-
runTurn(request) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
attempt === models.length - 1) {
|
|
225
|
-
return outcome;
|
|
226
|
-
}
|
|
227
|
-
this.logModelFallback(request.sessionId, model, models[attempt + 1], outcome.errorMessage);
|
|
192
|
+
async runTurn(request) {
|
|
193
|
+
// Fail closed: this runner only knows the Cursor SDK's local and cloud
|
|
194
|
+
// harnesses. A grokbot turn reaching it means the serve wiring skipped
|
|
195
|
+
// the Grok Bot runner — running it on the local harness would silently
|
|
196
|
+
// swap the box (and the SendToUser contract) out from under the agent.
|
|
197
|
+
if (request.runtime === "grokbot") {
|
|
198
|
+
throw new Error(`Session ${request.sessionId} is a grokbot turn, which the local and cloud turn runner cannot execute. Serve must route grokbot turns to the Grok Bot runner.`);
|
|
199
|
+
}
|
|
200
|
+
const models = modelAttemptChain(request);
|
|
201
|
+
let lastError;
|
|
202
|
+
for (let attempt = 0; attempt < models.length; attempt++) {
|
|
203
|
+
const model = models[attempt];
|
|
204
|
+
let streamed = false;
|
|
205
|
+
const attemptRequest = modelAttemptRequest(request, model, attempt);
|
|
206
|
+
try {
|
|
207
|
+
const outcome = await this.runTurnWithTransportRetry(attemptRequest, () => {
|
|
208
|
+
streamed = true;
|
|
209
|
+
});
|
|
210
|
+
if (outcome.status !== "error" ||
|
|
211
|
+
streamed ||
|
|
212
|
+
request.signal?.aborted === true ||
|
|
213
|
+
!shouldFallbackToNextModel(outcome.errorMessage, outcome.errorCode) ||
|
|
214
|
+
attempt === models.length - 1) {
|
|
215
|
+
return outcome;
|
|
228
216
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
this.logModelFallback(request.sessionId, model, models[attempt + 1], message);
|
|
217
|
+
this.logModelFallback(request.sessionId, model, models[attempt + 1], outcome.errorMessage);
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
lastError = error;
|
|
221
|
+
if (streamed ||
|
|
222
|
+
request.signal?.aborted === true ||
|
|
223
|
+
!shouldFallbackToNextModelOnError(error) ||
|
|
224
|
+
attempt === models.length - 1) {
|
|
225
|
+
throw error;
|
|
239
226
|
}
|
|
227
|
+
const message = error instanceof Error ? error.message : undefined;
|
|
228
|
+
this.logModelFallback(request.sessionId, model, models[attempt + 1], message);
|
|
240
229
|
}
|
|
241
|
-
|
|
242
|
-
|
|
230
|
+
}
|
|
231
|
+
throw lastError;
|
|
243
232
|
}
|
|
244
233
|
/**
|
|
245
234
|
* One model attempt, plus the existing in-place transport retry (expired
|
|
@@ -247,172 +236,179 @@ export class CursorSdkRunner {
|
|
|
247
236
|
* fallback is the caller's job: this returns the error outcome when a
|
|
248
237
|
* fresh handle cannot fix it.
|
|
249
238
|
*/
|
|
250
|
-
runTurnWithTransportRetry(request, onStreamed) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
239
|
+
async runTurnWithTransportRetry(request, onStreamed) {
|
|
240
|
+
let sawUpdate = false;
|
|
241
|
+
const tracked = {
|
|
242
|
+
...request,
|
|
243
|
+
onUpdate: update => {
|
|
244
|
+
sawUpdate = true;
|
|
245
|
+
onStreamed();
|
|
246
|
+
return request.onUpdate(update);
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
const outcome = await this.runTurnAttempt(tracked);
|
|
250
|
+
if (outcome.status !== "error" || sawUpdate || request.signal?.aborted === true) {
|
|
251
|
+
return outcome;
|
|
252
|
+
}
|
|
253
|
+
const reason = retryReason(outcome.errorMessage, request.isFirstTurn);
|
|
254
|
+
if (reason === undefined) {
|
|
255
|
+
return outcome;
|
|
256
|
+
}
|
|
257
|
+
// Log the original error even when the retry succeeds so the expiry
|
|
258
|
+
// still shows up in Datadog.
|
|
259
|
+
this.log(`[bdk] session ${request.sessionId}: ${reason}: ${outcome.errorMessage}; retrying the turn`);
|
|
260
|
+
try {
|
|
261
|
+
return await this.runTurnAttempt(tracked);
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return outcome;
|
|
265
|
+
}
|
|
277
266
|
}
|
|
278
267
|
logModelFallback(sessionId, from, to, message) {
|
|
279
|
-
this.log(`[bdk] session ${sessionId}: cannot use model ${modelSettingLabel(from)}; retrying on ${modelSettingLabel(to)}: ${message
|
|
280
|
-
}
|
|
281
|
-
runTurnAttempt(request) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
268
|
+
this.log(`[bdk] session ${sessionId}: cannot use model ${modelSettingLabel(from)}; retrying on ${modelSettingLabel(to)}: ${message ?? "model unavailable"}`);
|
|
269
|
+
}
|
|
270
|
+
async runTurnAttempt(request) {
|
|
271
|
+
const agentPromise = this.getAgent(request);
|
|
272
|
+
try {
|
|
273
|
+
const agent = await agentPromise;
|
|
274
|
+
const sendMessage = request.images !== undefined && request.images.length > 0
|
|
275
|
+
? {
|
|
276
|
+
text: request.prompt,
|
|
277
|
+
images: request.images.map(image => ({
|
|
278
|
+
data: image.data,
|
|
279
|
+
mimeType: image.mimeType,
|
|
280
|
+
})),
|
|
281
|
+
}
|
|
282
|
+
: request.prompt;
|
|
283
|
+
const run = await agent.send(sendMessage, {
|
|
284
|
+
onDelta: async ({ update }) => {
|
|
285
|
+
try {
|
|
286
|
+
await request.onUpdate(update);
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
// Stream mapping must never reject into the SDK transport.
|
|
293
290
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
catch (_b) {
|
|
300
|
-
// Stream mapping must never reject into the SDK transport.
|
|
301
|
-
}
|
|
302
|
-
}) }, (request.runtime === "local" && request.perSendMcpServers === true
|
|
291
|
+
},
|
|
292
|
+
// The SDK builds this send's MCP session from exactly this set, so
|
|
293
|
+
// a turn always runs on the headers the engine evaluated for it —
|
|
294
|
+
// never on the ones a previous turn opened the cached handle with.
|
|
295
|
+
...(request.runtime === "local" && request.perSendMcpServers === true
|
|
303
296
|
? { mcpServers: request.mcpServers }
|
|
304
|
-
: {})
|
|
297
|
+
: {}),
|
|
298
|
+
...(request.runtime === "local"
|
|
305
299
|
? {
|
|
306
|
-
local:
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const signal = request.signal;
|
|
314
|
-
const onAbort = () => {
|
|
315
|
-
void run.cancel().catch(() => { });
|
|
316
|
-
};
|
|
317
|
-
if (signal !== undefined) {
|
|
318
|
-
if (signal.aborted) {
|
|
319
|
-
onAbort();
|
|
320
|
-
}
|
|
321
|
-
else {
|
|
322
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
// Cloud + envVars: server mints the real `bc-…` id during createAgent
|
|
326
|
-
// inside the first send. Bind only after that so we never persist/print
|
|
327
|
-
// the provisional client-seeded id.
|
|
328
|
-
if (request.onSdkAgentId !== undefined) {
|
|
329
|
-
yield request.onSdkAgentId(agent.agentId);
|
|
330
|
-
}
|
|
331
|
-
// Readable on the handle as soon as send resolves, long before wait().
|
|
332
|
-
if (request.onRequestId !== undefined &&
|
|
333
|
-
run.requestId !== undefined &&
|
|
334
|
-
run.requestId !== "") {
|
|
335
|
-
yield request.onRequestId(run.requestId);
|
|
336
|
-
}
|
|
337
|
-
this.activeRuns.set(request.sessionId, run);
|
|
338
|
-
try {
|
|
339
|
-
const result = yield run.wait();
|
|
340
|
-
let outcome = toTurnOutcome(result);
|
|
341
|
-
if (outcome.status === "error") {
|
|
342
|
-
// An error result usually means the handle's transport is poisoned
|
|
343
|
-
// — most often a cached access token that aged past its 60-minute
|
|
344
|
-
// lifetime and gets replayed on every request (stream failures
|
|
345
|
-
// bypass the transport's 401 retry). Retire the handle so the next
|
|
346
|
-
// attempt resumes the conversation from the store on a fresh
|
|
347
|
-
// transport instead of failing every turn until a restart.
|
|
348
|
-
this.evictAgent(request.sessionId, agentPromise);
|
|
349
|
-
}
|
|
350
|
-
else if (request.runtime === "cloud" &&
|
|
351
|
-
outcome.status === "finished" &&
|
|
352
|
-
usageTokenSum(outcome.usage) <= 0 &&
|
|
353
|
-
result.id !== "") {
|
|
354
|
-
// Cloud `wait()` drops usage after stream reconnect / getRun replay,
|
|
355
|
-
// or returns an all-zero stub. `getUsage` still has the run's tokens
|
|
356
|
-
// (eventually); without them traces never record an estimated cost.
|
|
357
|
-
outcome = yield fillMissingCloudUsage(agent, result.id, outcome);
|
|
300
|
+
local: {
|
|
301
|
+
customTools: request.customTools,
|
|
302
|
+
// Follow-up turns expire any run still marked active on the
|
|
303
|
+
// agent (a preempted or crash-wedged run) so this send is not
|
|
304
|
+
// rejected with "already has active run".
|
|
305
|
+
...(request.forceExpireActiveRun === true ? { force: true } : {}),
|
|
306
|
+
},
|
|
358
307
|
}
|
|
359
|
-
|
|
308
|
+
: {}),
|
|
309
|
+
});
|
|
310
|
+
// A follow-up can preempt this turn: cancelling tears down execution and
|
|
311
|
+
// marks the SDK run terminal so the next send is admitted cleanly. The
|
|
312
|
+
// signal may already be aborted if the preempt landed while send() was
|
|
313
|
+
// still creating the run.
|
|
314
|
+
const signal = request.signal;
|
|
315
|
+
const onAbort = () => {
|
|
316
|
+
void run.cancel().catch(() => { });
|
|
317
|
+
};
|
|
318
|
+
if (signal !== undefined) {
|
|
319
|
+
if (signal.aborted) {
|
|
320
|
+
onAbort();
|
|
360
321
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
this.activeRuns.delete(request.sessionId);
|
|
364
|
-
}
|
|
365
|
-
signal === null || signal === void 0 ? void 0 : signal.removeEventListener("abort", onAbort);
|
|
366
|
-
// Mirror the conversation without holding the turn outcome: on
|
|
367
|
-
// hosted v2 the pod can be parked as soon as the execution reply
|
|
368
|
-
// lands, so the engine's durability drain awaits this write through
|
|
369
|
-
// drainConversation before that reply, not before turn.completed.
|
|
370
|
-
// In the `finally` so a `wait()` that THROWS (transport death
|
|
371
|
-
// mid-turn, an abort with no follow-up) still persists the
|
|
372
|
-
// checkpoints the turn already wrote — the store is local SQLite,
|
|
373
|
-
// safe to read on the throw path, and persistConversation swallows
|
|
374
|
-
// its own errors. Guarded here (not just inside the helper) so
|
|
375
|
-
// unmirrored turns keep their exact post-wait sequencing.
|
|
376
|
-
if (request.runtime === "local" && this.options.conversationMirror !== undefined) {
|
|
377
|
-
this.trackPersist(request.sessionId, this.persistConversation(request, agent.agentId));
|
|
378
|
-
}
|
|
322
|
+
else {
|
|
323
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
379
324
|
}
|
|
380
325
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
326
|
+
// Cloud + envVars: server mints the real `bc-…` id during createAgent
|
|
327
|
+
// inside the first send. Bind only after that so we never persist/print
|
|
328
|
+
// the provisional client-seeded id.
|
|
329
|
+
if (request.onSdkAgentId !== undefined) {
|
|
330
|
+
await request.onSdkAgentId(agent.agentId);
|
|
386
331
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
if ((run === null || run === void 0 ? void 0 : run.steer) === undefined) {
|
|
393
|
-
return "revert_to_followup";
|
|
332
|
+
// Readable on the handle as soon as send resolves, long before wait().
|
|
333
|
+
if (request.onRequestId !== undefined &&
|
|
334
|
+
run.requestId !== undefined &&
|
|
335
|
+
run.requestId !== "") {
|
|
336
|
+
await request.onRequestId(run.requestId);
|
|
394
337
|
}
|
|
338
|
+
this.activeRuns.set(request.sessionId, run);
|
|
395
339
|
try {
|
|
396
|
-
|
|
340
|
+
const result = await run.wait();
|
|
341
|
+
let outcome = toTurnOutcome(result);
|
|
342
|
+
if (outcome.status === "error") {
|
|
343
|
+
// An error result usually means the handle's transport is poisoned
|
|
344
|
+
// — most often a cached access token that aged past its 60-minute
|
|
345
|
+
// lifetime and gets replayed on every request (stream failures
|
|
346
|
+
// bypass the transport's 401 retry). Retire the handle so the next
|
|
347
|
+
// attempt resumes the conversation from the store on a fresh
|
|
348
|
+
// transport instead of failing every turn until a restart.
|
|
349
|
+
this.evictAgent(request.sessionId, agentPromise);
|
|
350
|
+
}
|
|
351
|
+
else if (request.runtime === "cloud" &&
|
|
352
|
+
outcome.status === "finished" &&
|
|
353
|
+
usageTokenSum(outcome.usage) <= 0 &&
|
|
354
|
+
result.id !== "") {
|
|
355
|
+
// Cloud `wait()` drops usage after stream reconnect / getRun replay,
|
|
356
|
+
// or returns an all-zero stub. `getUsage` still has the run's tokens
|
|
357
|
+
// (eventually); without them traces never record an estimated cost.
|
|
358
|
+
outcome = await fillMissingCloudUsage(agent, result.id, outcome);
|
|
359
|
+
}
|
|
360
|
+
return outcome;
|
|
397
361
|
}
|
|
398
|
-
|
|
399
|
-
this.
|
|
400
|
-
|
|
362
|
+
finally {
|
|
363
|
+
if (this.activeRuns.get(request.sessionId) === run) {
|
|
364
|
+
this.activeRuns.delete(request.sessionId);
|
|
365
|
+
}
|
|
366
|
+
signal?.removeEventListener("abort", onAbort);
|
|
367
|
+
// Mirror the conversation without holding the turn outcome: on
|
|
368
|
+
// hosted v2 the pod can be parked as soon as the execution reply
|
|
369
|
+
// lands, so the engine's durability drain awaits this write through
|
|
370
|
+
// drainConversation before that reply, not before turn.completed.
|
|
371
|
+
// In the `finally` so a `wait()` that THROWS (transport death
|
|
372
|
+
// mid-turn, an abort with no follow-up) still persists the
|
|
373
|
+
// checkpoints the turn already wrote — the store is local SQLite,
|
|
374
|
+
// safe to read on the throw path, and persistConversation swallows
|
|
375
|
+
// its own errors. Guarded here (not just inside the helper) so
|
|
376
|
+
// unmirrored turns keep their exact post-wait sequencing.
|
|
377
|
+
if (request.runtime === "local" && this.options.conversationMirror !== undefined) {
|
|
378
|
+
this.trackPersist(request.sessionId, this.persistConversation(request, agent.agentId));
|
|
379
|
+
}
|
|
401
380
|
}
|
|
402
|
-
}
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
// Drop the cached agent so a dead Connect/HTTP2 session cannot poison
|
|
384
|
+
// the next turn (terminal/shell overflow often kills the transport).
|
|
385
|
+
this.evictAgent(request.sessionId, agentPromise);
|
|
386
|
+
throw error;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
async steer(request) {
|
|
390
|
+
const run = this.activeRuns.get(request.sessionId);
|
|
391
|
+
if (run?.steer === undefined) {
|
|
392
|
+
return "revert_to_followup";
|
|
393
|
+
}
|
|
394
|
+
try {
|
|
395
|
+
return await run.steer(request.text);
|
|
396
|
+
}
|
|
397
|
+
catch (error) {
|
|
398
|
+
this.log(`[bdk] session ${request.sessionId}: steer failed: ${describeError(error)}`);
|
|
399
|
+
return "revert_to_followup";
|
|
400
|
+
}
|
|
403
401
|
}
|
|
404
402
|
/**
|
|
405
403
|
* Build the local executor for a workspace before any session asks for it.
|
|
406
404
|
* The warmed executor is reference counted, so the lease is held until
|
|
407
405
|
* {@link dispose}; dropping it early would tear the workspace back down.
|
|
408
406
|
*/
|
|
409
|
-
prewarm(request) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
return { warmed: true };
|
|
415
|
-
});
|
|
407
|
+
async prewarm(request) {
|
|
408
|
+
const platform = await createAgentPlatform();
|
|
409
|
+
const release = await platform.prewarmLocalWorkspace(await this.buildLocalOptions(request));
|
|
410
|
+
this.prewarmReleases.push(release);
|
|
411
|
+
return { warmed: true };
|
|
416
412
|
}
|
|
417
413
|
/**
|
|
418
414
|
* Drop the cached SDK agent for this session, if one is open.
|
|
@@ -432,10 +428,8 @@ export class CursorSdkRunner {
|
|
|
432
428
|
}
|
|
433
429
|
this.evictAgent(sessionId, cached.agent);
|
|
434
430
|
}
|
|
435
|
-
drainConversation(sessionId) {
|
|
436
|
-
|
|
437
|
-
yield this.pendingPersists.get(sessionId);
|
|
438
|
-
});
|
|
431
|
+
async drainConversation(sessionId) {
|
|
432
|
+
await this.pendingPersists.get(sessionId);
|
|
439
433
|
}
|
|
440
434
|
trackPersist(sessionId, persist) {
|
|
441
435
|
const tracked = Promise.all([this.pendingPersists.get(sessionId), persist]).then(() => {
|
|
@@ -445,19 +439,17 @@ export class CursorSdkRunner {
|
|
|
445
439
|
});
|
|
446
440
|
this.pendingPersists.set(sessionId, tracked);
|
|
447
441
|
}
|
|
448
|
-
dispose() {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
settled.value.close();
|
|
458
|
-
}
|
|
442
|
+
async dispose() {
|
|
443
|
+
await Promise.allSettled([...this.pendingPersists.values()]);
|
|
444
|
+
const releases = this.prewarmReleases.splice(0);
|
|
445
|
+
await Promise.allSettled(releases.map(release => release()));
|
|
446
|
+
const agents = await Promise.allSettled([...this.agents.values()].map(handle => handle.agent));
|
|
447
|
+
this.agents.clear();
|
|
448
|
+
for (const settled of agents) {
|
|
449
|
+
if (settled.status === "fulfilled") {
|
|
450
|
+
settled.value.close();
|
|
459
451
|
}
|
|
460
|
-
}
|
|
452
|
+
}
|
|
461
453
|
}
|
|
462
454
|
getAgent(request) {
|
|
463
455
|
const cached = this.agents.get(request.sessionId);
|
|
@@ -468,7 +460,7 @@ export class CursorSdkRunner {
|
|
|
468
460
|
}
|
|
469
461
|
// Past this age the handle's exchanged access token could expire
|
|
470
462
|
// mid-turn. Retire it and reopen below on a fresh transport.
|
|
471
|
-
this.log(`[bdk] session ${request.sessionId}: recycling the SDK agent handle after ${Math.round(ageMs /
|
|
463
|
+
this.log(`[bdk] session ${request.sessionId}: recycling the SDK agent handle after ${Math.round(ageMs / 60_000)} min so the turn runs on a fresh access token`);
|
|
472
464
|
this.evictAgent(request.sessionId, cached.agent);
|
|
473
465
|
}
|
|
474
466
|
const agentPromise = this.openAgent(request).catch(error => {
|
|
@@ -496,8 +488,7 @@ export class CursorSdkRunner {
|
|
|
496
488
|
void cached.agent.then(sdkAgent => sdkAgent.close()).catch(() => { });
|
|
497
489
|
}
|
|
498
490
|
log(line) {
|
|
499
|
-
|
|
500
|
-
((_a = this.options.logger) !== null && _a !== void 0 ? _a : (() => { }))(line);
|
|
491
|
+
(this.options.logger ?? (() => { }))(line);
|
|
501
492
|
}
|
|
502
493
|
/**
|
|
503
494
|
* Re-resolve on every turn. Hosted freeze snapshots listen unsigned; the
|
|
@@ -512,111 +503,128 @@ export class CursorSdkRunner {
|
|
|
512
503
|
return resolved.apiKey;
|
|
513
504
|
}
|
|
514
505
|
buildSharedOptions(request) {
|
|
515
|
-
var _a;
|
|
516
506
|
const subagents = toAgentDefinitions(request.subagents);
|
|
517
|
-
return
|
|
518
|
-
|
|
519
|
-
:
|
|
507
|
+
return {
|
|
508
|
+
model: toModelSelection(request.model ?? DEFAULT_MODEL),
|
|
509
|
+
apiKey: this.requireApiKey(),
|
|
510
|
+
// Per-send servers ride each agent.send instead (fresh per-session
|
|
511
|
+
// auth headers every turn). Keeping them out of the create/resume
|
|
512
|
+
// options also keeps the local executor cache key — which hashes
|
|
513
|
+
// these options — stable while credentials rotate.
|
|
514
|
+
...(Object.keys(request.mcpServers).length > 0 && request.perSendMcpServers !== true
|
|
515
|
+
? { mcpServers: request.mcpServers }
|
|
516
|
+
: {}),
|
|
517
|
+
...(subagents === undefined ? {} : { agents: subagents }),
|
|
518
|
+
};
|
|
520
519
|
}
|
|
521
520
|
/**
|
|
522
521
|
* The options that decide which local executor a turn runs on. Prewarming
|
|
523
522
|
* goes through here too, so a warmed workspace is the one turns land on.
|
|
524
523
|
*/
|
|
525
|
-
buildLocalOptions(request) {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
524
|
+
async buildLocalOptions(request) {
|
|
525
|
+
// Not resolveStore: an injected store is used synchronously (no
|
|
526
|
+
// microtask, no thenable assimilation), exactly as before the mirror
|
|
527
|
+
// existed.
|
|
528
|
+
const store = this.options.store ?? (await this.getStore(request.runnerStateDir));
|
|
529
|
+
return {
|
|
530
|
+
...this.buildSharedOptions(request),
|
|
531
|
+
// The built-in tool allowlist rides AgentOptions, not `local`, and is
|
|
532
|
+
// deliberately absent from openCloudAgent's options: the SDK rejects
|
|
533
|
+
// tool restrictions on cloud agents. Passed on create *and* resume
|
|
534
|
+
// (both flow through here) — the SDK does not persist it across runs.
|
|
535
|
+
...(request.tools === undefined ? {} : { tools: request.tools }),
|
|
536
|
+
...(request.disallowedTools === undefined
|
|
533
537
|
? {}
|
|
534
|
-
: { disallowedTools: request.disallowedTools })
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
return this.openLocalAgent(request);
|
|
549
|
-
});
|
|
538
|
+
: { disallowedTools: request.disallowedTools }),
|
|
539
|
+
// Same shape: local-only (the SDK rejects it with `cloud`), not
|
|
540
|
+
// persisted, so it rides every create/resume. Replaces Cursor's
|
|
541
|
+
// built-in system prompt with the agent's composed instructions.
|
|
542
|
+
// Prewarm requests carry none, and the SDK's workspace cache key
|
|
543
|
+
// ignores it, so a warmed executor is still the one turns land on.
|
|
544
|
+
systemPrompt: request.instructions,
|
|
545
|
+
local: {
|
|
546
|
+
cwd: request.workspaceDir,
|
|
547
|
+
settingSources: ["project"],
|
|
548
|
+
store,
|
|
549
|
+
...(request.sandbox === true ? { sandboxOptions: { enabled: true } } : {}),
|
|
550
|
+
},
|
|
551
|
+
};
|
|
550
552
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
return Agent.create(Object.assign(Object.assign({}, options), { agentId }));
|
|
553
|
+
async openAgent(request) {
|
|
554
|
+
if (request.runtime === "cloud") {
|
|
555
|
+
return this.openCloudAgent(request, this.buildSharedOptions(request));
|
|
556
|
+
}
|
|
557
|
+
return this.openLocalAgent(request);
|
|
558
|
+
}
|
|
559
|
+
async openLocalAgent(request) {
|
|
560
|
+
const options = await this.buildLocalOptions(request);
|
|
561
|
+
if (request.isFirstTurn || request.sdkAgentId === undefined) {
|
|
562
|
+
return Agent.create({
|
|
563
|
+
...options,
|
|
564
|
+
agentId: request.sdkAgentId ?? request.sessionId,
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
const agentId = request.sdkAgentId ?? request.sessionId;
|
|
568
|
+
const mirror = this.options.conversationMirror;
|
|
569
|
+
if (mirror !== undefined) {
|
|
570
|
+
// Host replacement: restore the conversation from the durable mirror
|
|
571
|
+
// before resuming, so the thread continues instead of starting fresh.
|
|
572
|
+
// A sink failure propagates and fails the turn (retryable) — reading
|
|
573
|
+
// an outage as "nothing mirrored" would silently fork the thread.
|
|
574
|
+
const store = await this.resolveStore(request);
|
|
575
|
+
await mirror.hydrate(store, agentId);
|
|
576
|
+
}
|
|
577
|
+
try {
|
|
578
|
+
return await Agent.resume(agentId, options);
|
|
579
|
+
}
|
|
580
|
+
catch (error) {
|
|
581
|
+
if (!isLocalAgentNotFoundError(error, agentId)) {
|
|
582
|
+
throw error;
|
|
582
583
|
}
|
|
583
|
-
|
|
584
|
+
// Host replacement: the session record survived in durable storage,
|
|
585
|
+
// but the conversation store died with the old pod. A fresh
|
|
586
|
+
// conversation under the same id beats failing this thread's turns
|
|
587
|
+
// forever ("Agent … not found" on every follow-up). The channel's
|
|
588
|
+
// warm-turn prompt context re-hydrates the thread history.
|
|
589
|
+
this.log(`[bdk] no stored conversation for ${agentId} on this host; starting a fresh one`);
|
|
590
|
+
return Agent.create({ ...options, agentId });
|
|
591
|
+
}
|
|
584
592
|
}
|
|
585
|
-
openCloudAgent(request, shared) {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
if (!hasEnvVars) {
|
|
601
|
-
// Client-seeded (non bc-…) id on a brand new session: forward it to
|
|
602
|
-
// create so the server adopts it. With envVars the server must mint
|
|
603
|
-
// the id, so the seed cannot be honored and create() runs below.
|
|
604
|
-
return Agent.create(Object.assign(Object.assign({}, options), { agentId: sdkAgentId }));
|
|
605
|
-
}
|
|
593
|
+
async openCloudAgent(request, shared) {
|
|
594
|
+
const cloud = toCloudAgentOptions(request.cloud, request.agentServeAgent);
|
|
595
|
+
const hasEnvVars = cloud.envVars !== undefined && Object.keys(cloud.envVars).length > 0;
|
|
596
|
+
const options = {
|
|
597
|
+
...shared,
|
|
598
|
+
cloud,
|
|
599
|
+
};
|
|
600
|
+
const sdkAgentId = request.sdkAgentId?.trim();
|
|
601
|
+
if (sdkAgentId !== undefined && sdkAgentId !== "") {
|
|
602
|
+
// A server-minted `bc-…` id always resumes — including on the first
|
|
603
|
+
// framework turn of a session seeded via SendMessageOptions.sdkAgentId
|
|
604
|
+
// (PR→bcId affinity across session-store resets). Any persisted id
|
|
605
|
+
// resumes on later turns.
|
|
606
|
+
if (isServerMintedCloudAgentId(sdkAgentId) || !request.isFirstTurn) {
|
|
607
|
+
return Agent.resume(sdkAgentId, options);
|
|
606
608
|
}
|
|
607
|
-
if (
|
|
608
|
-
|
|
609
|
+
if (!hasEnvVars) {
|
|
610
|
+
// Client-seeded (non bc-…) id on a brand new session: forward it to
|
|
611
|
+
// create so the server adopts it. With envVars the server must mint
|
|
612
|
+
// the id, so the seed cannot be honored and create() runs below.
|
|
613
|
+
return Agent.create({ ...options, agentId: sdkAgentId });
|
|
609
614
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
// one). Reaching here means the binding turn failed before the server
|
|
613
|
-
// ever minted an agent — e.g. create() rejected its PR attach — so the
|
|
614
|
-
// session would otherwise fail every future turn. Mirror the local
|
|
615
|
-
// host-replacement path above: a fresh conversation beats failing this
|
|
616
|
-
// thread forever, and the new id binds to the session for later resumes.
|
|
617
|
-
this.log(`[bdk] cloud session ${request.sessionId} has no bound cloud agent; creating a fresh one`);
|
|
615
|
+
}
|
|
616
|
+
if (request.isFirstTurn) {
|
|
618
617
|
return Agent.create(options);
|
|
619
|
-
}
|
|
618
|
+
}
|
|
619
|
+
// A cloud session past its first turn should carry the bound agent id
|
|
620
|
+
// (the engine persists it via onSdkAgentId as soon as create() reports
|
|
621
|
+
// one). Reaching here means the binding turn failed before the server
|
|
622
|
+
// ever minted an agent — e.g. create() rejected its PR attach — so the
|
|
623
|
+
// session would otherwise fail every future turn. Mirror the local
|
|
624
|
+
// host-replacement path above: a fresh conversation beats failing this
|
|
625
|
+
// thread forever, and the new id binds to the session for later resumes.
|
|
626
|
+
this.log(`[bdk] cloud session ${request.sessionId} has no bound cloud agent; creating a fresh one`);
|
|
627
|
+
return Agent.create(options);
|
|
620
628
|
}
|
|
621
629
|
resolveStore(request) {
|
|
622
630
|
return this.options.store !== undefined
|
|
@@ -627,20 +635,18 @@ export class CursorSdkRunner {
|
|
|
627
635
|
* Mirror the settled turn's conversation. Persist failures are logged and
|
|
628
636
|
* dropped — a durable-mirror outage must not fail a turn that already ran.
|
|
629
637
|
*/
|
|
630
|
-
persistConversation(request, sdkAgentId) {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
}
|
|
643
|
-
});
|
|
638
|
+
async persistConversation(request, sdkAgentId) {
|
|
639
|
+
const mirror = this.options.conversationMirror;
|
|
640
|
+
if (mirror === undefined) {
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
try {
|
|
644
|
+
const store = await this.resolveStore(request);
|
|
645
|
+
await mirror.persist(store, sdkAgentId);
|
|
646
|
+
}
|
|
647
|
+
catch (error) {
|
|
648
|
+
this.log(`[bdk] conversation mirror: persist for ${sdkAgentId} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
649
|
+
}
|
|
644
650
|
}
|
|
645
651
|
getStore(stateDir) {
|
|
646
652
|
let storePromise = this.stores.get(stateDir);
|
|
@@ -673,14 +679,25 @@ export function toModelSelection(model) {
|
|
|
673
679
|
if (typeof model === "string") {
|
|
674
680
|
return { id: model };
|
|
675
681
|
}
|
|
676
|
-
return
|
|
682
|
+
return {
|
|
683
|
+
id: model.id,
|
|
684
|
+
...(model.params === undefined ? {} : { params: model.params }),
|
|
685
|
+
};
|
|
677
686
|
}
|
|
678
687
|
function toCloudAgentOptions(cloud, agentServeAgent) {
|
|
679
|
-
return
|
|
680
|
-
? {}
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
688
|
+
return {
|
|
689
|
+
...(cloud?.env === undefined ? {} : { env: cloud.env }),
|
|
690
|
+
...(cloud?.repos === undefined ? {} : { repos: cloud.repos }),
|
|
691
|
+
...(cloud?.workOnCurrentBranch === undefined
|
|
692
|
+
? {}
|
|
693
|
+
: { workOnCurrentBranch: cloud.workOnCurrentBranch }),
|
|
694
|
+
...(cloud?.autoCreatePR === undefined ? {} : { autoCreatePR: cloud.autoCreatePR }),
|
|
695
|
+
...(cloud?.skipReviewerRequest === undefined
|
|
696
|
+
? {}
|
|
697
|
+
: { skipReviewerRequest: cloud.skipReviewerRequest }),
|
|
698
|
+
...(cloud?.envVars === undefined ? {} : { envVars: cloud.envVars }),
|
|
699
|
+
...(agentServeAgent === undefined ? {} : { agentServeAgent }),
|
|
700
|
+
};
|
|
684
701
|
}
|
|
685
702
|
function toAgentDefinitions(subagents) {
|
|
686
703
|
if (subagents.length === 0) {
|
|
@@ -697,13 +714,24 @@ function toAgentDefinitions(subagents) {
|
|
|
697
714
|
return definitions;
|
|
698
715
|
}
|
|
699
716
|
function toTurnOutcome(result) {
|
|
700
|
-
var _a;
|
|
701
717
|
const usage = result.usage === undefined
|
|
702
718
|
? undefined
|
|
703
|
-
:
|
|
704
|
-
|
|
705
|
-
:
|
|
706
|
-
|
|
719
|
+
: {
|
|
720
|
+
inputTokens: result.usage.inputTokens,
|
|
721
|
+
outputTokens: result.usage.outputTokens,
|
|
722
|
+
cacheReadTokens: result.usage.cacheReadTokens,
|
|
723
|
+
cacheWriteTokens: result.usage.cacheWriteTokens,
|
|
724
|
+
...(result.usage.reasoningTokens === undefined
|
|
725
|
+
? {}
|
|
726
|
+
: { reasoningTokens: result.usage.reasoningTokens }),
|
|
727
|
+
};
|
|
728
|
+
return {
|
|
729
|
+
status: result.status,
|
|
730
|
+
...(result.result === undefined ? {} : { result: result.result }),
|
|
731
|
+
...(result.status === "error" ? { errorMessage: runErrorMessage(result) } : {}),
|
|
732
|
+
errorCode: result.status === "error" ? result.error?.code : undefined,
|
|
733
|
+
...(usage === undefined ? {} : { usage }),
|
|
734
|
+
};
|
|
707
735
|
}
|
|
708
736
|
/** Billing can lag briefly after `wait()`; retry before giving up on cost. */
|
|
709
737
|
const CLOUD_USAGE_RETRY_DELAYS_MS = [0, 400, 1200];
|
|
@@ -712,28 +740,25 @@ const CLOUD_USAGE_RETRY_DELAYS_MS = [0, 400, 1200];
|
|
|
712
740
|
* tokens from the usage API so the engine can still price the turn.
|
|
713
741
|
* Failures are ignored: a missing estimate is better than failing the turn.
|
|
714
742
|
*/
|
|
715
|
-
function fillMissingCloudUsage(agent, runId, outcome) {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
continue;
|
|
726
|
-
}
|
|
727
|
-
return Object.assign(Object.assign({}, outcome), { usage: mapped });
|
|
728
|
-
}
|
|
729
|
-
catch (_a) {
|
|
730
|
-
// Transient usage-API failures should still burn the retry budget.
|
|
743
|
+
async function fillMissingCloudUsage(agent, runId, outcome) {
|
|
744
|
+
for (const delayMs of CLOUD_USAGE_RETRY_DELAYS_MS) {
|
|
745
|
+
if (delayMs > 0) {
|
|
746
|
+
await sleep(delayMs);
|
|
747
|
+
}
|
|
748
|
+
try {
|
|
749
|
+
const billed = await agent.getUsage({ runId });
|
|
750
|
+
const mapped = mapSdkTokenUsage(billed.usage);
|
|
751
|
+
if (usageTokenSum(mapped) <= 0) {
|
|
752
|
+
continue;
|
|
731
753
|
}
|
|
754
|
+
return { ...outcome, usage: mapped };
|
|
755
|
+
}
|
|
756
|
+
catch {
|
|
757
|
+
// Transient usage-API failures should still burn the retry budget.
|
|
732
758
|
}
|
|
733
|
-
|
|
734
|
-
|
|
759
|
+
}
|
|
760
|
+
return outcome;
|
|
735
761
|
}
|
|
736
762
|
export function runErrorMessage(result) {
|
|
737
|
-
|
|
738
|
-
return ((_b = (_a = result.error) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.trim()) || "The Cursor agent run failed";
|
|
763
|
+
return result.error?.message?.trim() || "The Cursor agent run failed";
|
|
739
764
|
}
|