@cursor/bdk 0.2.10 → 0.2.12
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/bin/agent-serve.js +28 -26
- package/dist/channels/bitbucket/api.js +8 -8
- package/dist/channels/bitbucket/binding.js +4 -4
- package/dist/channels/bitbucket/bitbucket-channel.js +1 -1
- package/dist/channels/bitbucket/bitbucket-webhook.js +1 -1
- package/dist/channels/bitbucket/checks.js +1 -1
- package/dist/channels/bitbucket/cursor-account.js +1 -1
- package/dist/channels/bitbucket/events.js +1 -1
- package/dist/channels/change-monitors/change-monitors-channel.js +1 -1
- package/dist/channels/checks.js +2 -2
- package/dist/channels/deployments/deployments-channel.js +1 -1
- package/dist/channels/github/cursor-account.js +3 -3
- package/dist/channels/github/defaults.js +3 -3
- package/dist/channels/github/events.js +1 -1
- package/dist/channels/github/forward.js +8 -8
- package/dist/channels/github/github-channel.js +2 -2
- package/dist/channels/gitlab/binding.js +4 -4
- package/dist/channels/gitlab/checks.js +1 -1
- package/dist/channels/gitlab/cursor-account.js +1 -1
- package/dist/channels/gitlab/events.js +1 -1
- package/dist/channels/gitlab/gitlab-channel.js +1 -1
- package/dist/channels/gitlab/gitlab-webhook.js +1 -1
- package/dist/channels/gitlab/replay.js +2 -2
- package/dist/channels/origin/binding.js +3 -3
- package/dist/channels/origin/checks.js +1 -1
- package/dist/channels/origin/cursor-account.js +1 -1
- package/dist/channels/origin/events.js +1 -1
- package/dist/channels/origin/origin-channel.js +1 -1
- package/dist/channels/origin/origin-webhook.js +2 -2
- package/dist/channels/slack/agentic-delivery.js +3 -3
- package/dist/channels/slack/agentic-signals.js +1 -1
- package/dist/channels/slack/api.js +5 -5
- package/dist/channels/slack/approvals.js +1 -1
- package/dist/channels/slack/attachments.js +3 -3
- package/dist/channels/slack/blocks.js +3 -3
- package/dist/channels/slack/bot-mentions.js +4 -4
- package/dist/channels/slack/channel-watch.js +4 -4
- package/dist/channels/slack/cli-project.js +3 -3
- package/dist/channels/slack/dispatch.js +1 -1
- package/dist/channels/slack/doctor.js +1 -1
- package/dist/channels/slack/eval-directive.js +1 -1
- package/dist/channels/slack/footer.js +1 -1
- package/dist/channels/slack/interactive.js +2 -2
- package/dist/channels/slack/log.d.ts.map +1 -1
- package/dist/channels/slack/log.js +1 -1
- package/dist/channels/slack/manifest.js +1 -1
- package/dist/channels/slack/nudge-carrier.js +1 -1
- package/dist/channels/slack/nudge-store.js +2 -2
- package/dist/channels/slack/recording-sink.js +6 -6
- package/dist/channels/slack/reply-options.js +6 -6
- package/dist/channels/slack/self-identity.d.ts +7 -4
- package/dist/channels/slack/self-identity.d.ts.map +1 -1
- package/dist/channels/slack/self-identity.js +17 -8
- package/dist/channels/slack/sender-name.d.ts.map +1 -1
- package/dist/channels/slack/sender-name.js +2 -6
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +1 -1
- package/dist/channels/slack/slack-channel.js +2 -2
- package/dist/channels/slack/socket-mode.js +2 -2
- package/dist/channels/slack/thread-context.js +8 -8
- package/dist/channels/slack/tool-cards.js +1 -1
- package/dist/channels/slack/user-info.d.ts +2 -1
- package/dist/channels/slack/user-info.d.ts.map +1 -1
- package/dist/channels/slack/user-info.js +16 -1
- package/dist/channels.js +1 -1
- package/dist/docs/404.html +3 -3
- package/dist/docs/assets/{app.DXI7bwox.js → app.CKta5zX1.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot.DtlCe4t6.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BrbO5mEe.js → VPLocalSearchBox.4vRM3EDG.js} +2 -2
- package/dist/docs/assets/chunks/{arc.BOG1yms8.js → arc.CofbA8tA.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.C0hsMZnZ.js → architectureDiagram-Q4EWVU46.Mt2UV5M-.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.H044KjKs.js → baseUniq.C_W0Aqp4.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.BsRW6GoB.js → blockDiagram-DXYQGD6D.dAc4goE-.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.B9HV5PFR.js → c4Diagram-AHTNJAMY.dnbRC3Dm.js} +1 -1
- package/dist/docs/assets/chunks/channel.DpljPUVU.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.CPoT_ajl.js → chunk-4BX2VUAB.B42ltSTd.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.DZBwWuCL.js → chunk-4TB4RGXK.2GbAul_E.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.CZ3yTiyq.js → chunk-55IACEB6.pjzY-v-B.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.6DfvHSd8.js → chunk-EDXVE4YY.BB1GXLj2.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.CpBj8HfK.js → chunk-FMBD7UC4.B2WxZkoA.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.BdKo8YqS.js → chunk-OYMX7WX6.BMvb2w73.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BnXNyxJx.js → chunk-QZHKN3VN.Bmu_2lNr.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.Cg1OcF8G.js → chunk-YZCP3GAM.Cth65EaC.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.DFNHq2OM.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.DFNHq2OM.js +1 -0
- package/dist/docs/assets/chunks/clone.DssygCzX.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.1SP8al9c.js → cose-bilkent-S5V4N54A.CrfA7Iw_.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.DS1L6hJt.js → dagre-KV5264BT.PCD6KQDb.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.ChsausbG.js → diagram-5BDNPKRD.CGNlYlP1.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.3XsptNWj.js → diagram-G4DWMVQ6.C0cvryPD.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.DPA9Dk_P.js → diagram-MMDJMWI5.DHlkZHNV.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.BVswXWrB.js → diagram-TYMM5635.DDGqH_4B.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.BSak5OSP.js → erDiagram-SMLLAGMA.4gOY_C3v.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.CQgN4TTz.js → flowDiagram-DWJPFMVM.8i7zsxuh.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.GrT0kA4a.js → ganttDiagram-T4ZO3ILL.BEKHYdM-.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.CdS7Ucll.js → gitGraphDiagram-UUTBAWPF.ACzeLGiB.js} +1 -1
- package/dist/docs/assets/chunks/{graph.BVqKRmRo.js → graph.08C3hS6m.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.C3C9FRto.js → infoDiagram-42DDH7IO.D8R9obOH.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.2FuAh_Zj.js → ishikawaDiagram-UXIWVN3A.CmgYpCWL.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CaHMfK4b.js → journeyDiagram-VCZTEJTY.DUzjGfoZ.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.CjhIUwcA.js → kanban-definition-6JOO6SKY.DbcW2iZ0.js} +1 -1
- package/dist/docs/assets/chunks/{layout.CGU3gfSf.js → layout.BaDEpJzu.js} +1 -1
- package/dist/docs/assets/chunks/{linear.DaihpW_n.js → linear.B_zRQgCU.js} +1 -1
- package/dist/docs/assets/chunks/{min.BS-j8kHQ.js → min.BYscCdSu.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.BVJ1Bbnk.js → mindmap-definition-QFDTVHPH.Ggu0jg86.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.Cz1WIv9r.js → pieDiagram-DEJITSTG.D_q4SVDT.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.DKLFxcjy.js → quadrantDiagram-34T5L4WZ.D3zGj5ok.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.BHegiK7x.js → requirementDiagram-MS252O5E.DVTg7zr2.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.DYkY6yPc.js → sankeyDiagram-XADWPNL6.D3X8jm57.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.DYQ1QUrI.js → sequenceDiagram-FGHM5R23.Dpjai9YP.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.Iru8BsFo.js → stateDiagram-FHFEXIEX.D_AbQBuP.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CWKWRxRx.js +1 -0
- package/dist/docs/assets/chunks/{theme.DaplWQhQ.js → theme.BcgOnbZ6.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BwFA8hiX.js → timeline-definition-GMOUNBTQ.Cp3DKBe2.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CZ60W1C_.js → vennDiagram-DHZGUBPP.Bcvg-Aqu.js} +1 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.CCpdcUSq.js +162 -0
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.B69D2r8-.js → wardleyDiagram-NUSXRM2D.L0yehCc5.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.CLPZEIU9.js → xychartDiagram-5P7HB3ND.Cw8-tJmw.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.Bljpve-y.js → reference_connections.md.DLrgAd5f.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.C5LCJ1R3.js → reference_hooks.md.B-eGa2km.js} +3 -3
- package/dist/docs/assets/{reference_hooks.md.C5LCJ1R3.lean.js → reference_hooks.md.B-eGa2km.lean.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.CM5zo3w4.js → reference_sessions.md.CyM7ARz1.js} +1 -1
- package/dist/docs/assets/{reference_skills.md.C0guGcH0.js → reference_skills.md.ClkMoQsV.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.v3SXVSs_.js → reference_tools.md.DzIY9JzY.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.v3SXVSs_.lean.js → reference_tools.md.DzIY9JzY.lean.js} +1 -1
- package/dist/docs/assets/{style.C130MVnH.css → style.Dwls12uf.css} +1 -1
- package/dist/docs/building-with-agents.html +37 -37
- package/dist/docs/deployment.html +37 -37
- package/dist/docs/evals.html +37 -37
- package/dist/docs/guides/agent-to-agent.html +37 -37
- package/dist/docs/guides/bitbucket.html +37 -37
- package/dist/docs/guides/cloud-agents.html +37 -37
- package/dist/docs/guides/convert-automation.html +37 -37
- package/dist/docs/guides/github.html +37 -37
- package/dist/docs/guides/gitlab.html +37 -37
- package/dist/docs/guides/grokbot-agents.html +37 -37
- package/dist/docs/guides/hooks.html +37 -37
- package/dist/docs/guides/improve.html +37 -37
- package/dist/docs/guides/jev.html +37 -37
- package/dist/docs/guides/mcp-oauth.html +37 -37
- package/dist/docs/guides/migrate.html +37 -37
- package/dist/docs/guides/opentelemetry.html +37 -37
- package/dist/docs/guides/slack.html +37 -37
- package/dist/docs/guides/webhooks.html +37 -37
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +37 -37
- package/dist/docs/index.html +37 -37
- package/dist/docs/llms-full.txt +15 -2
- package/dist/docs/quickstart.html +37 -37
- package/dist/docs/reference/agent-config.html +37 -37
- package/dist/docs/reference/artifacts.html +37 -37
- package/dist/docs/reference/channels.html +37 -37
- package/dist/docs/reference/cli.html +37 -37
- package/dist/docs/reference/connections.html +39 -39
- package/dist/docs/reference/connections.md +2 -1
- package/dist/docs/reference/evals.html +37 -37
- package/dist/docs/reference/extensions.html +37 -37
- package/dist/docs/reference/hooks.html +39 -39
- package/dist/docs/reference/hooks.md +1 -0
- package/dist/docs/reference/http-api.html +37 -37
- package/dist/docs/reference/instructions.html +37 -37
- package/dist/docs/reference/playground.html +36 -36
- package/dist/docs/reference/project-layout.html +37 -37
- package/dist/docs/reference/prompt.html +37 -37
- package/dist/docs/reference/schedules.html +37 -37
- package/dist/docs/reference/sessions.html +37 -37
- package/dist/docs/reference/sessions.md +1 -1
- package/dist/docs/reference/skills.html +40 -40
- package/dist/docs/reference/subagents.html +37 -37
- package/dist/docs/reference/tools.html +39 -39
- package/dist/docs/reference/tools.md +11 -0
- package/dist/docs/templates/agentic-owners.html +37 -37
- package/dist/docs/templates/grokbot-agents.html +37 -37
- package/dist/docs/templates/security-reviewer.html +37 -37
- package/dist/docs/templates/thermo-quality-review.html +37 -37
- package/dist/docs/templates/thermo-review.html +37 -37
- package/dist/docs/templates/triage.html +37 -37
- package/dist/docs/troubleshooting.html +36 -36
- package/dist/evals/assertions.d.ts.map +1 -1
- package/dist/evals/assertions.js +21 -19
- package/dist/evals/expect.js +1 -1
- package/dist/evals/judge.js +1 -1
- package/dist/evals/reporters.js +8 -8
- package/dist/evals/run-facts.js +2 -2
- package/dist/evals.js +6 -6
- package/dist/extensions/cursor-cloud-agents/extension.d.ts +2 -0
- package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/extension.js +2 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts +16 -0
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +44 -3
- package/dist/extensions/cursor-cloud-agents/lib/fleet.js +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts +23 -0
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.js +32 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.js +2 -2
- package/dist/extensions/cursor-cloud-agents/lib/transcript.js +2 -2
- package/dist/extensions/cursor-cloud-agents/lib/watch.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/watch.js +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/launch.js +3 -8
- package/dist/extensions/cursor-cloud-agents/tools/list.js +1 -1
- package/dist/extensions/cursor-grokbot-agents/extension.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/agents.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.js +4 -4
- package/dist/extensions/cursor-grokbot-agents/tools/list.js +1 -1
- package/dist/extensions/improve/skills/yourself.js +1 -1
- package/dist/extensions/jev/extension.js +2 -2
- package/dist/extensions/jev/tools/evaluate.js +1 -1
- package/dist/extensions/slack-communication/tools/react.js +1 -1
- package/dist/files-backends/cursor-hosted.js +8 -8
- package/dist/files-backends/local-fs.js +1 -1
- package/dist/filesystem.d.ts.map +1 -1
- package/dist/filesystem.js +15 -15
- package/dist/internal/advertise-tools.d.ts +3 -2
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +11 -9
- package/dist/internal/approval-gate.js +1 -1
- package/dist/internal/artifacts-store.js +13 -13
- package/dist/internal/as-of.js +2 -2
- package/dist/internal/authored-alias-hooks.js +1 -1
- package/dist/internal/builtin-tools/reminders.js +2 -2
- package/dist/internal/chat-client.js +5 -5
- package/dist/internal/cli-ax.js +14 -14
- package/dist/internal/cli-bitbucket.js +10 -10
- package/dist/internal/cli-convert-automation.js +2 -2
- package/dist/internal/cli-cursor.js +2 -2
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +40 -40
- package/dist/internal/cli-docs.js +5 -5
- package/dist/internal/cli-github.js +15 -15
- package/dist/internal/cli-gitlab.js +10 -10
- package/dist/internal/cli-images.js +16 -16
- package/dist/internal/cli-manifest.js +1 -1
- package/dist/internal/cli-mcp-oauth.js +5 -5
- package/dist/internal/cli-mcp.js +3 -3
- package/dist/internal/cli-migrate.js +1 -1
- package/dist/internal/cli-skills.js +2 -2
- package/dist/internal/cli-slack.js +5 -5
- package/dist/internal/cloud-turn-cost.js +1 -1
- package/dist/internal/continuation-identity.js +6 -6
- package/dist/internal/conversation-mirror.js +5 -5
- package/dist/internal/convert-automation/convert-workflow.js +24 -24
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +20 -20
- package/dist/internal/cursor/backend-client.js +6 -6
- package/dist/internal/cursor/credentials.js +1 -1
- package/dist/internal/cursor/store-api-client.js +1 -1
- package/dist/internal/cursor-account-mcp-auth.js +9 -9
- package/dist/internal/cursor-deployment-relay.d.ts.map +1 -1
- package/dist/internal/cursor-deployment-relay.js +9 -9
- package/dist/internal/cursor-event-relay.js +10 -10
- package/dist/internal/cursor-relay-core.js +2 -2
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +3 -0
- package/dist/internal/deploy-manifest.js +10 -10
- package/dist/internal/discovery/agent-config.js +2 -2
- package/dist/internal/discovery/agent.js +6 -6
- package/dist/internal/discovery/connections.js +5 -5
- package/dist/internal/discovery/cursor-plugin.js +12 -12
- package/dist/internal/discovery/extension-overlay.js +3 -3
- package/dist/internal/discovery/extensions.js +6 -6
- package/dist/internal/discovery/info.js +9 -9
- package/dist/internal/discovery/instructions.js +1 -1
- package/dist/internal/discovery/project.js +3 -3
- package/dist/internal/discovery/services.js +1 -1
- package/dist/internal/discovery/tools.js +1 -1
- package/dist/internal/docs-site.js +2 -2
- package/dist/internal/env-file.js +1 -1
- package/dist/internal/eval-run-store.js +7 -7
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +14 -14
- package/dist/internal/eval-transport.js +1 -1
- package/dist/internal/evals-client.js +4 -4
- package/dist/internal/event-log.js +8 -8
- package/dist/internal/event-mapper.js +13 -13
- package/dist/internal/expected-delivery-failure.js +2 -2
- package/dist/internal/filesystem/format.js +2 -2
- package/dist/internal/filesystem/nearest.js +3 -3
- package/dist/internal/filesystem/scratch.js +3 -3
- package/dist/internal/filesystem/tools.js +6 -6
- package/dist/internal/filesystem/walk.d.ts.map +1 -1
- package/dist/internal/filesystem/walk.js +2 -2
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +6 -5
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +4 -2
- package/dist/internal/github-fanout.d.ts.map +1 -1
- package/dist/internal/github-fanout.js +3 -3
- package/dist/internal/guest-network.js +4 -4
- package/dist/internal/host-files.js +1 -1
- package/dist/internal/host-kv.js +2 -2
- package/dist/internal/hosted-catch-protocol.js +1 -1
- package/dist/internal/hosted-catch.js +1 -1
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +14 -14
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +23 -9
- package/dist/internal/hosted-eval-cases.js +4 -4
- package/dist/internal/hosted-execution-diag.js +3 -3
- package/dist/internal/hosting.js +1 -1
- package/dist/internal/http-channel.js +1 -1
- package/dist/internal/http-control-plane-session.js +2 -2
- package/dist/internal/init-interview.js +7 -7
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +12 -12
- package/dist/internal/inline-stdio-mcp.js +2 -2
- package/dist/internal/install-cursor-skills.js +11 -11
- package/dist/internal/json-schema.js +1 -1
- package/dist/internal/local-control-plane.js +3 -3
- package/dist/internal/local-env.js +3 -3
- package/dist/internal/log-ring.js +1 -1
- package/dist/internal/logs-client.js +1 -1
- package/dist/internal/mcp-endpoint.js +8 -8
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +5 -5
- package/dist/internal/mcp-oauth-on-demand.js +3 -3
- package/dist/internal/mcp-oauth.js +5 -5
- package/dist/internal/net.js +2 -2
- package/dist/internal/otel/config.js +3 -3
- package/dist/internal/otel/runtime.js +13 -13
- package/dist/internal/peer-connections.js +2 -2
- package/dist/internal/persistent-stage-log-mirror.d.ts +57 -0
- package/dist/internal/persistent-stage-log-mirror.d.ts.map +1 -0
- package/dist/internal/persistent-stage-log-mirror.js +231 -0
- package/dist/internal/platform-schedule-sync.js +1 -1
- package/dist/internal/platform-timers.js +1 -1
- package/dist/internal/playground/static.js +2 -2
- package/dist/internal/playground/toolchain.js +2 -2
- package/dist/internal/playground-proxy.js +3 -3
- package/dist/internal/process-memory-telemetry.js +1 -1
- package/dist/internal/reminder-runner.d.ts +1 -1
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +14 -16
- package/dist/internal/reminder-store.js +1 -1
- package/dist/internal/resolved-connections.js +8 -8
- package/dist/internal/router.js +4 -4
- package/dist/internal/run-client.js +2 -2
- package/dist/internal/schedule-runner.js +6 -6
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +6 -6
- package/dist/internal/serve-restart.js +1 -1
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +93 -72
- package/dist/internal/session-cost.js +3 -3
- package/dist/internal/session-engine.d.ts +8 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +183 -118
- package/dist/internal/session-live-publisher.d.ts +46 -0
- package/dist/internal/session-live-publisher.d.ts.map +1 -0
- package/dist/internal/session-live-publisher.js +352 -0
- package/dist/internal/session-run-log.js +6 -6
- package/dist/internal/sessions-client.js +3 -3
- package/dist/internal/skill-catalog.js +2 -2
- package/dist/internal/sleep.js +1 -1
- package/dist/internal/start-log-store.d.ts +5 -1
- package/dist/internal/start-log-store.d.ts.map +1 -1
- package/dist/internal/start-log-store.js +5 -3
- package/dist/internal/storage-coordinator.js +12 -12
- package/dist/internal/store-api-protocol.d.ts +51 -0
- package/dist/internal/store-api-protocol.d.ts.map +1 -1
- package/dist/internal/store-api-protocol.js +39 -2
- package/dist/internal/store-mirror.js +4 -4
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +4 -0
- package/dist/internal/terminal-style.js +2 -2
- package/dist/internal/tool-call-retry.d.ts +87 -0
- package/dist/internal/tool-call-retry.d.ts.map +1 -0
- package/dist/internal/tool-call-retry.js +387 -0
- package/dist/internal/tool-result.js +3 -3
- package/dist/internal/trajectory.js +7 -7
- package/dist/internal/turn-governor.js +2 -2
- package/dist/internal/turn-outbox.js +1 -1
- package/dist/internal/update-check.d.ts.map +1 -1
- package/dist/internal/update-check.js +4 -2
- package/dist/internal/v2-hosting.d.ts +6 -0
- package/dist/internal/v2-hosting.d.ts.map +1 -1
- package/dist/internal/v2-hosting.js +7 -1
- package/dist/internal/workspace.js +4 -4
- package/dist/kv/memory-kv.js +3 -3
- package/dist/playground/assets/{index-JekUQERK.js → index-HN5lOuAX.js} +42 -42
- package/dist/playground/assets/index-JY1wKCMg.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/prompt.js +1 -1
- package/dist/storage-backends/cursor-hosted-v2.js +2 -2
- package/dist/storage-backends/file-kv.js +7 -7
- package/dist/storage-protocol.d.ts +7 -0
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +7 -0
- package/dist/storage.js +3 -3
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -4
- package/docs/reference/connections.md +2 -1
- package/docs/reference/hooks.md +1 -0
- package/docs/reference/sessions.md +1 -1
- package/docs/reference/tools.md +11 -0
- package/package.json +6 -6
- package/templates/agentic-owners/bot/channels/github.ts +2 -2
- package/templates/agentic-owners/bot/lib/github.ts +7 -5
- package/templates/agentic-owners/bot/lib/owners/decision.ts +9 -9
- package/templates/agentic-owners/bot/lib/owners/handles.ts +2 -2
- package/templates/agentic-owners/bot/lib/owners/match.ts +5 -3
- package/templates/agentic-owners/bot/lib/owners/matching.ts +1 -1
- package/templates/agentic-owners/bot/lib/owners/parse.ts +4 -4
- package/templates/agentic-owners/bot/lib/owners/prompt.ts +1 -1
- package/templates/agentic-owners/bot/lib/review.ts +18 -17
- package/templates/agentic-owners/evals/owners.eval.ts +2 -2
- package/templates/agents-md/bot/lib/collect.ts +6 -6
- package/templates/agents-md/bot/lib/config.ts +1 -1
- package/templates/agents-md/bot/tools/apply_agents.ts +4 -4
- package/templates/code-wiki/bot/channels/github.ts +3 -3
- package/templates/code-wiki/bot/lib/repos.ts +1 -1
- package/templates/code-wiki/bot/tools/apply_wiki.ts +2 -2
- package/templates/demo/bot/lib/collect.ts +1 -1
- package/templates/demo/bot/lib/repos.ts +1 -1
- package/templates/demo/bot/tools/record_demo.ts +1 -1
- package/templates/pr-autofixer/bot/channels/github.ts +2 -2
- package/templates/pr-autofixer/bot/lib/merge-watch.ts +2 -2
- package/templates/pr-autofixer/bot/lib/repos.ts +2 -2
- package/templates/pr-autofixer/bot/lib/webhook-routing.ts +1 -1
- package/templates/security-help/bot/lib/repos.ts +1 -1
- package/templates/security-reviewer/bot/lib/repos.ts +1 -1
- package/templates/triage/bot/lib/actuate.ts +15 -15
- package/dist/docs/assets/chunks/@localSearchIndexroot.CtLtpWcx.js +0 -1
- package/dist/docs/assets/chunks/channel.CBwrU9rP.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CbC_mrvB.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CbC_mrvB.js +0 -1
- package/dist/docs/assets/chunks/clone.BTvFyY1a.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.BYXl4LW6.js +0 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.iXazD3Z7.js +0 -162
- package/dist/playground/assets/index-DXm_VXAQ.css +0 -1
- /package/dist/docs/assets/{reference_connections.md.Bljpve-y.lean.js → reference_connections.md.DLrgAd5f.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.CM5zo3w4.lean.js → reference_sessions.md.CyM7ARz1.lean.js} +0 -0
- /package/dist/docs/assets/{reference_skills.md.C0guGcH0.lean.js → reference_skills.md.ClkMoQsV.lean.js} +0 -0
|
@@ -53,14 +53,17 @@ import { sessionExternalLinks } from "./session-links.js";
|
|
|
53
53
|
import { SessionStore } from "./session-store.js";
|
|
54
54
|
import { syncSkillsToStore } from "./skills-sync.js";
|
|
55
55
|
import { steeringEnabled } from "./steering.js";
|
|
56
|
+
import { resolveApiKeySync } from "./cursor/credentials.js";
|
|
57
|
+
import { createSessionLivePublisher } from "./session-live-publisher.js";
|
|
56
58
|
import { StorageCoordinator, isTurnBoundaryEvent } from "./storage-coordinator.js";
|
|
57
59
|
import { decideToolCall, directCallEffect } from "./tool-policy.js";
|
|
60
|
+
import { retryReadOnlyToolCall } from "./tool-call-retry.js";
|
|
58
61
|
import { normalizeToolResult, toolCallErrorMessage } from "./tool-result.js";
|
|
59
62
|
import { estimateTurnCostFromApi, roundCostUsd, } from "./turn-cost.js";
|
|
60
63
|
import { TurnGovernor } from "./turn-governor.js";
|
|
61
64
|
import { TurnLeaseStore } from "./turn-lease-store.js";
|
|
62
65
|
import { TurnOutbox } from "./turn-outbox.js";
|
|
63
|
-
import { resolveAgentV2Hosting } from "./v2-hosting.js";
|
|
66
|
+
import { isCursorManagedV2Hosting, resolveAgentV2Hosting } from "./v2-hosting.js";
|
|
64
67
|
import { buildAgentsMdContent, buildCloudMemorySection, buildCloudSessionWorkspaceSection, buildCloudWorkspaceSection, ensureOwnGitRoot, isNestedInGitRepo, materializeWorkspace, SERVER_TOOLS_MCP_SERVER_NAME, } from "./workspace.js";
|
|
65
68
|
import { syncSessionWorkspaceFiles, syncWorkspaceToStore, WorkspaceFileRefusal, wipeSessionWorkspace, } from "./workspace-sync.js";
|
|
66
69
|
export const HTTP_CHANNEL_ID = "http";
|
|
@@ -274,7 +277,7 @@ export class SessionEngine {
|
|
|
274
277
|
this.askDedupe = new SlackAskDedupeStore(join(options.stateRoot, "slack-asks"));
|
|
275
278
|
this.turnLeases = new TurnLeaseStore(join(options.stateRoot, "turn-leases"));
|
|
276
279
|
this.outbox = new TurnOutbox(join(options.stateRoot, "outbox"));
|
|
277
|
-
this.logs = new EventLogStore(sessionId => this.sessions.eventFilePath(sessionId), (sessionId, error) => this.logger(`[bdk] failed to persist events for ${sessionId}: ${describeError(error)}`));
|
|
280
|
+
this.logs = new EventLogStore((sessionId) => this.sessions.eventFilePath(sessionId), (sessionId, error) => this.logger(`[bdk] failed to persist events for ${sessionId}: ${describeError(error)}`));
|
|
278
281
|
// Framework session state (records, event chunks, continuations) is
|
|
279
282
|
// mirrored to whatever this selects; see framework-storage-selection.ts
|
|
280
283
|
// for why the choice does not belong to the agent author.
|
|
@@ -292,14 +295,24 @@ export class SessionEngine {
|
|
|
292
295
|
logger: this.logger,
|
|
293
296
|
keys: storageKeysForArchitecture(options.project.agent.architecture),
|
|
294
297
|
});
|
|
298
|
+
const v2Hosting = resolveAgentV2Hosting({
|
|
299
|
+
architecture: options.project.agent.architecture,
|
|
300
|
+
});
|
|
301
|
+
// Author KV stays on disk for a persistent slot: `/state/kv` is durable
|
|
302
|
+
// and already holds entries a switch to the store would hide.
|
|
303
|
+
const authorKvStorage = v2Hosting.kind === "cursor-managed-persistent" ? undefined : this.storage;
|
|
295
304
|
this.kvApi = createHostKvApi({
|
|
296
305
|
agentName: options.project.name,
|
|
297
306
|
stateRoot: options.stateRoot,
|
|
298
|
-
...(
|
|
299
|
-
});
|
|
300
|
-
const v2Hosting = resolveAgentV2Hosting({
|
|
301
|
-
architecture: options.project.agent.architecture,
|
|
307
|
+
...(authorKvStorage === undefined ? {} : { storage: authorKvStorage }),
|
|
302
308
|
});
|
|
309
|
+
this.livePublisher = isCursorManagedV2Hosting(v2Hosting)
|
|
310
|
+
? createSessionLivePublisher({
|
|
311
|
+
readEvents: (sessionId, fromIndex) => this.listEvents(sessionId, fromIndex),
|
|
312
|
+
resolveApiKey: () => resolveApiKeySync()?.apiKey,
|
|
313
|
+
logger: this.logger,
|
|
314
|
+
})
|
|
315
|
+
: undefined;
|
|
303
316
|
const managedV2Files = v2Hosting.kind === "cursor-managed"
|
|
304
317
|
? () => cursorHostedFiles({
|
|
305
318
|
resolveStoreSourceId: () => v2Hosting.resolveStoreIds().deploymentStoreSourceId,
|
|
@@ -332,7 +345,7 @@ export class SessionEngine {
|
|
|
332
345
|
this.mcpHost = new McpHost([
|
|
333
346
|
...options.project.agent.connections,
|
|
334
347
|
...(options.project.agent.hostConnections ?? []),
|
|
335
|
-
].filter(connection => !isSymbolicConnectionTransport(connection.transport)));
|
|
348
|
+
].filter((connection) => !isSymbolicConnectionTransport(connection.transport)));
|
|
336
349
|
const basePlatforms = options.platforms ?? createHostPlatforms();
|
|
337
350
|
const slackBinding = resolveDedicatedSlackHostBinding(options.project.channels);
|
|
338
351
|
this.platforms =
|
|
@@ -378,8 +391,8 @@ export class SessionEngine {
|
|
|
378
391
|
}
|
|
379
392
|
}
|
|
380
393
|
authoredConnection(name) {
|
|
381
|
-
return (this.project.agent.connections.find(item => item.name === name) ??
|
|
382
|
-
this.project.agent.hostConnections?.find(item => item.name === name));
|
|
394
|
+
return (this.project.agent.connections.find((item) => item.name === name) ??
|
|
395
|
+
this.project.agent.hostConnections?.find((item) => item.name === name));
|
|
383
396
|
}
|
|
384
397
|
setCloudServerToolsConnection(connection, resolveHeaders) {
|
|
385
398
|
this.cloudServerToolsConnection = connection;
|
|
@@ -464,8 +477,8 @@ export class SessionEngine {
|
|
|
464
477
|
turnId: input.turnId ?? binding.turnId,
|
|
465
478
|
});
|
|
466
479
|
},
|
|
467
|
-
list: filter => this.artifactsStore.list(filter),
|
|
468
|
-
page: options => this.artifactsStore.page(options),
|
|
480
|
+
list: (filter) => this.artifactsStore.list(filter),
|
|
481
|
+
page: (options) => this.artifactsStore.page(options),
|
|
469
482
|
};
|
|
470
483
|
}
|
|
471
484
|
/**
|
|
@@ -592,10 +605,10 @@ export class SessionEngine {
|
|
|
592
605
|
}
|
|
593
606
|
slackNudgeHostApi() {
|
|
594
607
|
return {
|
|
595
|
-
append: input => this.nudgeStore.append(input),
|
|
596
|
-
drainFormatted: continuationKey => this.nudgeStore.drainFormatted(continuationKey),
|
|
597
|
-
clear: continuationKey => this.nudgeStore.clear(continuationKey),
|
|
598
|
-
hasUndelivered: continuationKey => this.nudgeStore.hasUndelivered(continuationKey),
|
|
608
|
+
append: (input) => this.nudgeStore.append(input),
|
|
609
|
+
drainFormatted: (continuationKey) => this.nudgeStore.drainFormatted(continuationKey),
|
|
610
|
+
clear: (continuationKey) => this.nudgeStore.clear(continuationKey),
|
|
611
|
+
hasUndelivered: (continuationKey) => this.nudgeStore.hasUndelivered(continuationKey),
|
|
599
612
|
isDelivered: (continuationKey, sourceTs) => this.nudgeStore.isDelivered(continuationKey, sourceTs),
|
|
600
613
|
tryClaimAsk: (channelId, messageTs) => this.askDedupe.tryClaim(channelId, messageTs),
|
|
601
614
|
releaseAsk: (channelId, messageTs) => this.askDedupe.release(channelId, messageTs),
|
|
@@ -686,7 +699,7 @@ export class SessionEngine {
|
|
|
686
699
|
if (refreshWorkspace ||
|
|
687
700
|
sendOptions.workspaceFiles !== undefined ||
|
|
688
701
|
sendOptions.images !== undefined) {
|
|
689
|
-
record = await this.updateRecord(existing.sessionId, current => ({
|
|
702
|
+
record = await this.updateRecord(existing.sessionId, (current) => ({
|
|
690
703
|
...current,
|
|
691
704
|
workspaceOverride: refreshWorkspace
|
|
692
705
|
? sendOptions.workspaceDir
|
|
@@ -699,14 +712,14 @@ export class SessionEngine {
|
|
|
699
712
|
// configured runtime. Omission remains sticky for compatibility:
|
|
700
713
|
// follow-ups that do not know the original attach keep it.
|
|
701
714
|
if (sendOptions.clearCloudOverride === true && record.cloudOverride !== undefined) {
|
|
702
|
-
record = await this.updateRecord(record.sessionId, current => ({
|
|
715
|
+
record = await this.updateRecord(record.sessionId, (current) => ({
|
|
703
716
|
...current,
|
|
704
717
|
cloudOverride: undefined,
|
|
705
718
|
}));
|
|
706
719
|
}
|
|
707
720
|
else if (sendOptions.cloud !== undefined &&
|
|
708
721
|
JSON.stringify(sendOptions.cloud) !== JSON.stringify(record.cloudOverride)) {
|
|
709
|
-
record = await this.updateRecord(record.sessionId, current => ({
|
|
722
|
+
record = await this.updateRecord(record.sessionId, (current) => ({
|
|
710
723
|
...current,
|
|
711
724
|
cloudOverride: sendOptions.cloud,
|
|
712
725
|
}));
|
|
@@ -714,7 +727,7 @@ export class SessionEngine {
|
|
|
714
727
|
// Refresh wake-derived channel state (GitHub headSha / refs) without
|
|
715
728
|
// wiping sticky fields. Null patch values are skipped.
|
|
716
729
|
if (sendOptions.refreshState !== undefined) {
|
|
717
|
-
record = await this.updateRecord(record.sessionId, current => ({
|
|
730
|
+
record = await this.updateRecord(record.sessionId, (current) => ({
|
|
718
731
|
...current,
|
|
719
732
|
channelState: mergeChannelStateSkipNull(current.channelState, sendOptions.refreshState),
|
|
720
733
|
}));
|
|
@@ -791,7 +804,7 @@ export class SessionEngine {
|
|
|
791
804
|
const stale = new Error("stale HTTP continuation");
|
|
792
805
|
let previous;
|
|
793
806
|
try {
|
|
794
|
-
await this.updateRecord(sessionId, record => {
|
|
807
|
+
await this.updateRecord(sessionId, (record) => {
|
|
795
808
|
const expectedChannel = record.httpContinuationKey === undefined ? record.channelId : HTTP_CHANNEL_ID;
|
|
796
809
|
const expectedKey = record.httpContinuationKey ?? record.continuationKey;
|
|
797
810
|
if (token.channelId !== expectedChannel || token.key !== expectedKey) {
|
|
@@ -812,7 +825,7 @@ export class SessionEngine {
|
|
|
812
825
|
return next;
|
|
813
826
|
}
|
|
814
827
|
catch (error) {
|
|
815
|
-
await this.updateRecord(sessionId, record => record.httpContinuationKey === next ? { ...record, httpContinuationKey: previous } : record);
|
|
828
|
+
await this.updateRecord(sessionId, (record) => record.httpContinuationKey === next ? { ...record, httpContinuationKey: previous } : record);
|
|
816
829
|
throw error;
|
|
817
830
|
}
|
|
818
831
|
}
|
|
@@ -939,7 +952,7 @@ export class SessionEngine {
|
|
|
939
952
|
drainOutbox(sessionId) {
|
|
940
953
|
void this.outbox
|
|
941
954
|
.takeAll(sessionId)
|
|
942
|
-
.then(items => {
|
|
955
|
+
.then((items) => {
|
|
943
956
|
for (const item of items) {
|
|
944
957
|
void this.startTurn(sessionId, item.message, item.options).catch(() => { });
|
|
945
958
|
}
|
|
@@ -948,7 +961,7 @@ export class SessionEngine {
|
|
|
948
961
|
}
|
|
949
962
|
enqueueCoalesced(sessionId, item) {
|
|
950
963
|
const queue = this.coalesceQueues.get(sessionId) ?? [];
|
|
951
|
-
if (item.sourceTs !== undefined && queue.some(entry => entry.sourceTs === item.sourceTs)) {
|
|
964
|
+
if (item.sourceTs !== undefined && queue.some((entry) => entry.sourceTs === item.sourceTs)) {
|
|
952
965
|
return;
|
|
953
966
|
}
|
|
954
967
|
queue.push(item);
|
|
@@ -1124,7 +1137,7 @@ export class SessionEngine {
|
|
|
1124
1137
|
this.pendingTurns.add(sessionId);
|
|
1125
1138
|
let lifecycleInstalled = false;
|
|
1126
1139
|
try {
|
|
1127
|
-
const record = await this.updateRecord(sessionId, current => ({
|
|
1140
|
+
const record = await this.updateRecord(sessionId, (current) => ({
|
|
1128
1141
|
...current,
|
|
1129
1142
|
turnCount: current.turnCount + 1,
|
|
1130
1143
|
}));
|
|
@@ -1175,7 +1188,7 @@ export class SessionEngine {
|
|
|
1175
1188
|
// Failed or cancelled owners must not start a coalesced successor;
|
|
1176
1189
|
// managed delivery retries the same follow-ups.
|
|
1177
1190
|
if (wasCurrent && !abort.signal.aborted && outcome.status === "finished") {
|
|
1178
|
-
const drain = this.drainCoalescedFollowups(sessionId).catch(error => {
|
|
1191
|
+
const drain = this.drainCoalescedFollowups(sessionId).catch((error) => {
|
|
1179
1192
|
this.logger(`[session] coalesce drain failed for ${sessionId}: ${describeError(error)}`);
|
|
1180
1193
|
});
|
|
1181
1194
|
this.coalesceDrains.set(sessionId, drain);
|
|
@@ -1391,7 +1404,7 @@ export class SessionEngine {
|
|
|
1391
1404
|
if (turn === undefined) {
|
|
1392
1405
|
return tools;
|
|
1393
1406
|
}
|
|
1394
|
-
return tools.map(tool => {
|
|
1407
|
+
return tools.map((tool) => {
|
|
1395
1408
|
const execute = tool.definition.execute;
|
|
1396
1409
|
if (typeof execute !== "function") {
|
|
1397
1410
|
return tool;
|
|
@@ -1586,7 +1599,7 @@ export class SessionEngine {
|
|
|
1586
1599
|
// the turns' requests or the warmed executor is one no turn asks for.
|
|
1587
1600
|
mcpServers: this.buildMcpServers("local"),
|
|
1588
1601
|
...(this.hasAttachedAuthedConnections() ||
|
|
1589
|
-
this.project.agent.connections.some(connection => isCursorAccountTransport(connection.transport))
|
|
1602
|
+
this.project.agent.connections.some((connection) => isCursorAccountTransport(connection.transport))
|
|
1590
1603
|
? { perSendMcpServers: true }
|
|
1591
1604
|
: {}),
|
|
1592
1605
|
subagents: buildRunnerSubagents(agent),
|
|
@@ -1637,7 +1650,7 @@ export class SessionEngine {
|
|
|
1637
1650
|
// Read by closure, so the mapper still sees it while draining after the
|
|
1638
1651
|
// registry entry below is gone.
|
|
1639
1652
|
const stubbed = new Set();
|
|
1640
|
-
const mapper = new TurnEventMapper(emit, callId => stubbed.has(callId));
|
|
1653
|
+
const mapper = new TurnEventMapper(emit, (callId) => stubbed.has(callId));
|
|
1641
1654
|
// Take a turn slot before any work happens. When every slot is busy the
|
|
1642
1655
|
// turn waits FIFO — durable `turn.queued` marks the wait — and a
|
|
1643
1656
|
// preempting follow-up (or interrupt) resolves the wait as cancelled
|
|
@@ -1645,7 +1658,7 @@ export class SessionEngine {
|
|
|
1645
1658
|
const permit = await this.turnGovernor.acquire({
|
|
1646
1659
|
sessionId,
|
|
1647
1660
|
signal,
|
|
1648
|
-
onQueued: position => {
|
|
1661
|
+
onQueued: (position) => {
|
|
1649
1662
|
const maxRunningTurns = this.turnGovernor.maxRunningTurns ?? 0;
|
|
1650
1663
|
emit({ type: "turn.queued", data: { position, maxRunningTurns } });
|
|
1651
1664
|
this.logger(`[session] ${sessionId} ${turnId} queued at position ${position} (${maxRunningTurns} turn slot(s) busy)`);
|
|
@@ -1704,7 +1717,7 @@ export class SessionEngine {
|
|
|
1704
1717
|
}
|
|
1705
1718
|
if ((hasPendingFiles && runtime !== "cloud") ||
|
|
1706
1719
|
(pendingImages !== undefined && pendingImages.length > 0)) {
|
|
1707
|
-
await this.updateRecord(sessionId, current => ({
|
|
1720
|
+
await this.updateRecord(sessionId, (current) => ({
|
|
1708
1721
|
...current,
|
|
1709
1722
|
pendingWorkspaceFiles: hasPendingFiles &&
|
|
1710
1723
|
runtime !== "cloud" &&
|
|
@@ -1772,7 +1785,7 @@ export class SessionEngine {
|
|
|
1772
1785
|
mapper.finish();
|
|
1773
1786
|
if (mapper.title !== undefined) {
|
|
1774
1787
|
const title = mapper.title;
|
|
1775
|
-
await this.updateRecord(sessionId, current => ({ ...current, title }));
|
|
1788
|
+
await this.updateRecord(sessionId, (current) => ({ ...current, title }));
|
|
1776
1789
|
eventContext.session = { ...eventContext.session, title };
|
|
1777
1790
|
}
|
|
1778
1791
|
const finalResult = outcome.result ?? mapper.finalText;
|
|
@@ -1832,7 +1845,7 @@ export class SessionEngine {
|
|
|
1832
1845
|
// dispatch, and awaiting that chain deadlocks when an earlier handler
|
|
1833
1846
|
// is waiting on the next turn (defineResult refresh). Coalesce drain
|
|
1834
1847
|
// snapshots disk as soon as this returns.
|
|
1835
|
-
await this.updateRecord(sessionId, current => ({
|
|
1848
|
+
await this.updateRecord(sessionId, (current) => ({
|
|
1836
1849
|
...current,
|
|
1837
1850
|
channelState: mergeChannelStateMutation({
|
|
1838
1851
|
current: current.channelState,
|
|
@@ -1912,7 +1925,7 @@ export class SessionEngine {
|
|
|
1912
1925
|
}
|
|
1913
1926
|
}
|
|
1914
1927
|
async clearPendingWorkspaceFiles(sessionId, pending) {
|
|
1915
|
-
await this.updateRecord(sessionId, current => ({
|
|
1928
|
+
await this.updateRecord(sessionId, (current) => ({
|
|
1916
1929
|
...current,
|
|
1917
1930
|
pendingWorkspaceFiles: current.pendingWorkspaceFiles === pending ? undefined : current.pendingWorkspaceFiles,
|
|
1918
1931
|
}));
|
|
@@ -1929,7 +1942,7 @@ export class SessionEngine {
|
|
|
1929
1942
|
if (inFlight !== undefined) {
|
|
1930
1943
|
return inFlight;
|
|
1931
1944
|
}
|
|
1932
|
-
let sync = run().then(() => true, error => {
|
|
1945
|
+
let sync = run().then(() => true, (error) => {
|
|
1933
1946
|
this.logger(`[${surface}] ${store.label} sync failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1934
1947
|
return false;
|
|
1935
1948
|
});
|
|
@@ -2016,7 +2029,7 @@ export class SessionEngine {
|
|
|
2016
2029
|
// per-session tools or identity is worse than a refused one. Non-local
|
|
2017
2030
|
// agents already fail discovery; this guards hybrid agents' per-send
|
|
2018
2031
|
// cloud sessions.
|
|
2019
|
-
const perSessionConnection = agent.connections.find(connection => connection.advertiseTools === true || connection.auth !== undefined);
|
|
2032
|
+
const perSessionConnection = agent.connections.find((connection) => connection.advertiseTools === true || connection.auth !== undefined);
|
|
2020
2033
|
if (runtime !== "local" && perSessionConnection !== undefined) {
|
|
2021
2034
|
throw new Error(`Agent "${agent.name}" connection "${perSessionConnection.name}" uses advertiseTools/auth, which only run on local turns. Refusing the session rather than running it without the connection's tools or identity.`);
|
|
2022
2035
|
}
|
|
@@ -2055,7 +2068,7 @@ export class SessionEngine {
|
|
|
2055
2068
|
// replace a working index with an empty custom tool.
|
|
2056
2069
|
const synthesized = root === undefined
|
|
2057
2070
|
? []
|
|
2058
|
-
: this.withTurnScratchTools(authoredRoot ? fileTools : fileTools.filter(tool => tool.name !== "SemanticSearch"), record.sessionId);
|
|
2071
|
+
: this.withTurnScratchTools(authoredRoot ? fileTools : fileTools.filter((tool) => tool.name !== "SemanticSearch"), record.sessionId);
|
|
2059
2072
|
let turnPrompt = prompt;
|
|
2060
2073
|
if (isFirstTurn) {
|
|
2061
2074
|
const contextBlock = buildSessionContextBlock({
|
|
@@ -2120,7 +2133,7 @@ export class SessionEngine {
|
|
|
2120
2133
|
sections.push(buildCloudMemorySection(this.project.name));
|
|
2121
2134
|
}
|
|
2122
2135
|
if (preamble !== "" || sections.length > 0) {
|
|
2123
|
-
turnPrompt = [preamble, ...sections, turnPrompt].filter(part => part !== "").join("\n\n");
|
|
2136
|
+
turnPrompt = [preamble, ...sections, turnPrompt].filter((part) => part !== "").join("\n\n");
|
|
2124
2137
|
}
|
|
2125
2138
|
}
|
|
2126
2139
|
else if (isFirstTurn && runtime === "local" && authoredRoot) {
|
|
@@ -2172,11 +2185,13 @@ export class SessionEngine {
|
|
|
2172
2185
|
...(runtime === "cloud" && !isCursorHostedFilesAvailable()
|
|
2173
2186
|
? { agentServeAgent: this.project.name }
|
|
2174
2187
|
: {}),
|
|
2175
|
-
customTools: runtime === "local"
|
|
2188
|
+
customTools: runtime === "local"
|
|
2189
|
+
? await this.buildCustomTools(record, turnId, emit, synthesized, signal)
|
|
2190
|
+
: {},
|
|
2176
2191
|
mcpServers: this.buildMcpServers(runtime, record.sessionId, await this.evaluateConnectionAuth(record)),
|
|
2177
2192
|
...(runtime === "local" &&
|
|
2178
2193
|
(this.hasAttachedAuthedConnections() ||
|
|
2179
|
-
this.project.agent.connections.some(connection => isCursorAccountTransport(connection.transport)))
|
|
2194
|
+
this.project.agent.connections.some((connection) => isCursorAccountTransport(connection.transport)))
|
|
2180
2195
|
? { perSendMcpServers: true }
|
|
2181
2196
|
: {}),
|
|
2182
2197
|
subagents: buildRunnerSubagents(agent),
|
|
@@ -2185,14 +2200,14 @@ export class SessionEngine {
|
|
|
2185
2200
|
// Local follow-ups expire any lingering active run so a preempted turn
|
|
2186
2201
|
// (or one orphaned by a crashed process) never blocks this send.
|
|
2187
2202
|
forceExpireActiveRun: runtime === "local" && !isFirstTurn,
|
|
2188
|
-
onRequestId: requestId => {
|
|
2203
|
+
onRequestId: (requestId) => {
|
|
2189
2204
|
emit({ type: "turn.bound", data: { requestId } });
|
|
2190
2205
|
},
|
|
2191
2206
|
onSdkAgentId: async (sdkAgentId) => {
|
|
2192
2207
|
if (record.sdkAgentId === sdkAgentId) {
|
|
2193
2208
|
return;
|
|
2194
2209
|
}
|
|
2195
|
-
await this.updateRecord(record.sessionId, current => ({
|
|
2210
|
+
await this.updateRecord(record.sessionId, (current) => ({
|
|
2196
2211
|
...current,
|
|
2197
2212
|
sdkAgentId,
|
|
2198
2213
|
}));
|
|
@@ -2275,9 +2290,9 @@ export class SessionEngine {
|
|
|
2275
2290
|
// Advertised connections surface as named server tools instead of an
|
|
2276
2291
|
// attached MCP server (each tool appears exactly once).
|
|
2277
2292
|
const advertisedNames = new Set(this.project.agent.connections
|
|
2278
|
-
.filter(connection => connection.advertiseTools === true)
|
|
2279
|
-
.map(connection => connection.name));
|
|
2280
|
-
const hostConnectionNames = new Set((this.project.agent.hostConnections ?? []).map(connection => connection.name));
|
|
2293
|
+
.filter((connection) => connection.advertiseTools === true)
|
|
2294
|
+
.map((connection) => connection.name));
|
|
2295
|
+
const hostConnectionNames = new Set((this.project.agent.hostConnections ?? []).map((connection) => connection.name));
|
|
2281
2296
|
const bridgedNames = new Set(runtime === "cloud" &&
|
|
2282
2297
|
sessionId !== undefined &&
|
|
2283
2298
|
this.cloudServerToolsConnection !== undefined &&
|
|
@@ -2286,7 +2301,7 @@ export class SessionEngine {
|
|
|
2286
2301
|
: []);
|
|
2287
2302
|
assertCloudCanHonorAccountServersFilters({
|
|
2288
2303
|
runtime,
|
|
2289
|
-
resolvedConnections: this.resolvedConnections.filter(resolved => !advertisedNames.has(resolved.name) && !hostConnectionNames.has(resolved.name)),
|
|
2304
|
+
resolvedConnections: this.resolvedConnections.filter((resolved) => !advertisedNames.has(resolved.name) && !hostConnectionNames.has(resolved.name)),
|
|
2290
2305
|
bridgedNames,
|
|
2291
2306
|
});
|
|
2292
2307
|
const bridgeTransport = (name) => sessionId === undefined || !bridgedNames.has(name)
|
|
@@ -2368,7 +2383,7 @@ export class SessionEngine {
|
|
|
2368
2383
|
if (runtime === "cloud" &&
|
|
2369
2384
|
sessionId !== undefined &&
|
|
2370
2385
|
this.cloudServerToolsConnection !== undefined &&
|
|
2371
|
-
this.project.agent.tools.some(tool => tool.execution === "server")) {
|
|
2386
|
+
this.project.agent.tools.some((tool) => tool.execution === "server")) {
|
|
2372
2387
|
if (servers[SERVER_TOOLS_MCP_SERVER_NAME] !== undefined) {
|
|
2373
2388
|
throw new Error(`MCP connection name "${SERVER_TOOLS_MCP_SERVER_NAME}" is reserved for authored server tools on cloud turns.`);
|
|
2374
2389
|
}
|
|
@@ -2391,7 +2406,7 @@ export class SessionEngine {
|
|
|
2391
2406
|
* ride every send instead of being pinned on the cached agent handle.
|
|
2392
2407
|
*/
|
|
2393
2408
|
hasAttachedAuthedConnections() {
|
|
2394
|
-
return this.project.agent.connections.some(connection => connection.auth !== undefined && connection.advertiseTools !== true);
|
|
2409
|
+
return this.project.agent.connections.some((connection) => connection.auth !== undefined && connection.advertiseTools !== true);
|
|
2395
2410
|
}
|
|
2396
2411
|
/**
|
|
2397
2412
|
* Evaluate per-session connection auth (`defineConnection({ auth })`)
|
|
@@ -2401,7 +2416,7 @@ export class SessionEngine {
|
|
|
2401
2416
|
* without the connection's identity.
|
|
2402
2417
|
*/
|
|
2403
2418
|
async evaluateConnectionAuth(record) {
|
|
2404
|
-
const authed = this.project.agent.connections.filter(connection => connection.auth !== undefined && connection.advertiseTools !== true);
|
|
2419
|
+
const authed = this.project.agent.connections.filter((connection) => connection.auth !== undefined && connection.advertiseTools !== true);
|
|
2405
2420
|
if (authed.length === 0) {
|
|
2406
2421
|
return undefined;
|
|
2407
2422
|
}
|
|
@@ -2423,7 +2438,7 @@ export class SessionEngine {
|
|
|
2423
2438
|
}
|
|
2424
2439
|
return evaluated;
|
|
2425
2440
|
}
|
|
2426
|
-
async buildCustomTools(record, turnId, emit, extraTools = []) {
|
|
2441
|
+
async buildCustomTools(record, turnId, emit, extraTools = [], signal) {
|
|
2427
2442
|
const agent = this.project.agent;
|
|
2428
2443
|
const tools = {};
|
|
2429
2444
|
const register = (tool) => {
|
|
@@ -2447,6 +2462,7 @@ export class SessionEngine {
|
|
|
2447
2462
|
record,
|
|
2448
2463
|
turnId,
|
|
2449
2464
|
emit,
|
|
2465
|
+
signal,
|
|
2450
2466
|
});
|
|
2451
2467
|
},
|
|
2452
2468
|
};
|
|
@@ -2494,7 +2510,7 @@ export class SessionEngine {
|
|
|
2494
2510
|
if (active === undefined) {
|
|
2495
2511
|
return toolErrorResult(`Session ${sessionId} has no active turn for tool "${toolName}".`);
|
|
2496
2512
|
}
|
|
2497
|
-
const tool = this.project.agent.tools.find(candidate => candidate.name === toolName && candidate.execution === "server");
|
|
2513
|
+
const tool = this.project.agent.tools.find((candidate) => candidate.name === toolName && candidate.execution === "server");
|
|
2498
2514
|
if (tool === undefined) {
|
|
2499
2515
|
return toolErrorResult(`Unknown server tool "${toolName}".`);
|
|
2500
2516
|
}
|
|
@@ -2507,6 +2523,7 @@ export class SessionEngine {
|
|
|
2507
2523
|
record: active.record,
|
|
2508
2524
|
turnId: active.turnId,
|
|
2509
2525
|
emit: active.emit,
|
|
2526
|
+
signal: this.turnAborts.get(sessionId)?.signal,
|
|
2510
2527
|
});
|
|
2511
2528
|
this.logger(`[session] cloud HTTP MCP tool ${toolName} complete (${sessionId}, ${toolCallId}, isError=${isErrorEnvelope(result)})`);
|
|
2512
2529
|
return result;
|
|
@@ -2607,7 +2624,14 @@ export class SessionEngine {
|
|
|
2607
2624
|
callId: toolCallId,
|
|
2608
2625
|
toolName: args.tool.name,
|
|
2609
2626
|
emit: args.emit,
|
|
2610
|
-
}, () =>
|
|
2627
|
+
}, () => this.runExecutedTool({
|
|
2628
|
+
tool: args.tool,
|
|
2629
|
+
input: validation.value,
|
|
2630
|
+
callId: toolCallId,
|
|
2631
|
+
signal: args.signal,
|
|
2632
|
+
emit: args.emit,
|
|
2633
|
+
execute: () => execute(validation.value, toolCtx),
|
|
2634
|
+
})));
|
|
2611
2635
|
this.logger(`[session] tool ${args.tool.name} done (${Date.now() - started}ms)`);
|
|
2612
2636
|
return normalizeToolResult(result);
|
|
2613
2637
|
}
|
|
@@ -2651,6 +2675,34 @@ export class SessionEngine {
|
|
|
2651
2675
|
toolName: args.toolName,
|
|
2652
2676
|
}, run);
|
|
2653
2677
|
}
|
|
2678
|
+
/**
|
|
2679
|
+
* Retry a read-effect call that already passed validation, dry-run, and
|
|
2680
|
+
* approval. Anything else runs once; a transient failure there is counted
|
|
2681
|
+
* and rethrown unchanged.
|
|
2682
|
+
*/
|
|
2683
|
+
runExecutedTool(args) {
|
|
2684
|
+
const connection = args.tool.connection;
|
|
2685
|
+
return retryReadOnlyToolCall({
|
|
2686
|
+
toolName: args.tool.name,
|
|
2687
|
+
...(connection === undefined ? {} : { connection }),
|
|
2688
|
+
effect: directCallEffect(args.tool, args.input),
|
|
2689
|
+
signal: args.signal,
|
|
2690
|
+
onRetry: (notice) => {
|
|
2691
|
+
this.logger(`[session] tool ${args.tool.name} retry connection=${notice.connection ?? "-"} attempt=${notice.attempt} class=${notice.reason} backoffMs=${notice.backoffMs}`);
|
|
2692
|
+
args.emit?.({
|
|
2693
|
+
type: "action.tool_retry",
|
|
2694
|
+
data: {
|
|
2695
|
+
callId: args.callId,
|
|
2696
|
+
toolName: args.tool.name,
|
|
2697
|
+
attempt: notice.attempt,
|
|
2698
|
+
reason: notice.reason,
|
|
2699
|
+
...(notice.connection === undefined ? {} : { connection: notice.connection }),
|
|
2700
|
+
},
|
|
2701
|
+
});
|
|
2702
|
+
},
|
|
2703
|
+
execute: args.execute,
|
|
2704
|
+
});
|
|
2705
|
+
}
|
|
2654
2706
|
/**
|
|
2655
2707
|
* Park a server-tool call until a human approves or denies. Emits
|
|
2656
2708
|
* `action.approval_requested` / `action.approval_resolved` on the
|
|
@@ -2666,10 +2718,10 @@ export class SessionEngine {
|
|
|
2666
2718
|
requestedAt,
|
|
2667
2719
|
};
|
|
2668
2720
|
const resolutionPromise = this.approvals.wait(args.sessionId, pendingRecord);
|
|
2669
|
-
await this.updateRecord(args.sessionId, current => ({
|
|
2721
|
+
await this.updateRecord(args.sessionId, (current) => ({
|
|
2670
2722
|
...current,
|
|
2671
2723
|
pendingApprovals: [
|
|
2672
|
-
...(current.pendingApprovals ?? []).filter(item => item.callId !== args.callId),
|
|
2724
|
+
...(current.pendingApprovals ?? []).filter((item) => item.callId !== args.callId),
|
|
2673
2725
|
pendingRecord,
|
|
2674
2726
|
],
|
|
2675
2727
|
}));
|
|
@@ -2683,9 +2735,9 @@ export class SessionEngine {
|
|
|
2683
2735
|
});
|
|
2684
2736
|
this.logger(`[session] tool ${args.toolName} awaiting approval (${args.callId})`);
|
|
2685
2737
|
const { decision, by } = await resolutionPromise;
|
|
2686
|
-
await this.updateRecord(args.sessionId, current => ({
|
|
2738
|
+
await this.updateRecord(args.sessionId, (current) => ({
|
|
2687
2739
|
...current,
|
|
2688
|
-
pendingApprovals: (current.pendingApprovals ?? []).filter(item => item.callId !== args.callId),
|
|
2740
|
+
pendingApprovals: (current.pendingApprovals ?? []).filter((item) => item.callId !== args.callId),
|
|
2689
2741
|
}));
|
|
2690
2742
|
args.emit({
|
|
2691
2743
|
type: "action.approval_resolved",
|
|
@@ -2706,7 +2758,7 @@ export class SessionEngine {
|
|
|
2706
2758
|
current.pendingApprovals.length === 0) {
|
|
2707
2759
|
return;
|
|
2708
2760
|
}
|
|
2709
|
-
await this.updateRecord(sessionId, record => ({
|
|
2761
|
+
await this.updateRecord(sessionId, (record) => ({
|
|
2710
2762
|
...record,
|
|
2711
2763
|
pendingApprovals: [],
|
|
2712
2764
|
}));
|
|
@@ -2740,8 +2792,8 @@ export class SessionEngine {
|
|
|
2740
2792
|
if (!samePrincipal(record.auth, ownershipAuth)) {
|
|
2741
2793
|
throw new SessionAuthError(sessionId);
|
|
2742
2794
|
}
|
|
2743
|
-
const pending = (record.pendingApprovals ?? []).find(item => item.callId === callId) ??
|
|
2744
|
-
this.approvals.list(sessionId).find(item => item.callId === callId);
|
|
2795
|
+
const pending = (record.pendingApprovals ?? []).find((item) => item.callId === callId) ??
|
|
2796
|
+
this.approvals.list(sessionId).find((item) => item.callId === callId);
|
|
2745
2797
|
if (pending === undefined) {
|
|
2746
2798
|
throw new ApprovalNotFoundError(sessionId, callId);
|
|
2747
2799
|
}
|
|
@@ -2753,23 +2805,23 @@ export class SessionEngine {
|
|
|
2753
2805
|
return pending;
|
|
2754
2806
|
}
|
|
2755
2807
|
async removePendingApproval(sessionId, callId) {
|
|
2756
|
-
await this.updateRecord(sessionId, current => ({
|
|
2808
|
+
await this.updateRecord(sessionId, (current) => ({
|
|
2757
2809
|
...current,
|
|
2758
|
-
pendingApprovals: (current.pendingApprovals ?? []).filter(item => item.callId !== callId),
|
|
2810
|
+
pendingApprovals: (current.pendingApprovals ?? []).filter((item) => item.callId !== callId),
|
|
2759
2811
|
}));
|
|
2760
2812
|
}
|
|
2761
2813
|
wrapMcp(inner) {
|
|
2762
2814
|
return {
|
|
2763
2815
|
names: () => inner.names(),
|
|
2764
|
-
listTools: name => this.withMcpAuth(name, () => inner.listTools(name)),
|
|
2816
|
+
listTools: (name) => this.withMcpAuth(name, () => inner.listTools(name)),
|
|
2765
2817
|
callTool: (name, tool, args) => this.withMcpAuth(name, () => inner.callTool(name, tool, args)),
|
|
2766
2818
|
};
|
|
2767
2819
|
}
|
|
2768
2820
|
advertiseMcp() {
|
|
2769
2821
|
return {
|
|
2770
|
-
listTools: name => this.withMcpListAuth(name, () => this.mcpHost.listTools(name)),
|
|
2822
|
+
listTools: (name) => this.withMcpListAuth(name, () => this.mcpHost.listTools(name)),
|
|
2771
2823
|
callTool: (name, tool, args) => this.withMcpAuth(name, () => this.mcpHost.callTool(name, tool, args)),
|
|
2772
|
-
oneOff: connection => {
|
|
2824
|
+
oneOff: (connection) => {
|
|
2773
2825
|
const inner = this.mcpHost.oneOff(connection);
|
|
2774
2826
|
return {
|
|
2775
2827
|
listTools: () => this.withMcpListAuth(connection.name, () => inner.listTools()),
|
|
@@ -2885,10 +2937,10 @@ export class SessionEngine {
|
|
|
2885
2937
|
requestedAt,
|
|
2886
2938
|
};
|
|
2887
2939
|
const resolutionPromise = this.auths.wait(args.sessionId, pendingRecord);
|
|
2888
|
-
await this.updateRecord(args.sessionId, current => ({
|
|
2940
|
+
await this.updateRecord(args.sessionId, (current) => ({
|
|
2889
2941
|
...current,
|
|
2890
2942
|
pendingAuths: [
|
|
2891
|
-
...(current.pendingAuths ?? []).filter(item => item.callId !== args.callId),
|
|
2943
|
+
...(current.pendingAuths ?? []).filter((item) => item.callId !== args.callId),
|
|
2892
2944
|
pendingRecord,
|
|
2893
2945
|
],
|
|
2894
2946
|
}));
|
|
@@ -2903,9 +2955,9 @@ export class SessionEngine {
|
|
|
2903
2955
|
});
|
|
2904
2956
|
this.logger(`[session] tool ${args.toolName} awaiting MCP auth ${args.connection} (${args.callId})`);
|
|
2905
2957
|
const { decision, by } = await resolutionPromise;
|
|
2906
|
-
await this.updateRecord(args.sessionId, current => ({
|
|
2958
|
+
await this.updateRecord(args.sessionId, (current) => ({
|
|
2907
2959
|
...current,
|
|
2908
|
-
pendingAuths: (current.pendingAuths ?? []).filter(item => item.callId !== args.callId),
|
|
2960
|
+
pendingAuths: (current.pendingAuths ?? []).filter((item) => item.callId !== args.callId),
|
|
2909
2961
|
}));
|
|
2910
2962
|
args.emit({
|
|
2911
2963
|
type: "action.auth_resolved",
|
|
@@ -2928,7 +2980,7 @@ export class SessionEngine {
|
|
|
2928
2980
|
current.pendingAuths.length === 0) {
|
|
2929
2981
|
return;
|
|
2930
2982
|
}
|
|
2931
|
-
await this.updateRecord(sessionId, record => ({
|
|
2983
|
+
await this.updateRecord(sessionId, (record) => ({
|
|
2932
2984
|
...record,
|
|
2933
2985
|
pendingAuths: [],
|
|
2934
2986
|
}));
|
|
@@ -2953,8 +3005,8 @@ export class SessionEngine {
|
|
|
2953
3005
|
if (!samePrincipal(record.auth, ownershipAuth)) {
|
|
2954
3006
|
throw new SessionAuthError(sessionId);
|
|
2955
3007
|
}
|
|
2956
|
-
const pending = (record.pendingAuths ?? []).find(item => item.callId === callId) ??
|
|
2957
|
-
this.auths.list(sessionId).find(item => item.callId === callId);
|
|
3008
|
+
const pending = (record.pendingAuths ?? []).find((item) => item.callId === callId) ??
|
|
3009
|
+
this.auths.list(sessionId).find((item) => item.callId === callId);
|
|
2958
3010
|
if (pending === undefined) {
|
|
2959
3011
|
throw new AuthNotFoundError(sessionId, callId);
|
|
2960
3012
|
}
|
|
@@ -2969,9 +3021,9 @@ export class SessionEngine {
|
|
|
2969
3021
|
return pending;
|
|
2970
3022
|
}
|
|
2971
3023
|
async removePendingAuth(sessionId, callId) {
|
|
2972
|
-
await this.updateRecord(sessionId, current => ({
|
|
3024
|
+
await this.updateRecord(sessionId, (current) => ({
|
|
2973
3025
|
...current,
|
|
2974
|
-
pendingAuths: (current.pendingAuths ?? []).filter(item => item.callId !== callId),
|
|
3026
|
+
pendingAuths: (current.pendingAuths ?? []).filter((item) => item.callId !== callId),
|
|
2975
3027
|
}));
|
|
2976
3028
|
}
|
|
2977
3029
|
async runWithMcpPark(sessionId, toolName, fn) {
|
|
@@ -3113,16 +3165,16 @@ export class SessionEngine {
|
|
|
3113
3165
|
* fetch for `ls` must not wait on every advertised MCP server.
|
|
3114
3166
|
*/
|
|
3115
3167
|
async describeCatalogTool(toolName, options = {}) {
|
|
3116
|
-
const authored = this.project.agent.tools.find(tool => tool.name === toolName);
|
|
3168
|
+
const authored = this.project.agent.tools.find((tool) => tool.name === toolName);
|
|
3117
3169
|
if (authored !== undefined) {
|
|
3118
3170
|
return { tool: authored };
|
|
3119
3171
|
}
|
|
3120
3172
|
const catalog = await this.listCatalogTools(options);
|
|
3121
|
-
const tool = catalog.tools.find(entry => entry.name === toolName);
|
|
3173
|
+
const tool = catalog.tools.find((entry) => entry.name === toolName);
|
|
3122
3174
|
if (tool === undefined) {
|
|
3123
3175
|
return {
|
|
3124
3176
|
tool: undefined,
|
|
3125
|
-
availableTools: catalog.tools.map(entry => entry.name),
|
|
3177
|
+
availableTools: catalog.tools.map((entry) => entry.name),
|
|
3126
3178
|
connectionErrors: catalog.connectionErrors,
|
|
3127
3179
|
};
|
|
3128
3180
|
}
|
|
@@ -3156,8 +3208,9 @@ export class SessionEngine {
|
|
|
3156
3208
|
if (native !== undefined) {
|
|
3157
3209
|
return native;
|
|
3158
3210
|
}
|
|
3159
|
-
let tool = this.project.agent.tools.find(t => t.name === toolName);
|
|
3160
|
-
if (tool === undefined &&
|
|
3211
|
+
let tool = this.project.agent.tools.find((t) => t.name === toolName);
|
|
3212
|
+
if (tool === undefined &&
|
|
3213
|
+
this.project.agent.connections.some((c) => c.advertiseTools === true)) {
|
|
3161
3214
|
// Advertised passthroughs are ordinary server tools in the session's
|
|
3162
3215
|
// namespace; resolve the live listing so direct calls address them by
|
|
3163
3216
|
// the same model-facing name a turn would. A listing failure fails
|
|
@@ -3167,10 +3220,10 @@ export class SessionEngine {
|
|
|
3167
3220
|
session,
|
|
3168
3221
|
hostMcp: this.advertiseMcp(),
|
|
3169
3222
|
});
|
|
3170
|
-
tool = advertised.find(t => t.name === toolName);
|
|
3223
|
+
tool = advertised.find((t) => t.name === toolName);
|
|
3171
3224
|
}
|
|
3172
3225
|
if (tool === undefined) {
|
|
3173
|
-
throw new UnknownToolError(toolName, this.project.agent.tools.filter(t => t.execution === "server").map(t => t.name));
|
|
3226
|
+
throw new UnknownToolError(toolName, this.project.agent.tools.filter((t) => t.execution === "server").map((t) => t.name));
|
|
3174
3227
|
}
|
|
3175
3228
|
const execute = tool.definition.execute;
|
|
3176
3229
|
if (tool.execution !== "server" || typeof execute !== "function") {
|
|
@@ -3310,27 +3363,34 @@ export class SessionEngine {
|
|
|
3310
3363
|
isError = false;
|
|
3311
3364
|
}
|
|
3312
3365
|
else {
|
|
3313
|
-
const run = () =>
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3366
|
+
const run = () => this.runExecutedTool({
|
|
3367
|
+
tool,
|
|
3368
|
+
input: validation.value,
|
|
3369
|
+
callId,
|
|
3370
|
+
signal: record === undefined ? undefined : this.turnAborts.get(record.sessionId)?.signal,
|
|
3371
|
+
emit,
|
|
3372
|
+
execute: () => execute(validation.value, {
|
|
3373
|
+
toolCallId: callId,
|
|
3374
|
+
session,
|
|
3375
|
+
workspaceDir,
|
|
3376
|
+
stateRoot: this.stateRoot,
|
|
3377
|
+
host: this.hostForSession(record?.sessionId),
|
|
3378
|
+
// Scratch calls have no real session; their facade stays unbound.
|
|
3379
|
+
artifacts: record === undefined
|
|
3380
|
+
? this.artifactsApi()
|
|
3381
|
+
: this.artifactsApi({
|
|
3382
|
+
sessionId: record.sessionId,
|
|
3383
|
+
turnId: callId,
|
|
3384
|
+
}),
|
|
3385
|
+
send: (channelId, message, sendOptions = {}) => this.send(channelId, message, {
|
|
3386
|
+
...sendOptions,
|
|
3387
|
+
auth: sendOptions.auth !== undefined ? sendOptions.auth : session.auth,
|
|
3325
3388
|
}),
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3389
|
+
getSession: (channelId, sessionId) => this.getChannelSession(channelId, sessionId),
|
|
3390
|
+
emit,
|
|
3391
|
+
now: sessionClock(record?.asOf),
|
|
3392
|
+
...(record?.asOf === undefined ? {} : { asOf: record.asOf }),
|
|
3329
3393
|
}),
|
|
3330
|
-
getSession: (channelId, sessionId) => this.getChannelSession(channelId, sessionId),
|
|
3331
|
-
emit,
|
|
3332
|
-
now: sessionClock(record?.asOf),
|
|
3333
|
-
...(record?.asOf === undefined ? {} : { asOf: record.asOf }),
|
|
3334
3394
|
});
|
|
3335
3395
|
const executeBody = record !== undefined && emit !== undefined
|
|
3336
3396
|
? () => mcpAuthAls.run({
|
|
@@ -3480,7 +3540,7 @@ export class SessionEngine {
|
|
|
3480
3540
|
async bridgedToolInfo(connectionName, toolName) {
|
|
3481
3541
|
try {
|
|
3482
3542
|
const listed = await this.host.mcp.listTools(connectionName);
|
|
3483
|
-
return listed.find(tool => tool.name === toolName);
|
|
3543
|
+
return listed.find((tool) => tool.name === toolName);
|
|
3484
3544
|
}
|
|
3485
3545
|
catch {
|
|
3486
3546
|
return undefined;
|
|
@@ -3499,10 +3559,11 @@ export class SessionEngine {
|
|
|
3499
3559
|
// Single funnel for both append paths (appendEvent + the held-log emit),
|
|
3500
3560
|
// so the storage sink sees every durable event exactly once.
|
|
3501
3561
|
this.storage?.event(event);
|
|
3562
|
+
this.livePublisher?.event(event);
|
|
3502
3563
|
const chain = this.dispatchChains.get(sessionId) ?? Promise.resolve();
|
|
3503
3564
|
const next = chain
|
|
3504
3565
|
.then(() => this.dispatchEvent(sessionId, event, context))
|
|
3505
|
-
.catch(error => {
|
|
3566
|
+
.catch((error) => {
|
|
3506
3567
|
this.logger(`[bdk] event dispatch failed for ${sessionId}: ${describeError(error)}`);
|
|
3507
3568
|
})
|
|
3508
3569
|
.then(() => {
|
|
@@ -3559,10 +3620,10 @@ export class SessionEngine {
|
|
|
3559
3620
|
// context; merge turn-start → live so a last-event before/after cannot
|
|
3560
3621
|
// drop earlier handler writes.
|
|
3561
3622
|
if (context === undefined) {
|
|
3562
|
-
await this.updateRecord(sessionId, current => ({ ...current }));
|
|
3623
|
+
await this.updateRecord(sessionId, (current) => ({ ...current }));
|
|
3563
3624
|
}
|
|
3564
3625
|
else if (isTurnBoundaryEvent(event.type)) {
|
|
3565
|
-
await this.updateRecord(sessionId, current => ({
|
|
3626
|
+
await this.updateRecord(sessionId, (current) => ({
|
|
3566
3627
|
...current,
|
|
3567
3628
|
channelState: mergeChannelStateMutation({
|
|
3568
3629
|
current: current.channelState,
|
|
@@ -3689,7 +3750,7 @@ export class SessionEngine {
|
|
|
3689
3750
|
let matches;
|
|
3690
3751
|
if (options?.includeAll !== true) {
|
|
3691
3752
|
const owned = await this.ownedSessionIds(caller);
|
|
3692
|
-
matches = record => record.sessionId !== undefined && owned.has(record.sessionId);
|
|
3753
|
+
matches = (record) => record.sessionId !== undefined && owned.has(record.sessionId);
|
|
3693
3754
|
}
|
|
3694
3755
|
return this.artifactsStore.page({
|
|
3695
3756
|
kind: options?.filter?.kind,
|
|
@@ -3723,7 +3784,9 @@ export class SessionEngine {
|
|
|
3723
3784
|
}
|
|
3724
3785
|
async ownedSessionIds(caller) {
|
|
3725
3786
|
const sessions = await this.sessions.list();
|
|
3726
|
-
return new Set(sessions
|
|
3787
|
+
return new Set(sessions
|
|
3788
|
+
.filter((record) => samePrincipal(record.auth, caller))
|
|
3789
|
+
.map((record) => record.sessionId));
|
|
3727
3790
|
}
|
|
3728
3791
|
/**
|
|
3729
3792
|
* Same as {@link listSessions}, plus which store answered
|
|
@@ -3830,8 +3893,8 @@ export class SessionEngine {
|
|
|
3830
3893
|
}
|
|
3831
3894
|
summarizeSessionRecords(records, caller, includeAll) {
|
|
3832
3895
|
return records
|
|
3833
|
-
.filter(record => includeAll || samePrincipal(record.auth, caller))
|
|
3834
|
-
.map(record => {
|
|
3896
|
+
.filter((record) => includeAll || samePrincipal(record.auth, caller))
|
|
3897
|
+
.map((record) => {
|
|
3835
3898
|
const links = sessionExternalLinks(record);
|
|
3836
3899
|
return {
|
|
3837
3900
|
sessionId: record.sessionId,
|
|
@@ -3876,7 +3939,7 @@ export class SessionEngine {
|
|
|
3876
3939
|
if (existing === undefined) {
|
|
3877
3940
|
throw new Error(`Unknown session: ${sessionId}`);
|
|
3878
3941
|
}
|
|
3879
|
-
const record = await this.updateRecord(sessionId, current => ({
|
|
3942
|
+
const record = await this.updateRecord(sessionId, (current) => ({
|
|
3880
3943
|
...current,
|
|
3881
3944
|
turnCount: current.turnCount + 1,
|
|
3882
3945
|
}));
|
|
@@ -3928,7 +3991,7 @@ export class SessionEngine {
|
|
|
3928
3991
|
data: { ...completed.data, cost },
|
|
3929
3992
|
});
|
|
3930
3993
|
})
|
|
3931
|
-
.catch(error => {
|
|
3994
|
+
.catch((error) => {
|
|
3932
3995
|
this.logger(`[bdk] turn cost stamp failed for ${sessionId}: ${describeError(error)}`);
|
|
3933
3996
|
});
|
|
3934
3997
|
}
|
|
@@ -4022,7 +4085,7 @@ export class SessionEngine {
|
|
|
4022
4085
|
return pending;
|
|
4023
4086
|
}
|
|
4024
4087
|
const work = this.runCloudTurnCostBackfill(sessionId)
|
|
4025
|
-
.catch(error => {
|
|
4088
|
+
.catch((error) => {
|
|
4026
4089
|
this.logger(`[bdk] cloud cost backfill failed for ${sessionId}: ${describeError(error)}`);
|
|
4027
4090
|
})
|
|
4028
4091
|
.finally(() => {
|
|
@@ -4034,8 +4097,9 @@ export class SessionEngine {
|
|
|
4034
4097
|
async runCloudTurnCostBackfill(sessionId) {
|
|
4035
4098
|
const log = await this.logs.get(sessionId);
|
|
4036
4099
|
const events = await log.snapshot(0);
|
|
4037
|
-
if (!events.some(event => isUnpricedCompletedTurn(event))) {
|
|
4038
|
-
if (!this.isTurnRunning(sessionId) &&
|
|
4100
|
+
if (!events.some((event) => isUnpricedCompletedTurn(event))) {
|
|
4101
|
+
if (!this.isTurnRunning(sessionId) &&
|
|
4102
|
+
events.some((event) => event.type === "turn.completed")) {
|
|
4039
4103
|
this.cloudCostBackfillDone.add(sessionId);
|
|
4040
4104
|
}
|
|
4041
4105
|
return;
|
|
@@ -4063,13 +4127,13 @@ export class SessionEngine {
|
|
|
4063
4127
|
}
|
|
4064
4128
|
log.replace(i, next);
|
|
4065
4129
|
}
|
|
4066
|
-
if (!(await log.snapshot(0)).some(event => isUnpricedCompletedTurn(event))) {
|
|
4130
|
+
if (!(await log.snapshot(0)).some((event) => isUnpricedCompletedTurn(event))) {
|
|
4067
4131
|
this.cloudCostBackfillDone.add(sessionId);
|
|
4068
4132
|
}
|
|
4069
4133
|
}
|
|
4070
4134
|
async setContinuationToken(sessionId, token) {
|
|
4071
4135
|
const previous = await this.sessions.get(sessionId);
|
|
4072
|
-
await this.updateRecord(sessionId, current => ({
|
|
4136
|
+
await this.updateRecord(sessionId, (current) => ({
|
|
4073
4137
|
...current,
|
|
4074
4138
|
continuationKey: token,
|
|
4075
4139
|
}));
|
|
@@ -4200,7 +4264,7 @@ export class SessionEngine {
|
|
|
4200
4264
|
// the lazy continuation-lookup path.
|
|
4201
4265
|
const cutoff = Date.now() - policy.maxAgeMs;
|
|
4202
4266
|
const candidates = loaded
|
|
4203
|
-
.map(record => ({
|
|
4267
|
+
.map((record) => ({
|
|
4204
4268
|
record,
|
|
4205
4269
|
// Numeric timestamp for both the age filter and the sort; a
|
|
4206
4270
|
// non-string updatedAt (e.g. a raw DB Date from an untyped sink)
|
|
@@ -4387,6 +4451,7 @@ export class SessionEngine {
|
|
|
4387
4451
|
// After the drain, so a successor need not wait out the heartbeat TTL.
|
|
4388
4452
|
await this.turnLeases.releaseAll().catch(() => { });
|
|
4389
4453
|
await this.logs.flushAll();
|
|
4454
|
+
this.livePublisher?.close();
|
|
4390
4455
|
await this.storage?.close();
|
|
4391
4456
|
await this.mcpHost.close();
|
|
4392
4457
|
await this.runner.dispose?.();
|
|
@@ -4424,7 +4489,7 @@ function eventsNdjson(events) {
|
|
|
4424
4489
|
if (events.length === 0) {
|
|
4425
4490
|
return undefined;
|
|
4426
4491
|
}
|
|
4427
|
-
return `${events.map(event => JSON.stringify(event)).join("\n")}\n`;
|
|
4492
|
+
return `${events.map((event) => JSON.stringify(event)).join("\n")}\n`;
|
|
4428
4493
|
}
|
|
4429
4494
|
/**
|
|
4430
4495
|
* Restore-time turn-id fence: the durable record's `turnCount` may lag the
|
|
@@ -4460,7 +4525,7 @@ function subagentPrompt(subagent) {
|
|
|
4460
4525
|
* executor that turn will run on.
|
|
4461
4526
|
*/
|
|
4462
4527
|
function buildRunnerSubagents(agent) {
|
|
4463
|
-
return agent.subagents.map(subagent => ({
|
|
4528
|
+
return agent.subagents.map((subagent) => ({
|
|
4464
4529
|
name: subagent.name,
|
|
4465
4530
|
description: subagent.description ?? subagent.name,
|
|
4466
4531
|
prompt: subagentPrompt(subagent),
|
|
@@ -4480,7 +4545,7 @@ async function defaultGetCloudUsage(sdkAgentId) {
|
|
|
4480
4545
|
return {
|
|
4481
4546
|
usage: mapSdkTokenUsage(billed.usage),
|
|
4482
4547
|
cost: billed.cost,
|
|
4483
|
-
runs: billed.runs.map(run => ({
|
|
4548
|
+
runs: billed.runs.map((run) => ({
|
|
4484
4549
|
runId: run.runId,
|
|
4485
4550
|
usage: mapSdkTokenUsage(run.usage),
|
|
4486
4551
|
cost: run.cost,
|
|
@@ -4520,7 +4585,7 @@ function approvalResolverLabel(auth) {
|
|
|
4520
4585
|
}
|
|
4521
4586
|
/** Let the HTTP NDJSON writer flush before the next SDK update. */
|
|
4522
4587
|
function yieldEventLoop() {
|
|
4523
|
-
return new Promise(resolve => {
|
|
4588
|
+
return new Promise((resolve) => {
|
|
4524
4589
|
setImmediate(resolve);
|
|
4525
4590
|
});
|
|
4526
4591
|
}
|