@cursor/july 0.1.108 → 0.1.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +3 -7
- package/README.md +3 -21
- package/dist/bin/agent-serve.js +81 -66
- package/dist/channels/bitbucket/api.d.ts +41 -0
- package/dist/channels/bitbucket/api.d.ts.map +1 -1
- package/dist/channels/bitbucket/api.js +266 -6
- package/dist/channels/bitbucket/binding.d.ts +4 -0
- package/dist/channels/bitbucket/binding.d.ts.map +1 -1
- package/dist/channels/bitbucket/binding.js +20 -4
- package/dist/channels/bitbucket/bitbucket-channel.js +1 -1
- package/dist/channels/bitbucket/bitbucket-webhook.js +1 -1
- package/dist/channels/bitbucket/checks.d.ts.map +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/bitbucket/index.d.ts +1 -1
- package/dist/channels/bitbucket/index.d.ts.map +1 -1
- package/dist/channels/bitbucket/index.js +1 -1
- package/dist/channels/change-monitors/change-monitors-channel.js +1 -1
- package/dist/channels/checks.d.ts.map +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.d.ts.map +1 -1
- package/dist/channels/github/defaults.js +5 -3
- package/dist/channels/github/events.js +1 -1
- package/dist/channels/github/forward.js +8 -8
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +17 -13
- package/dist/channels/github/progress.d.ts.map +1 -1
- package/dist/channels/github/progress.js +7 -2
- package/dist/channels/github/state.d.ts +6 -0
- package/dist/channels/github/state.d.ts.map +1 -1
- package/dist/channels/github/types.d.ts +6 -0
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/gitlab/api.d.ts +27 -0
- package/dist/channels/gitlab/api.d.ts.map +1 -1
- package/dist/channels/gitlab/api.js +88 -0
- package/dist/channels/gitlab/binding.d.ts +5 -0
- package/dist/channels/gitlab/binding.d.ts.map +1 -1
- package/dist/channels/gitlab/binding.js +14 -4
- package/dist/channels/gitlab/checks.d.ts.map +1 -1
- 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/index.d.ts +1 -1
- package/dist/channels/gitlab/index.d.ts.map +1 -1
- package/dist/channels/gitlab/index.js +1 -1
- package/dist/channels/gitlab/replay.js +2 -2
- package/dist/channels/origin/binding.d.ts +2 -0
- package/dist/channels/origin/binding.d.ts.map +1 -1
- package/dist/channels/origin/binding.js +3 -3
- package/dist/channels/origin/checks.d.ts +19 -7
- package/dist/channels/origin/checks.d.ts.map +1 -1
- package/dist/channels/origin/checks.js +13 -9
- package/dist/channels/origin/cursor-account.js +1 -1
- package/dist/channels/origin/defaults.d.ts.map +1 -1
- package/dist/channels/origin/defaults.js +3 -1
- package/dist/channels/origin/events.js +1 -1
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +2 -1
- package/dist/channels/origin/origin-webhook.js +2 -2
- package/dist/channels/slack/agentic-delivery.d.ts +23 -0
- package/dist/channels/slack/agentic-delivery.d.ts.map +1 -0
- package/dist/channels/slack/agentic-delivery.js +558 -0
- package/dist/channels/slack/agentic-posted.d.ts +30 -0
- package/dist/channels/slack/agentic-posted.d.ts.map +1 -0
- package/dist/channels/slack/agentic-posted.js +102 -0
- package/dist/channels/slack/agentic-signals.d.ts +48 -0
- package/dist/channels/slack/agentic-signals.d.ts.map +1 -0
- package/dist/channels/slack/agentic-signals.js +204 -0
- package/dist/channels/slack/api.d.ts +20 -1
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +43 -11
- package/dist/channels/slack/approvals.js +1 -1
- package/dist/channels/slack/auth.d.ts.map +1 -1
- package/dist/channels/slack/auth.js +3 -1
- package/dist/channels/slack/blocks.js +3 -3
- package/dist/channels/slack/bot-mentions.d.ts.map +1 -1
- package/dist/channels/slack/bot-mentions.js +5 -5
- package/dist/channels/slack/channel-watch.js +1 -1
- package/dist/channels/slack/cli-project.js +3 -3
- package/dist/channels/slack/defaults.d.ts +3 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +90 -29
- package/dist/channels/slack/dispatch.d.ts +44 -1
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +233 -103
- package/dist/channels/slack/doctor.js +1 -1
- package/dist/channels/slack/eval-directive.js +1 -1
- package/dist/channels/slack/external-policy.d.ts +2 -1
- package/dist/channels/slack/external-policy.d.ts.map +1 -1
- package/dist/channels/slack/external-policy.js +13 -2
- package/dist/channels/slack/footer.d.ts +30 -0
- package/dist/channels/slack/footer.d.ts.map +1 -0
- package/dist/channels/slack/footer.js +88 -0
- package/dist/channels/slack/index.d.ts +2 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +2 -0
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +5 -3
- package/dist/channels/slack/live-delivery.d.ts +1 -1
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +20 -6
- 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/paint-start.d.ts +22 -0
- package/dist/channels/slack/paint-start.d.ts.map +1 -0
- package/dist/channels/slack/paint-start.js +91 -0
- package/dist/channels/slack/placeholder.d.ts +36 -0
- package/dist/channels/slack/placeholder.d.ts.map +1 -0
- package/dist/channels/slack/placeholder.js +240 -0
- package/dist/channels/slack/progress-delivery.d.ts.map +1 -1
- package/dist/channels/slack/progress-delivery.js +13 -4
- package/dist/channels/slack/reasoning-chip.d.ts +8 -0
- package/dist/channels/slack/reasoning-chip.d.ts.map +1 -0
- package/dist/channels/slack/reasoning-chip.js +30 -0
- package/dist/channels/slack/recording-sink.d.ts +29 -0
- package/dist/channels/slack/recording-sink.d.ts.map +1 -0
- package/dist/channels/slack/recording-sink.js +142 -0
- package/dist/channels/slack/reply-options.d.ts +8 -1
- package/dist/channels/slack/reply-options.d.ts.map +1 -1
- package/dist/channels/slack/reply-options.js +59 -14
- package/dist/channels/slack/setup.js +1 -1
- package/dist/channels/slack/slack-channel.d.ts +12 -5
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +110 -24
- package/dist/channels/slack/socket-mode.js +2 -2
- package/dist/channels/slack/thread-context.js +5 -5
- package/dist/channels/slack/tool-approval-events.d.ts +5 -0
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
- package/dist/channels/slack/tool-approval-events.js +50 -38
- package/dist/channels/slack/tool-cards.js +1 -1
- package/dist/channels/slack/tool-chip.d.ts +9 -0
- package/dist/channels/slack/tool-chip.d.ts.map +1 -0
- package/dist/channels/slack/tool-chip.js +25 -0
- package/dist/channels/slack/types.d.ts +49 -7
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/channels/slack/upload.d.ts +13 -0
- package/dist/channels/slack/upload.d.ts.map +1 -0
- package/dist/channels/slack/upload.js +135 -0
- package/dist/channels.d.ts +10 -14
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +9 -21
- package/dist/dashboard-session-url.d.ts +15 -0
- package/dist/dashboard-session-url.d.ts.map +1 -0
- package/dist/dashboard-session-url.js +25 -0
- package/dist/docs/404.html +3 -3
- package/dist/docs/architecture.svg +59 -0
- package/dist/docs/assets/app.Drol6mi6.js +309 -0
- package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.js → building-with-agents.md.CEGVXkmO.js} +2 -2
- package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.lean.js → building-with-agents.md.CEGVXkmO.lean.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DtXk1hy-.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BOKxlYGP.js → VPLocalSearchBox.CdqoBZJX.js} +2 -2
- package/dist/docs/assets/chunks/arc.BVX3ycTn.js +1 -0
- package/dist/docs/assets/chunks/architectureDiagram-Q4EWVU46.CcChnMxX.js +36 -0
- package/dist/docs/assets/chunks/baseUniq.xwtXO-yt.js +1 -0
- package/dist/docs/assets/chunks/blockDiagram-DXYQGD6D.CijZ_taK.js +132 -0
- package/dist/docs/assets/chunks/c4Diagram-AHTNJAMY.0FBvwBvK.js +10 -0
- package/dist/docs/assets/chunks/channel.Bkv1N-gK.js +1 -0
- package/dist/docs/assets/chunks/chunk-4BX2VUAB.CELMmMDA.js +1 -0
- package/dist/docs/assets/chunks/chunk-4TB4RGXK.C4bhFtSm.js +206 -0
- package/dist/docs/assets/chunks/chunk-55IACEB6.ZnQ9gRRQ.js +1 -0
- package/dist/docs/assets/chunks/chunk-EDXVE4YY.DPlmglG-.js +1 -0
- package/dist/docs/assets/chunks/chunk-FMBD7UC4.BrUk8pff.js +15 -0
- package/dist/docs/assets/chunks/chunk-OYMX7WX6.CcmWIncu.js +231 -0
- package/dist/docs/assets/chunks/chunk-QZHKN3VN.D65-cs8I.js +1 -0
- package/dist/docs/assets/chunks/chunk-YZCP3GAM.qoXZpG9F.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CZDco1o8.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CZDco1o8.js +1 -0
- package/dist/docs/assets/chunks/clone.YSt_40_s.js +1 -0
- package/dist/docs/assets/chunks/cose-bilkent-S5V4N54A.8rYtqudO.js +1 -0
- package/dist/docs/assets/chunks/cytoscape.esm.BQk4lpUV.js +331 -0
- package/dist/docs/assets/chunks/dagre-KV5264BT.DrRP1fOh.js +4 -0
- package/dist/docs/assets/chunks/defaultLocale.C4B-KCzX.js +1 -0
- package/dist/docs/assets/chunks/diagram-5BDNPKRD.DHj_xA2_.js +10 -0
- package/dist/docs/assets/chunks/diagram-G4DWMVQ6.Bz_6nAKj.js +24 -0
- package/dist/docs/assets/chunks/diagram-MMDJMWI5.BWA0xSW9.js +43 -0
- package/dist/docs/assets/chunks/diagram-TYMM5635.CpTJLNJI.js +24 -0
- package/dist/docs/assets/chunks/erDiagram-SMLLAGMA.-7AWWSrP.js +85 -0
- package/dist/docs/assets/chunks/flowDiagram-DWJPFMVM.BTnQ742_.js +162 -0
- package/dist/docs/assets/chunks/framework.dypDpWZ3.js +19 -0
- package/dist/docs/assets/chunks/ganttDiagram-T4ZO3ILL.B5_HiiQ5.js +292 -0
- package/dist/docs/assets/chunks/gitGraphDiagram-UUTBAWPF.CZcNTFZd.js +106 -0
- package/dist/docs/assets/chunks/graph.V2GLaab4.js +1 -0
- package/dist/docs/assets/chunks/infoDiagram-42DDH7IO.7pZOkCCU.js +2 -0
- package/dist/docs/assets/chunks/init.Gi6I4Gst.js +1 -0
- package/dist/docs/assets/chunks/ishikawaDiagram-UXIWVN3A.DSMo3Qa3.js +70 -0
- package/dist/docs/assets/chunks/journeyDiagram-VCZTEJTY.BNEgWN1S.js +139 -0
- package/dist/docs/assets/chunks/kanban-definition-6JOO6SKY.B-4d4tC7.js +89 -0
- package/dist/docs/assets/chunks/katex.DkKDou_j.js +257 -0
- package/dist/docs/assets/chunks/layout.Dvbn9nSb.js +1 -0
- package/dist/docs/assets/chunks/linear.D2GM4p4b.js +1 -0
- package/dist/docs/assets/chunks/min.DVBtLK-B.js +1 -0
- package/dist/docs/assets/chunks/mindmap-definition-QFDTVHPH.CnJRI55x.js +96 -0
- package/dist/docs/assets/chunks/ordinal.DBvzRdQf.js +1 -0
- package/dist/docs/assets/chunks/pieDiagram-DEJITSTG.CtoaTFlA.js +30 -0
- package/dist/docs/assets/chunks/quadrantDiagram-34T5L4WZ.DtT24_vN.js +7 -0
- package/dist/docs/assets/chunks/requirementDiagram-MS252O5E.CjSO4o8f.js +84 -0
- package/dist/docs/assets/chunks/sankeyDiagram-XADWPNL6.-wWiIVWa.js +10 -0
- package/dist/docs/assets/chunks/sequenceDiagram-FGHM5R23.DSk8s4gX.js +157 -0
- package/dist/docs/assets/chunks/stateDiagram-FHFEXIEX.BFKAsdkN.js +1 -0
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.C4CLm481.js +1 -0
- package/dist/docs/assets/chunks/{theme.DbDZW-zb.js → theme.C0MctGaz.js} +2 -2
- package/dist/docs/assets/chunks/timeline-definition-GMOUNBTQ.TUNJbAFe.js +120 -0
- package/dist/docs/assets/chunks/vennDiagram-DHZGUBPP.C-RGNnk4.js +34 -0
- package/dist/docs/assets/chunks/virtual_mermaid-config.DDnGl6nM.js +1 -0
- package/dist/docs/assets/chunks/wardley-RL74JXVD.g5efOWmT.js +162 -0
- package/dist/docs/assets/chunks/wardleyDiagram-NUSXRM2D.DH4zt73Y.js +20 -0
- package/dist/docs/assets/chunks/xychartDiagram-5P7HB3ND.B-3k6bF6.js +7 -0
- package/dist/docs/assets/{deployment.md.JenwuCCB.js → deployment.md.Dm4Qo3hp.js} +5 -5
- package/dist/docs/assets/{deployment.md.JenwuCCB.lean.js → deployment.md.Dm4Qo3hp.lean.js} +1 -1
- package/dist/docs/assets/evals.md.BLDRt5LH.js +211 -0
- package/dist/docs/assets/evals.md.BLDRt5LH.lean.js +1 -0
- package/dist/docs/assets/guides_agent-to-agent.md.BI0xclmy.js +14 -0
- package/dist/docs/assets/guides_agent-to-agent.md.BI0xclmy.lean.js +1 -0
- package/dist/docs/assets/guides_bitbucket.md.CTpCl__f.js +10 -0
- package/dist/docs/assets/guides_bitbucket.md.CTpCl__f.lean.js +1 -0
- package/dist/docs/assets/{guides_cloud-agents.md.BsloyHdY.js → guides_cloud-agents.md.lSE_l7lH.js} +2 -2
- package/dist/docs/assets/{guides_cloud-agents.md.BsloyHdY.lean.js → guides_cloud-agents.md.lSE_l7lH.lean.js} +1 -1
- package/dist/docs/assets/{guides_convert-automation.md.B4sjlodG.js → guides_convert-automation.md.Ck6Cr68A.js} +1 -1
- package/dist/docs/assets/{guides_convert-automation.md.B4sjlodG.lean.js → guides_convert-automation.md.Ck6Cr68A.lean.js} +1 -1
- package/dist/docs/assets/{guides_github.md.BH33UEBJ.js → guides_github.md.D6ER29dG.js} +13 -3
- package/dist/docs/assets/{guides_github.md.BH33UEBJ.lean.js → guides_github.md.D6ER29dG.lean.js} +1 -1
- package/dist/docs/assets/guides_gitlab.md.P-TjBnS5.js +14 -0
- package/dist/docs/assets/guides_gitlab.md.P-TjBnS5.lean.js +1 -0
- package/dist/docs/assets/guides_grokbot-agents.md.WBZIOvkz.js +9 -0
- package/dist/docs/assets/{guides_grokbot-agents.md.DyV-WArv.lean.js → guides_grokbot-agents.md.WBZIOvkz.lean.js} +1 -1
- package/dist/docs/assets/{guides_improve.md.BGVk32bK.js → guides_improve.md.BKaDuKKK.js} +1 -1
- package/dist/docs/assets/{guides_improve.md.BGVk32bK.lean.js → guides_improve.md.BKaDuKKK.lean.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.Dp6cDP7f.js → guides_mcp-oauth.md.DMNMpXtO.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.Dp6cDP7f.lean.js → guides_mcp-oauth.md.DMNMpXtO.lean.js} +1 -1
- package/dist/docs/assets/{guides_opentelemetry.md.SCRMskno.js → guides_opentelemetry.md._CRfDyzH.js} +14 -14
- package/dist/docs/assets/{guides_opentelemetry.md.SCRMskno.lean.js → guides_opentelemetry.md._CRfDyzH.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.D4RVMM4G.js → guides_slack.md.DdT8rmsj.js} +12 -4
- package/dist/docs/assets/{guides_slack.md.D4RVMM4G.lean.js → guides_slack.md.DdT8rmsj.lean.js} +1 -1
- package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.js → guides_webhooks.md.aQW10HRe.js} +3 -3
- package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.lean.js → guides_webhooks.md.aQW10HRe.lean.js} +1 -1
- package/dist/docs/assets/hillclimbing.md.Dq4kkVIL.js +1 -0
- package/dist/docs/assets/hillclimbing.md.Dq4kkVIL.lean.js +1 -0
- package/dist/docs/assets/index.md.BFVyY2KT.js +17 -0
- package/dist/docs/assets/index.md.BFVyY2KT.lean.js +1 -0
- package/dist/docs/assets/{quickstart.md.DdQOF7Y8.js → quickstart.md.D3MjSZN-.js} +30 -38
- package/dist/docs/assets/quickstart.md.D3MjSZN-.lean.js +1 -0
- package/dist/docs/assets/{reference_agent-config.md.CvoL6pof.js → reference_agent-config.md.CfVA-LZJ.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.CvoL6pof.lean.js → reference_agent-config.md.CfVA-LZJ.lean.js} +1 -1
- package/dist/docs/assets/{reference_artifacts.md.Dior32Qw.js → reference_artifacts.md.Vf7qyIZ-.js} +1 -1
- package/dist/docs/assets/{reference_artifacts.md.Dior32Qw.lean.js → reference_artifacts.md.Vf7qyIZ-.lean.js} +1 -1
- package/dist/docs/assets/{reference_channels.md.D-qTqwcq.js → reference_channels.md.icqLKcTc.js} +2 -12
- package/dist/docs/assets/{reference_channels.md.D-qTqwcq.lean.js → reference_channels.md.icqLKcTc.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.Ca26u0Es.js → reference_cli.md.B2dBL6L8.js} +4 -4
- package/dist/docs/assets/{reference_cli.md.Ca26u0Es.lean.js → reference_cli.md.B2dBL6L8.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.BojkC6c5.js → reference_connections.md.Cb3U_c8n.js} +4 -4
- package/dist/docs/assets/{reference_connections.md.BojkC6c5.lean.js → reference_connections.md.Cb3U_c8n.lean.js} +1 -1
- package/dist/docs/assets/{reference_extensions.md.CPWt00ds.js → reference_extensions.md.wlFD3cUR.js} +3 -3
- package/dist/docs/assets/{reference_extensions.md.CPWt00ds.lean.js → reference_extensions.md.wlFD3cUR.lean.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.js → reference_hooks.md.CZuynAxj.js} +3 -3
- package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.lean.js → reference_hooks.md.CZuynAxj.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.oySXBO8o.js → reference_http-api.md.DTKcYE6L.js} +3 -3
- package/dist/docs/assets/{reference_http-api.md.oySXBO8o.lean.js → reference_http-api.md.DTKcYE6L.lean.js} +1 -1
- package/dist/docs/assets/{reference_instructions.md.CR7XSsGk.js → reference_instructions.md.D7gkckK-.js} +1 -1
- package/dist/docs/assets/{reference_instructions.md.CR7XSsGk.lean.js → reference_instructions.md.D7gkckK-.lean.js} +1 -1
- package/dist/docs/assets/{reference_playground.md.4myJPxrf.js → reference_playground.md.D2YExv5K.js} +1 -1
- package/dist/docs/assets/{reference_playground.md.4myJPxrf.lean.js → reference_playground.md.D2YExv5K.lean.js} +1 -1
- package/dist/docs/assets/reference_project-layout.md.DPxbUJyt.js +19 -0
- package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.lean.js → reference_project-layout.md.DPxbUJyt.lean.js} +1 -1
- package/dist/docs/assets/{reference_prompt.md.DnaD5dNK.js → reference_prompt.md.BQ5uAv1F.js} +1 -1
- package/dist/docs/assets/{reference_prompt.md.DnaD5dNK.lean.js → reference_prompt.md.BQ5uAv1F.lean.js} +1 -1
- package/dist/docs/assets/{reference_schedules.md.DI_JrHgq.js → reference_schedules.md.BasfZWO-.js} +1 -1
- package/dist/docs/assets/{reference_schedules.md.DI_JrHgq.lean.js → reference_schedules.md.BasfZWO-.lean.js} +1 -1
- package/dist/docs/assets/reference_sessions.md.YKvIsWAx.js +1 -0
- package/dist/docs/assets/{reference_sessions.md.CueyOHSL.lean.js → reference_sessions.md.YKvIsWAx.lean.js} +1 -1
- package/dist/docs/assets/{reference_skills.md.l2ezAcaN.js → reference_skills.md.rNgpsGd0.js} +1 -1
- package/dist/docs/assets/{reference_skills.md.l2ezAcaN.lean.js → reference_skills.md.rNgpsGd0.lean.js} +1 -1
- package/dist/docs/assets/{reference_subagents.md.CfsIloPm.js → reference_subagents.md.e5qitjJt.js} +2 -2
- package/dist/docs/assets/{reference_subagents.md.CfsIloPm.lean.js → reference_subagents.md.e5qitjJt.lean.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.aGrn99hP.js → reference_tools.md.BdCO2aHZ.js} +4 -4
- package/dist/docs/assets/{reference_tools.md.aGrn99hP.lean.js → reference_tools.md.BdCO2aHZ.lean.js} +1 -1
- package/dist/docs/assets/{style.DCD_zyg3.css → style.Cfo2vbik.css} +1 -1
- package/dist/docs/assets/{templates_agentic-owners.md.BZSH4N9z.js → templates_agentic-owners.md.Da_AGDlH.js} +1 -1
- package/dist/docs/assets/{templates_agentic-owners.md.BZSH4N9z.lean.js → templates_agentic-owners.md.Da_AGDlH.lean.js} +1 -1
- package/dist/docs/assets/{templates_pr-autofixer.md.Bds_XWcV.js → templates_pr-autofixer.md.DqxocIGh.js} +1 -1
- package/dist/docs/assets/{templates_pr-autofixer.md.Bds_XWcV.lean.js → templates_pr-autofixer.md.DqxocIGh.lean.js} +1 -1
- package/dist/docs/assets/{templates_security-reviewer.md.lshxbCLK.js → templates_security-reviewer.md.Bhnvd8VE.js} +1 -1
- package/dist/docs/assets/{templates_security-reviewer.md.lshxbCLK.lean.js → templates_security-reviewer.md.Bhnvd8VE.lean.js} +1 -1
- package/dist/docs/assets/{templates_triage.md.Co4UNzkZ.js → templates_triage.md.BdBWO9Ic.js} +1 -1
- package/dist/docs/assets/{templates_triage.md.Co4UNzkZ.lean.js → templates_triage.md.BdBWO9Ic.lean.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.CYEAO9bM.js → troubleshooting.md.BcgNoYtJ.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.CYEAO9bM.lean.js → troubleshooting.md.BcgNoYtJ.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +41 -8
- package/dist/docs/building-with-agents.md +15 -16
- package/dist/docs/deployment.html +44 -11
- package/dist/docs/deployment.md +6 -7
- package/dist/docs/evals.html +196 -37
- package/dist/docs/evals.md +612 -297
- package/dist/docs/guides/agent-to-agent.html +48 -11
- package/dist/docs/guides/agent-to-agent.md +40 -83
- package/dist/docs/guides/bitbucket.html +69 -0
- package/dist/docs/guides/bitbucket.md +84 -0
- package/dist/docs/guides/cloud-agents.html +41 -8
- package/dist/docs/guides/cloud-agents.md +24 -20
- package/dist/docs/guides/convert-automation.html +41 -8
- package/dist/docs/guides/github.html +52 -9
- package/dist/docs/guides/github.md +32 -1
- package/dist/docs/guides/gitlab.html +73 -0
- package/dist/docs/guides/gitlab.md +92 -0
- package/dist/docs/guides/grokbot-agents.html +41 -8
- package/dist/docs/guides/grokbot-agents.md +26 -19
- package/dist/docs/guides/improve.html +41 -8
- package/dist/docs/guides/mcp-oauth.html +41 -8
- package/dist/docs/guides/mcp-oauth.md +1 -1
- package/dist/docs/guides/opentelemetry.html +53 -20
- package/dist/docs/guides/opentelemetry.md +28 -41
- package/dist/docs/guides/slack.html +51 -10
- package/dist/docs/guides/slack.md +53 -4
- package/dist/docs/guides/webhooks.html +42 -9
- package/dist/docs/guides/webhooks.md +7 -6
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +40 -10
- package/dist/docs/hillclimbing.md +7 -7
- package/dist/docs/index.html +57 -12
- package/dist/docs/index.md +81 -146
- package/dist/docs/llms-full.txt +1368 -5551
- package/dist/docs/llms.txt +6 -31
- package/dist/docs/quickstart.html +70 -45
- package/dist/docs/quickstart.md +44 -105
- package/dist/docs/reference/agent-config.html +41 -8
- package/dist/docs/reference/artifacts.html +41 -8
- package/dist/docs/reference/channels.html +41 -18
- package/dist/docs/reference/channels.md +16 -19
- package/dist/docs/reference/cli.html +43 -10
- package/dist/docs/reference/cli.md +6 -20
- package/dist/docs/reference/connections.html +43 -10
- package/dist/docs/reference/connections.md +3 -5
- package/dist/docs/reference/extensions.html +43 -10
- package/dist/docs/reference/extensions.md +2 -5
- package/dist/docs/reference/hooks.html +42 -9
- package/dist/docs/reference/hooks.md +11 -16
- package/dist/docs/reference/http-api.html +42 -9
- package/dist/docs/reference/http-api.md +6 -7
- package/dist/docs/reference/instructions.html +41 -8
- package/dist/docs/reference/playground.html +40 -7
- package/dist/docs/reference/playground.md +2 -6
- package/dist/docs/reference/project-layout.html +42 -9
- package/dist/docs/reference/project-layout.md +4 -12
- package/dist/docs/reference/prompt.html +41 -8
- package/dist/docs/reference/schedules.html +41 -8
- package/dist/docs/reference/sessions.html +40 -7
- package/dist/docs/reference/sessions.md +6 -6
- package/dist/docs/reference/skills.html +41 -8
- package/dist/docs/reference/subagents.html +41 -8
- package/dist/docs/reference/subagents.md +2 -4
- package/dist/docs/reference/tools.html +43 -10
- package/dist/docs/reference/tools.md +2 -5
- package/dist/docs/templates/agentic-owners.html +41 -8
- package/dist/docs/templates/pr-autofixer.html +41 -8
- package/dist/docs/templates/security-reviewer.html +41 -8
- package/dist/docs/templates/triage.html +41 -8
- package/dist/docs/troubleshooting.html +40 -7
- package/dist/docs/troubleshooting.md +1 -2
- package/dist/evals/assertions.js +19 -19
- package/dist/evals/expect.js +1 -1
- package/dist/evals/judge.js +1 -1
- package/dist/evals/reporters.d.ts.map +1 -1
- package/dist/evals/reporters.js +8 -8
- package/dist/evals/run-facts.js +2 -2
- package/dist/evals.d.ts +1 -1
- package/dist/evals.d.ts.map +1 -1
- package/dist/evals.js +7 -7
- package/dist/extensions/cursor-cloud-agents/extension.js +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +3 -3
- package/dist/extensions/cursor-cloud-agents/lib/fleet.js +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/repos.js +6 -6
- package/dist/extensions/cursor-cloud-agents/lib/transcript.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/transcript.js +2 -2
- package/dist/extensions/cursor-cloud-agents/tools/list.js +1 -1
- package/dist/extensions/improve/skills/yourself.js +1 -1
- package/dist/extensions/slack-communication/extension.d.ts +28 -0
- package/dist/extensions/slack-communication/extension.d.ts.map +1 -0
- package/dist/extensions/slack-communication/extension.js +32 -0
- package/dist/extensions/slack-communication/skills/slack-voice.d.ts +5 -0
- package/dist/extensions/slack-communication/skills/slack-voice.d.ts.map +1 -0
- package/dist/extensions/slack-communication/skills/slack-voice.js +54 -0
- package/dist/extensions/slack-communication/tools/delete-message.d.ts +4 -0
- package/dist/extensions/slack-communication/tools/delete-message.d.ts.map +1 -0
- package/dist/extensions/slack-communication/tools/delete-message.js +29 -0
- package/dist/extensions/slack-communication/tools/edit-message.d.ts +4 -0
- package/dist/extensions/slack-communication/tools/edit-message.d.ts.map +1 -0
- package/dist/extensions/slack-communication/tools/edit-message.js +37 -0
- package/dist/extensions/slack-communication/tools/post-card.d.ts +4 -0
- package/dist/extensions/slack-communication/tools/post-card.d.ts.map +1 -0
- package/dist/extensions/slack-communication/tools/post-card.js +25 -0
- package/dist/extensions/slack-communication/tools/post-file.d.ts +4 -0
- package/dist/extensions/slack-communication/tools/post-file.d.ts.map +1 -0
- package/dist/extensions/slack-communication/tools/post-file.js +76 -0
- package/dist/extensions/slack-communication/tools/post-update.d.ts +4 -0
- package/dist/extensions/slack-communication/tools/post-update.d.ts.map +1 -0
- package/dist/extensions/slack-communication/tools/post-update.js +36 -0
- package/dist/extensions/slack-communication/tools/react.d.ts +4 -0
- package/dist/extensions/slack-communication/tools/react.d.ts.map +1 -0
- package/dist/extensions/slack-communication/tools/react.js +27 -0
- package/dist/extensions/slack-communication/tools/set-status.d.ts +4 -0
- package/dist/extensions/slack-communication/tools/set-status.d.ts.map +1 -0
- package/dist/extensions/slack-communication/tools/set-status.js +18 -0
- package/dist/extensions.d.ts +2 -3
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +2 -5
- package/dist/files-backends/cursor-hosted.d.ts +18 -6
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +357 -74
- package/dist/files-backends/local-fs.js +1 -1
- package/dist/files.d.ts +15 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/filesystem.d.ts.map +1 -1
- package/dist/filesystem.js +15 -15
- package/dist/index.d.ts +6 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -8
- package/dist/internal/advertise-tools.js +6 -6
- package/dist/internal/approval-gate.js +1 -1
- package/dist/internal/artifacts-store.js +3 -3
- package/dist/internal/as-of.js +2 -2
- package/dist/internal/authored-alias-hooks.d.ts +5 -0
- package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
- package/dist/internal/authored-alias-hooks.js +17 -0
- package/dist/internal/authored-loaders.d.ts +4 -0
- package/dist/internal/authored-loaders.d.ts.map +1 -1
- package/dist/internal/authored-loaders.js +21 -2
- package/dist/internal/builtin-tools/reminders.js +2 -2
- package/dist/internal/chat-client.js +5 -5
- package/dist/internal/cli-ax.d.ts +2 -2
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +69 -15
- package/dist/internal/cli-bitbucket.js +10 -10
- package/dist/internal/cli-convert-automation.js +2 -2
- package/dist/internal/cli-cursor.d.ts +3 -11
- package/dist/internal/cli-cursor.d.ts.map +1 -1
- package/dist/internal/cli-cursor.js +5 -10
- package/dist/internal/cli-deploy.d.ts +12 -2
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +328 -96
- package/dist/internal/cli-docs.js +5 -5
- package/dist/internal/cli-github.js +15 -16
- package/dist/internal/cli-gitlab.js +10 -10
- package/dist/internal/cli-manifest.js +1 -1
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
- package/dist/internal/cli-mcp-oauth.js +5 -5
- package/dist/internal/cli-mcp.js +3 -3
- 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-channel.d.ts.map +1 -1
- package/dist/internal/continuation-channel.js +2 -2
- package/dist/internal/continuation-identity.d.ts.map +1 -1
- package/dist/internal/continuation-identity.js +22 -12
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +33 -2
- package/dist/internal/convert-automation/convert-workflow.js +25 -24
- package/dist/internal/convert-automation/types.d.ts +8 -0
- package/dist/internal/convert-automation/types.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.d.ts +2 -2
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +32 -27
- package/dist/internal/cursor/backend-client.d.ts +15 -10
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +17 -11
- package/dist/internal/cursor/credentials.js +1 -1
- package/dist/internal/cursor/hosted-store-secrets.d.ts +16 -0
- package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -1
- package/dist/internal/cursor/hosted-store-secrets.js +25 -0
- package/dist/internal/cursor-account-mcp-auth.js +9 -9
- 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 +106 -9
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +171 -23
- package/dist/internal/deploy-manifest.d.ts +13 -0
- package/dist/internal/deploy-manifest.d.ts.map +1 -1
- package/dist/internal/deploy-manifest.js +32 -16
- package/dist/internal/discovery/agent-config.d.ts +5 -0
- package/dist/internal/discovery/agent-config.d.ts.map +1 -1
- package/dist/internal/discovery/agent-config.js +27 -0
- package/dist/internal/discovery/agent.d.ts +1 -1
- package/dist/internal/discovery/agent.d.ts.map +1 -1
- package/dist/internal/discovery/agent.js +10 -13
- package/dist/internal/discovery/channels.js +4 -4
- package/dist/internal/discovery/connections.js +4 -4
- package/dist/internal/discovery/cursor-plugin.js +12 -12
- package/dist/internal/discovery/extension-overlay.d.ts +1 -2
- package/dist/internal/discovery/extension-overlay.d.ts.map +1 -1
- package/dist/internal/discovery/extension-overlay.js +3 -17
- package/dist/internal/discovery/extensions.d.ts +1 -2
- package/dist/internal/discovery/extensions.d.ts.map +1 -1
- package/dist/internal/discovery/extensions.js +10 -28
- package/dist/internal/discovery/info.d.ts.map +1 -1
- package/dist/internal/discovery/info.js +44 -26
- package/dist/internal/discovery/instructions.js +1 -1
- package/dist/internal/discovery/modules.js +0 -1
- package/dist/internal/discovery/project.d.ts.map +1 -1
- package/dist/internal/discovery/project.js +4 -20
- 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.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +7 -7
- package/dist/internal/eval-runner.js +14 -15
- package/dist/internal/evals-client.js +4 -4
- package/dist/internal/event-log.js +8 -8
- package/dist/internal/event-mapper.d.ts +18 -0
- package/dist/internal/event-mapper.d.ts.map +1 -1
- package/dist/internal/event-mapper.js +34 -2
- package/dist/internal/filesystem/format.d.ts.map +1 -1
- package/dist/internal/filesystem/format.js +6 -3
- package/dist/internal/filesystem/scratch.js +3 -3
- package/dist/internal/filesystem/tools.d.ts.map +1 -1
- package/dist/internal/filesystem/tools.js +6 -6
- package/dist/internal/filesystem/walk.js +1 -1
- package/dist/internal/framework-file-storage.d.ts +10 -7
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +95 -7
- package/dist/internal/framework-storage-selection.d.ts +2 -8
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +4 -13
- 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-admission-adapter.d.ts +2 -0
- package/dist/internal/hosted-admission-adapter.d.ts.map +1 -1
- package/dist/internal/hosted-catch-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-catch-protocol.js +2 -4
- package/dist/internal/hosted-catch.js +1 -1
- package/dist/internal/hosted-delivery-protocol.d.ts +29 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +76 -8
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +201 -64
- package/dist/internal/hosted-execution-diag.js +3 -3
- package/dist/internal/hosted-execution-latency.d.ts +80 -0
- package/dist/internal/hosted-execution-latency.d.ts.map +1 -0
- package/dist/internal/hosted-execution-latency.js +220 -0
- package/dist/internal/hosting.d.ts +5 -5
- package/dist/internal/hosting.d.ts.map +1 -1
- package/dist/internal/hosting.js +5 -6
- package/dist/internal/http-channel-define.d.ts +11 -0
- package/dist/internal/http-channel-define.d.ts.map +1 -0
- package/dist/internal/http-channel-define.js +18 -0
- package/dist/internal/http-channel.d.ts +2 -3
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +3 -4
- package/dist/internal/http-control-plane-session.d.ts +7 -3
- package/dist/internal/http-control-plane-session.d.ts.map +1 -1
- package/dist/internal/http-control-plane-session.js +22 -10
- package/dist/internal/incoming-headers-to-fetch.d.ts +10 -0
- package/dist/internal/incoming-headers-to-fetch.d.ts.map +1 -0
- package/dist/internal/incoming-headers-to-fetch.js +41 -0
- package/dist/internal/init-interview.js +7 -7
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +14 -14
- package/dist/internal/init-scaffold.d.ts.map +1 -1
- package/dist/internal/init-scaffold.js +2 -3
- package/dist/internal/inline-stdio-mcp.js +2 -2
- package/dist/internal/install-cursor-skills.d.ts +5 -2
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +35 -15
- package/dist/internal/json-schema.js +1 -1
- package/dist/internal/local-control-plane.d.ts.map +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.js +4 -4
- 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/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.map +1 -1
- package/dist/internal/reminder-runner.js +7 -7
- package/dist/internal/reminder-store.js +1 -1
- package/dist/internal/request-error-status.d.ts.map +1 -1
- package/dist/internal/request-error-status.js +9 -0
- package/dist/internal/resolved-connections.js +8 -8
- package/dist/internal/result-output.d.ts +14 -2
- package/dist/internal/result-output.d.ts.map +1 -1
- package/dist/internal/result-output.js +45 -2
- package/dist/internal/router.js +4 -4
- package/dist/internal/run-client.d.ts +1 -1
- package/dist/internal/run-client.js +2 -2
- package/dist/internal/schedule-runner.js +6 -6
- package/dist/internal/scm/pr-url.d.ts +3 -1
- package/dist/internal/scm/pr-url.d.ts.map +1 -1
- package/dist/internal/scm/pr-url.js +10 -2
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +15 -16
- package/dist/internal/serve-restart.js +1 -1
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +81 -101
- package/dist/internal/session-cost.js +3 -3
- package/dist/internal/session-engine.d.ts +39 -35
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +394 -343
- package/dist/internal/session-run-log.d.ts.map +1 -1
- package/dist/internal/session-run-log.js +4 -4
- package/dist/internal/session-store.d.ts +47 -3
- package/dist/internal/session-store.d.ts.map +1 -1
- package/dist/internal/session-store.js +198 -33
- package/dist/internal/sessions-client.js +3 -3
- package/dist/internal/slack-thread-key.d.ts +7 -0
- package/dist/internal/slack-thread-key.d.ts.map +1 -0
- package/dist/internal/slack-thread-key.js +10 -0
- package/dist/internal/sleep.js +1 -1
- package/dist/internal/storage-coordinator.d.ts +22 -19
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +114 -73
- package/dist/internal/storage-roles.d.ts +4 -9
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/storage-roles.js +2 -2
- package/dist/internal/storage.d.ts +2 -0
- package/dist/internal/storage.d.ts.map +1 -0
- package/dist/internal/storage.js +1 -0
- package/dist/internal/store-mirror.js +4 -4
- package/dist/internal/terminal-style.js +2 -2
- 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.js +2 -2
- package/dist/internal/v2-hosting.d.ts +9 -0
- package/dist/internal/v2-hosting.d.ts.map +1 -1
- package/dist/internal/v2-hosting.js +10 -0
- package/dist/internal/workspace.d.ts +13 -10
- package/dist/internal/workspace.d.ts.map +1 -1
- package/dist/internal/workspace.js +17 -16
- package/dist/kv/memory-kv.d.ts +6 -4
- package/dist/kv/memory-kv.d.ts.map +1 -1
- package/dist/kv/memory-kv.js +9 -7
- package/dist/kv.d.ts +4 -7
- package/dist/kv.d.ts.map +1 -1
- package/dist/kv.js +4 -7
- package/dist/otel-public.d.ts +7 -0
- package/dist/otel-public.d.ts.map +1 -0
- package/dist/otel-public.js +5 -0
- package/dist/otel.d.ts +7 -2
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +7 -2
- package/dist/playground/assets/index-BLlKgZtI.css +1 -0
- package/dist/playground/assets/index-CDS5p9sR.js +67 -0
- package/dist/playground/index.html +2 -2
- package/dist/prompt.js +1 -1
- package/dist/result.d.ts +10 -4
- package/dist/result.d.ts.map +1 -1
- package/dist/result.js +9 -3
- package/dist/storage-backends/cursor-hosted-v2.d.ts +4 -5
- package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted-v2.js +6 -7
- package/dist/storage-backends/cursor-hosted.d.ts +6 -19
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +6 -50
- package/dist/storage-backends/file-kv.d.ts +9 -12
- package/dist/storage-backends/file-kv.d.ts.map +1 -1
- package/dist/storage-backends/file-kv.js +18 -54
- package/dist/storage-protocol.d.ts +3 -11
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +3 -11
- package/dist/storage.d.ts +28 -38
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +15 -50
- package/dist/types.d.ts +87 -68
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +12 -4
- package/docs/README.md +83 -148
- package/docs/building-with-agents.md +15 -16
- package/docs/deployment.md +6 -7
- package/docs/evals.md +613 -298
- package/docs/guides/agent-to-agent.md +41 -84
- package/docs/guides/bitbucket.md +89 -0
- package/docs/guides/cloud-agents.md +25 -20
- package/docs/guides/github.md +32 -1
- package/docs/guides/gitlab.md +97 -0
- package/docs/guides/grokbot-agents.md +27 -19
- package/docs/guides/mcp-oauth.md +1 -1
- package/docs/guides/opentelemetry.md +28 -41
- package/docs/guides/slack.md +53 -4
- package/docs/guides/webhooks.md +7 -6
- package/docs/hillclimbing.md +7 -7
- package/docs/quickstart.md +45 -106
- package/docs/reference/channels.md +16 -19
- package/docs/reference/cli.md +6 -20
- package/docs/reference/connections.md +3 -5
- package/docs/reference/extensions.md +2 -5
- package/docs/reference/hooks.md +11 -16
- package/docs/reference/http-api.md +6 -7
- package/docs/reference/playground.md +2 -6
- package/docs/reference/project-layout.md +4 -12
- package/docs/reference/sessions.md +6 -6
- package/docs/reference/subagents.md +2 -4
- package/docs/reference/tools.md +2 -5
- package/docs/troubleshooting.md +1 -2
- package/package.json +55 -43
- package/skills/deploy/SKILL.md +169 -0
- package/skills/evals/SKILL.md +45 -8
- package/skills/framework-map/SKILL.md +3 -4
- package/skills/otel/SKILL.md +8 -18
- package/src/bin/agent-serve.ts +93 -72
- package/src/channels/bitbucket/api.ts +347 -6
- package/src/channels/bitbucket/binding.ts +29 -4
- package/src/channels/bitbucket/bitbucket-channel.ts +1 -1
- package/src/channels/bitbucket/bitbucket-webhook.ts +1 -1
- package/src/channels/bitbucket/checks.ts +3 -4
- package/src/channels/bitbucket/cursor-account.ts +1 -1
- package/src/channels/bitbucket/events.ts +1 -1
- package/src/channels/bitbucket/index.ts +2 -0
- package/src/channels/change-monitors/change-monitors-channel.ts +2 -2
- package/src/channels/checks.ts +5 -4
- package/src/channels/deployments/deployments-channel.ts +1 -1
- package/src/channels/github/api.ts +1 -1
- package/src/channels/github/checks.ts +1 -1
- package/src/channels/github/cursor-account.ts +3 -3
- package/src/channels/github/defaults.ts +8 -4
- package/src/channels/github/events.ts +1 -1
- package/src/channels/github/forward.ts +8 -8
- package/src/channels/github/github-channel.ts +19 -2
- package/src/channels/github/progress.ts +7 -2
- package/src/channels/github/state.ts +6 -0
- package/src/channels/github/types.ts +6 -0
- package/src/channels/gitlab/api.ts +123 -0
- package/src/channels/gitlab/binding.ts +16 -4
- package/src/channels/gitlab/checks.ts +3 -4
- package/src/channels/gitlab/cursor-account.ts +1 -1
- package/src/channels/gitlab/events.ts +1 -1
- package/src/channels/gitlab/gitlab-channel.ts +1 -1
- package/src/channels/gitlab/gitlab-webhook.ts +1 -1
- package/src/channels/gitlab/index.ts +1 -0
- package/src/channels/gitlab/replay.ts +2 -2
- package/src/channels/origin/binding.ts +6 -3
- package/src/channels/origin/checks.ts +27 -17
- package/src/channels/origin/cursor-account.ts +1 -1
- package/src/channels/origin/defaults.ts +5 -1
- package/src/channels/origin/events.ts +1 -1
- package/src/channels/origin/origin-channel.ts +2 -1
- package/src/channels/origin/origin-webhook.ts +2 -2
- package/src/channels/slack/agentic-delivery.ts +659 -0
- package/src/channels/slack/agentic-posted.ts +148 -0
- package/src/channels/slack/agentic-signals.ts +248 -0
- package/src/channels/slack/api.ts +51 -11
- package/src/channels/slack/approvals.ts +1 -1
- package/src/channels/slack/attachments.ts +1 -1
- package/src/channels/slack/auth.ts +3 -1
- package/src/channels/slack/blocks.ts +3 -3
- package/src/channels/slack/bot-mentions.ts +5 -7
- package/src/channels/slack/channel-watch.ts +1 -1
- package/src/channels/slack/cli-project.ts +3 -3
- package/src/channels/slack/defaults.ts +109 -37
- package/src/channels/slack/dispatch.ts +323 -164
- package/src/channels/slack/doctor.ts +1 -1
- package/src/channels/slack/eval-directive.ts +1 -1
- package/src/channels/slack/external-policy.ts +15 -2
- package/src/channels/slack/footer.ts +108 -0
- package/src/channels/slack/index.ts +2 -0
- package/src/channels/slack/interactive.ts +4 -2
- package/src/channels/slack/live-delivery.ts +23 -7
- package/src/channels/slack/log.ts +1 -1
- package/src/channels/slack/manifest.ts +1 -1
- package/src/channels/slack/nudge-carrier.ts +1 -1
- package/src/channels/slack/nudge-store.ts +2 -2
- package/src/channels/slack/paint-start.ts +93 -0
- package/src/channels/slack/placeholder.ts +315 -0
- package/src/channels/slack/progress-delivery.ts +14 -1
- package/src/channels/slack/reasoning-chip.ts +48 -0
- package/src/channels/slack/recording-sink.ts +176 -0
- package/src/channels/slack/reply-options.ts +71 -15
- package/src/channels/slack/setup.ts +1 -1
- package/src/channels/slack/slack-channel.ts +140 -18
- package/src/channels/slack/socket-mode.ts +2 -2
- package/src/channels/slack/thread-context.ts +5 -5
- package/src/channels/slack/tool-approval-events.ts +54 -38
- package/src/channels/slack/tool-cards.ts +1 -1
- package/src/channels/slack/tool-chip.ts +36 -0
- package/src/channels/slack/types.ts +47 -7
- package/src/channels/slack/upload.ts +142 -0
- package/src/channels.ts +12 -30
- package/src/dashboard-session-url.ts +32 -0
- package/src/evals/assertions.ts +19 -19
- package/src/evals/expect.ts +1 -1
- package/src/evals/judge.ts +1 -1
- package/src/evals/reporters.ts +8 -9
- package/src/evals/run-facts.ts +2 -2
- package/src/evals.ts +7 -10
- package/src/extensions/cursor-cloud-agents/extension.ts +1 -1
- package/src/extensions/cursor-cloud-agents/lib/backend.ts +3 -3
- package/src/extensions/cursor-cloud-agents/lib/fleet.ts +1 -1
- package/src/extensions/cursor-cloud-agents/lib/repos.ts +3 -3
- package/src/extensions/cursor-cloud-agents/lib/transcript.ts +3 -4
- package/src/extensions/cursor-cloud-agents/tools/list.ts +1 -1
- package/src/extensions/improve/skills/yourself.ts +1 -1
- package/src/extensions/slack-communication/evals/harness.ts +728 -0
- package/src/extensions/slack-communication/evals/slack-communication.eval.ts +953 -0
- package/src/extensions/slack-communication/evals/slack-placeholder.eval.ts +194 -0
- package/src/extensions/slack-communication/extension.ts +45 -0
- package/src/extensions/slack-communication/skills/slack-voice.ts +59 -0
- package/src/extensions/slack-communication/tools/delete-message.ts +34 -0
- package/src/extensions/slack-communication/tools/edit-message.ts +42 -0
- package/src/extensions/slack-communication/tools/post-card.ts +28 -0
- package/src/extensions/slack-communication/tools/post-file.ts +85 -0
- package/src/extensions/slack-communication/tools/post-update.ts +41 -0
- package/src/extensions/slack-communication/tools/react.ts +33 -0
- package/src/extensions/slack-communication/tools/set-status.ts +21 -0
- package/src/extensions.ts +2 -6
- package/src/files-backends/cursor-hosted.ts +502 -98
- package/src/files-backends/local-fs.ts +1 -1
- package/src/files.ts +15 -0
- package/src/filesystem.ts +16 -18
- package/src/index.ts +4 -39
- package/src/internal/advertise-tools.ts +6 -6
- package/src/internal/approval-gate.ts +1 -1
- package/src/internal/artifacts-store.ts +3 -3
- package/src/internal/as-of.ts +2 -2
- package/src/internal/authored-alias-hooks.ts +32 -0
- package/src/internal/authored-loaders.ts +25 -2
- package/src/internal/builtin-tools/reminders.ts +2 -2
- package/src/internal/chat-client.ts +5 -5
- package/src/internal/cli-ax.ts +85 -16
- package/src/internal/cli-bitbucket.ts +11 -11
- package/src/internal/cli-convert-automation.ts +2 -2
- package/src/internal/cli-cursor.ts +5 -16
- package/src/internal/cli-deploy.ts +389 -104
- package/src/internal/cli-docs.ts +5 -5
- package/src/internal/cli-github.ts +16 -19
- package/src/internal/cli-gitlab.ts +11 -11
- package/src/internal/cli-manifest.ts +1 -1
- package/src/internal/cli-mcp-oauth.ts +5 -7
- package/src/internal/cli-mcp.ts +3 -3
- package/src/internal/cli-skills.ts +2 -2
- package/src/internal/cli-slack.ts +5 -5
- package/src/internal/cloud-turn-cost.ts +1 -1
- package/src/internal/continuation-channel.ts +2 -1
- package/src/internal/continuation-identity.ts +23 -11
- package/src/internal/conversation-mirror.ts +36 -3
- package/src/internal/convert-automation/convert-workflow.ts +27 -27
- package/src/internal/convert-automation/types.ts +9 -0
- package/src/internal/cursor/account-mcp.ts +48 -31
- package/src/internal/cursor/backend-client.ts +28 -17
- package/src/internal/cursor/credentials.ts +1 -1
- package/src/internal/cursor/hosted-store-secrets.ts +34 -0
- package/src/internal/cursor-account-mcp-auth.ts +9 -9
- package/src/internal/cursor-deployment-relay.ts +10 -10
- package/src/internal/cursor-event-relay.ts +10 -10
- package/src/internal/cursor-relay-core.ts +2 -2
- package/src/internal/deploy-client.ts +266 -24
- package/src/internal/deploy-manifest.ts +46 -8
- package/src/internal/discovery/agent-config.ts +34 -0
- package/src/internal/discovery/agent.ts +15 -13
- package/src/internal/discovery/channels.ts +4 -4
- package/src/internal/discovery/connections.ts +4 -4
- package/src/internal/discovery/cursor-plugin.ts +12 -12
- package/src/internal/discovery/extension-overlay.ts +3 -21
- package/src/internal/discovery/extensions.ts +8 -32
- package/src/internal/discovery/info.ts +12 -22
- package/src/internal/discovery/instructions.ts +1 -1
- package/src/internal/discovery/modules.ts +0 -1
- package/src/internal/discovery/project.ts +4 -20
- package/src/internal/discovery/services.ts +1 -1
- package/src/internal/discovery/tools.ts +1 -1
- package/src/internal/docs-site.ts +2 -2
- package/src/internal/env-file.ts +2 -2
- package/src/internal/eval-run-store.ts +7 -9
- package/src/internal/eval-runner.ts +20 -21
- package/src/internal/evals-client.ts +6 -6
- package/src/internal/event-log.ts +10 -10
- package/src/internal/event-mapper.ts +37 -2
- package/src/internal/filesystem/format.ts +11 -12
- package/src/internal/filesystem/scratch.ts +3 -3
- package/src/internal/filesystem/tools.ts +6 -8
- package/src/internal/filesystem/walk.ts +1 -1
- package/src/internal/framework-file-storage.ts +108 -9
- package/src/internal/framework-storage-selection.ts +4 -14
- package/src/internal/github-fanout.ts +4 -4
- package/src/internal/guest-network.ts +4 -4
- package/src/internal/host-files.ts +1 -1
- package/src/internal/host-kv.ts +2 -2
- package/src/internal/hosted-admission-adapter.ts +2 -0
- package/src/internal/hosted-catch-protocol.ts +3 -5
- package/src/internal/hosted-catch.ts +1 -1
- package/src/internal/hosted-delivery-protocol.ts +111 -13
- package/src/internal/hosted-delivery.ts +286 -81
- package/src/internal/hosted-execution-diag.ts +3 -3
- package/src/internal/hosted-execution-latency.ts +334 -0
- package/src/internal/hosting.ts +5 -6
- package/src/internal/http-channel-define.ts +27 -0
- package/src/internal/http-channel.ts +3 -4
- package/src/internal/http-control-plane-session.ts +24 -11
- package/src/internal/incoming-headers-to-fetch.ts +54 -0
- package/src/internal/init-interview.ts +7 -7
- package/src/internal/init-project.ts +14 -16
- package/src/internal/init-scaffold.ts +2 -3
- package/src/internal/inline-stdio-mcp.ts +2 -2
- package/src/internal/install-cursor-skills.ts +49 -16
- package/src/internal/json-schema.ts +1 -1
- package/src/internal/local-control-plane.ts +4 -5
- package/src/internal/local-env.ts +3 -3
- package/src/internal/log-ring.ts +1 -1
- package/src/internal/logs-client.ts +1 -1
- package/src/internal/mcp-endpoint.ts +10 -10
- package/src/internal/mcp-host.ts +9 -9
- package/src/internal/mcp-oauth-on-demand.ts +3 -3
- package/src/internal/mcp-oauth.ts +5 -5
- package/src/internal/net.ts +2 -2
- package/src/internal/otel/config.ts +3 -3
- package/src/internal/otel/runtime.ts +14 -14
- package/src/internal/peer-connections.ts +2 -2
- package/src/internal/platform-schedule-sync.ts +1 -1
- package/src/internal/platform-timers.ts +1 -1
- package/src/internal/playground/static.ts +2 -2
- package/src/internal/playground/toolchain.ts +2 -2
- package/src/internal/playground-proxy.ts +3 -3
- package/src/internal/process-memory-telemetry.ts +1 -1
- package/src/internal/reminder-runner.ts +8 -10
- package/src/internal/reminder-store.ts +1 -1
- package/src/internal/request-error-status.ts +9 -0
- package/src/internal/resolved-connections.ts +8 -8
- package/src/internal/result-output.ts +62 -5
- package/src/internal/router.ts +4 -4
- package/src/internal/run-client.ts +3 -3
- package/src/internal/schedule-runner.ts +6 -6
- package/src/internal/scm/pr-url.ts +11 -2
- package/src/internal/sdk-runner.ts +15 -29
- package/src/internal/serve-restart.ts +1 -1
- package/src/internal/server.ts +97 -115
- package/src/internal/session-cost.ts +3 -3
- package/src/internal/session-engine.ts +517 -445
- package/src/internal/session-run-log.ts +4 -6
- package/src/internal/session-store.ts +213 -39
- package/src/internal/sessions-client.ts +3 -3
- package/src/internal/slack-thread-key.ts +11 -0
- package/src/internal/sleep.ts +1 -1
- package/src/internal/storage-coordinator.ts +122 -96
- package/src/internal/storage-roles.ts +4 -9
- package/src/internal/storage.ts +1 -0
- package/src/internal/store-mirror.ts +4 -4
- package/src/internal/terminal-style.ts +2 -2
- package/src/internal/tool-result.ts +3 -3
- package/src/internal/trajectory.ts +7 -7
- package/src/internal/turn-governor.ts +2 -2
- package/src/internal/turn-outbox.ts +1 -1
- package/src/internal/update-check.ts +2 -2
- package/src/internal/v2-hosting.ts +14 -0
- package/src/internal/workspace.ts +17 -17
- package/src/kv/memory-kv.ts +9 -7
- package/src/kv.ts +4 -7
- package/src/otel-public.ts +24 -0
- package/src/otel.ts +7 -2
- package/src/prompt.ts +1 -1
- package/src/result.ts +10 -8
- package/src/storage-backends/cursor-hosted-v2.ts +6 -9
- package/src/storage-backends/cursor-hosted.ts +6 -60
- package/src/storage-backends/file-kv.ts +17 -58
- package/src/storage-protocol.ts +3 -17
- package/src/storage.ts +32 -108
- package/src/types.ts +101 -73
- package/templates/agentic-owners/agent/channels/github.ts +3 -6
- package/templates/agentic-owners/agent/lib/github.ts +5 -5
- package/templates/agentic-owners/agent/lib/owners/decision.ts +13 -10
- package/templates/agentic-owners/agent/lib/owners/handles.ts +2 -2
- package/templates/agentic-owners/agent/lib/owners/match.ts +3 -3
- package/templates/agentic-owners/agent/lib/owners/matching.ts +1 -1
- package/templates/agentic-owners/agent/lib/owners/parse.ts +4 -9
- package/templates/agentic-owners/agent/lib/owners/prompt.ts +1 -1
- package/templates/agentic-owners/agent/lib/review.ts +37 -30
- package/templates/agentic-owners/evals/owners.eval.ts +2 -2
- package/templates/agentic-owners/package.json +1 -1
- package/templates/agents-md/agent/lib/collect.ts +16 -10
- package/templates/agents-md/agent/lib/config.ts +1 -1
- package/templates/agents-md/agent/tools/apply_agents.ts +10 -8
- package/templates/agents-md/package.json +1 -1
- package/templates/code-wiki/agent/channels/github.ts +4 -7
- package/templates/code-wiki/agent/lib/repos.ts +1 -1
- package/templates/code-wiki/agent/tools/apply_wiki.ts +3 -4
- package/templates/code-wiki/package.json +1 -1
- package/templates/demo/README.md +10 -6
- package/templates/demo/agent/channels/github.ts +2 -0
- package/templates/demo/agent/channels/queue.ts +6 -2
- package/templates/demo/agent/lib/collect.ts +6 -2
- package/templates/demo/agent/lib/repos.ts +5 -0
- package/templates/demo/agent/tools/record_demo.ts +1 -1
- package/templates/demo/evals/demo.eval.ts +1 -5
- package/templates/demo/init.json +25 -0
- package/templates/demo/package.json +1 -1
- package/templates/grokbot-agents/package.json +1 -1
- package/templates/pr-autofixer/agent/channels/github.ts +16 -13
- package/templates/pr-autofixer/agent/lib/merge-watch.ts +2 -4
- package/templates/pr-autofixer/agent/lib/repos.ts +2 -2
- package/templates/pr-autofixer/agent/lib/webhook-routing.ts +1 -1
- package/templates/pr-autofixer/package.json +1 -1
- package/templates/security-help/agent/lib/repos.ts +1 -1
- package/templates/security-help/package.json +1 -1
- package/templates/security-reviewer/agent/lib/repos.ts +1 -1
- package/templates/security-reviewer/agent/tools/post_findings.ts +1 -3
- package/templates/security-reviewer/package.json +1 -1
- package/templates/triage/agent/lib/actuate.ts +26 -41
- package/templates/triage/agent/lib/parse-queue-event.ts +2 -1
- package/templates/triage/agent/lib/verify-webhook.ts +10 -5
- package/templates/triage/agent/tools/record_triage.ts +1 -4
- package/templates/triage/package.json +1 -1
- package/dist/ab.d.ts +0 -209
- package/dist/ab.d.ts.map +0 -1
- package/dist/ab.js +0 -246
- package/dist/client.d.ts +0 -14
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -12
- package/dist/docs/ab.html +0 -80
- package/dist/docs/ab.md +0 -332
- package/dist/docs/assets/ab.md.mlVgqvSk.js +0 -54
- package/dist/docs/assets/ab.md.mlVgqvSk.lean.js +0 -1
- package/dist/docs/assets/app.BASKM3M4.js +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BHZYsNVi.js +0 -1
- package/dist/docs/assets/chunks/framework.BCISBCiQ.js +0 -19
- package/dist/docs/assets/concepts.md.DgEcZOfT.js +0 -1
- package/dist/docs/assets/concepts.md.DgEcZOfT.lean.js +0 -1
- package/dist/docs/assets/evals.md.C1ekS3k2.js +0 -85
- package/dist/docs/assets/evals.md.C1ekS3k2.lean.js +0 -1
- package/dist/docs/assets/guides_agent-to-agent.md.BDb0t1QV.js +0 -10
- package/dist/docs/assets/guides_agent-to-agent.md.BDb0t1QV.lean.js +0 -1
- package/dist/docs/assets/guides_grokbot-agents.md.DyV-WArv.js +0 -9
- package/dist/docs/assets/guides_human-in-the-loop.md.By1G2T3_.js +0 -28
- package/dist/docs/assets/guides_human-in-the-loop.md.By1G2T3_.lean.js +0 -1
- package/dist/docs/assets/hillclimbing.md.CpTGTCle.js +0 -4
- package/dist/docs/assets/hillclimbing.md.CpTGTCle.lean.js +0 -1
- package/dist/docs/assets/index.md.BjH1w2ZW.js +0 -5
- package/dist/docs/assets/index.md.BjH1w2ZW.lean.js +0 -1
- package/dist/docs/assets/quickstart.md.DdQOF7Y8.lean.js +0 -1
- package/dist/docs/assets/reference_project-layout.md.DuBu9a96.js +0 -19
- package/dist/docs/assets/reference_result.md.BK5SxDrf.js +0 -19
- package/dist/docs/assets/reference_result.md.BK5SxDrf.lean.js +0 -1
- package/dist/docs/assets/reference_sessions.md.CueyOHSL.js +0 -1
- package/dist/docs/assets/scaffolding-agents.md.Kctn3OVb.js +0 -1
- package/dist/docs/assets/scaffolding-agents.md.Kctn3OVb.lean.js +0 -1
- package/dist/docs/assets/skills_ab.md.CsFNatVx.js +0 -26
- package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +0 -1
- package/dist/docs/assets/skills_create-agent.md.Q3h6Je-e.js +0 -8
- package/dist/docs/assets/skills_create-agent.md.Q3h6Je-e.lean.js +0 -1
- package/dist/docs/assets/skills_debug.md.CVjCXMFF.js +0 -1
- package/dist/docs/assets/skills_debug.md.CVjCXMFF.lean.js +0 -1
- package/dist/docs/assets/skills_evals.md.BhovOvrl.js +0 -25
- package/dist/docs/assets/skills_evals.md.BhovOvrl.lean.js +0 -1
- package/dist/docs/assets/skills_framework-map.md.D-tFZhFS.js +0 -1
- package/dist/docs/assets/skills_framework-map.md.D-tFZhFS.lean.js +0 -1
- package/dist/docs/assets/skills_github.md.hgFX_oKY.js +0 -16
- package/dist/docs/assets/skills_github.md.hgFX_oKY.lean.js +0 -1
- package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.js +0 -7
- package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.lean.js +0 -1
- package/dist/docs/assets/skills_index.md.DKwIxzGg.js +0 -1
- package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +0 -1
- package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.js +0 -18
- package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.lean.js +0 -1
- package/dist/docs/assets/skills_otel.md.B5Ddv1xH.js +0 -8
- package/dist/docs/assets/skills_otel.md.B5Ddv1xH.lean.js +0 -1
- package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.js +0 -20
- package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.lean.js +0 -1
- package/dist/docs/assets/storage.md.BOHeqk2M.js +0 -30
- package/dist/docs/assets/storage.md.BOHeqk2M.lean.js +0 -1
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +0 -2
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +0 -1
- package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.js +0 -2
- package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.lean.js +0 -1
- package/dist/docs/assets/templates_demo.md.BeQX9V3H.js +0 -4
- package/dist/docs/assets/templates_demo.md.BeQX9V3H.lean.js +0 -1
- package/dist/docs/assets/templates_grokbot-agents.md.c1s6Flp9.js +0 -3
- package/dist/docs/assets/templates_grokbot-agents.md.c1s6Flp9.lean.js +0 -1
- package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.js +0 -4
- package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.lean.js +0 -1
- package/dist/docs/concepts.html +0 -27
- package/dist/docs/concepts.md +0 -168
- package/dist/docs/design/filesystem.md +0 -376
- package/dist/docs/design/runtime-abstraction.md +0 -1756
- package/dist/docs/guides/human-in-the-loop.html +0 -54
- package/dist/docs/guides/human-in-the-loop.md +0 -126
- package/dist/docs/reference/result.html +0 -45
- package/dist/docs/reference/result.md +0 -89
- package/dist/docs/scaffolding-agents.html +0 -27
- package/dist/docs/scaffolding-agents.md +0 -130
- package/dist/docs/skills/ab.html +0 -52
- package/dist/docs/skills/ab.md +0 -50
- package/dist/docs/skills/create-agent.html +0 -34
- package/dist/docs/skills/create-agent.md +0 -160
- package/dist/docs/skills/debug.html +0 -27
- package/dist/docs/skills/debug.md +0 -36
- package/dist/docs/skills/evals.html +0 -51
- package/dist/docs/skills/evals.md +0 -99
- package/dist/docs/skills/framework-map.html +0 -27
- package/dist/docs/skills/framework-map.md +0 -100
- package/dist/docs/skills/github.html +0 -42
- package/dist/docs/skills/github.md +0 -93
- package/dist/docs/skills/hillclimb.html +0 -33
- package/dist/docs/skills/hillclimb.md +0 -55
- package/dist/docs/skills/index.html +0 -27
- package/dist/docs/skills/index.md +0 -21
- package/dist/docs/skills/mcp-auth.html +0 -44
- package/dist/docs/skills/mcp-auth.md +0 -76
- package/dist/docs/skills/otel.html +0 -34
- package/dist/docs/skills/otel.md +0 -53
- package/dist/docs/skills/setup-slack.html +0 -46
- package/dist/docs/skills/setup-slack.md +0 -141
- package/dist/docs/storage.html +0 -56
- package/dist/docs/storage.md +0 -176
- package/dist/docs/templates/agents-md.html +0 -28
- package/dist/docs/templates/agents-md.md +0 -105
- package/dist/docs/templates/code-wiki.html +0 -28
- package/dist/docs/templates/code-wiki.md +0 -91
- package/dist/docs/templates/demo.html +0 -30
- package/dist/docs/templates/demo.md +0 -80
- package/dist/docs/templates/grokbot-agents.html +0 -29
- package/dist/docs/templates/grokbot-agents.md +0 -48
- package/dist/docs/templates/security-help.html +0 -30
- package/dist/docs/templates/security-help.md +0 -65
- package/dist/internal/ab-collector.d.ts +0 -44
- package/dist/internal/ab-collector.d.ts.map +0 -1
- package/dist/internal/ab-collector.js +0 -142
- package/dist/internal/ab-fold.d.ts +0 -36
- package/dist/internal/ab-fold.d.ts.map +0 -1
- package/dist/internal/ab-fold.js +0 -175
- package/dist/internal/ab-snapshot.d.ts +0 -68
- package/dist/internal/ab-snapshot.d.ts.map +0 -1
- package/dist/internal/ab-snapshot.js +0 -208
- package/dist/internal/discovery/ab.d.ts +0 -9
- package/dist/internal/discovery/ab.d.ts.map +0 -1
- package/dist/internal/discovery/ab.js +0 -113
- package/dist/internal/tenant-slack/relay.d.ts +0 -75
- package/dist/internal/tenant-slack/relay.d.ts.map +0 -1
- package/dist/internal/tenant-slack/relay.js +0 -148
- package/dist/playground/assets/index-BMDqAeXu.js +0 -67
- package/dist/playground/assets/index-LUgJoWdL.css +0 -1
- package/docs/ab.md +0 -337
- package/docs/concepts.md +0 -173
- package/docs/design/filesystem.md +0 -376
- package/docs/design/runtime-abstraction.md +0 -1756
- package/docs/guides/human-in-the-loop.md +0 -131
- package/docs/reference/result.md +0 -94
- package/docs/scaffolding-agents.md +0 -135
- package/docs/skills/index.md +0 -26
- package/docs/storage.md +0 -181
- package/docs/templates/agents-md.md +0 -110
- package/docs/templates/code-wiki.md +0 -96
- package/docs/templates/demo.md +0 -85
- package/docs/templates/grokbot-agents.md +0 -53
- package/docs/templates/security-help.md +0 -70
- package/skills/ab/SKILL.md +0 -58
- package/src/ab.ts +0 -430
- package/src/client.ts +0 -23
- package/src/internal/ab-collector.ts +0 -200
- package/src/internal/ab-fold.ts +0 -232
- package/src/internal/ab-snapshot.ts +0 -331
- package/src/internal/discovery/ab.ts +0 -131
- package/src/internal/tenant-slack/relay.ts +0 -203
- package/templates/pr-autofixer/agent/storage.ts +0 -7
|
@@ -8,16 +8,10 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
11
|
-
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
11
|
+
import { access, mkdir, rm, writeFile } from "node:fs/promises";
|
|
12
12
|
import { dirname, join } from "node:path";
|
|
13
13
|
import type { SDKCustomTool, SDKCustomToolResult } from "@cursor/sdk";
|
|
14
14
|
import type { Meter } from "@opentelemetry/api";
|
|
15
|
-
import {
|
|
16
|
-
type ABDefinition,
|
|
17
|
-
mergeABInstructions,
|
|
18
|
-
resolveABMaxPlaygroundSessions,
|
|
19
|
-
resolveABSplit,
|
|
20
|
-
} from "../ab.js";
|
|
21
15
|
import { SLACK_CHANNEL_ID } from "../channels/slack/constants.js";
|
|
22
16
|
import { materializeSlackNudgeCarrier } from "../channels/slack/nudge-carrier.js";
|
|
23
17
|
import {
|
|
@@ -98,9 +92,6 @@ import {
|
|
|
98
92
|
type ToolNeedsApproval,
|
|
99
93
|
type TurnOutcome,
|
|
100
94
|
} from "../types.js";
|
|
101
|
-
import { ABCollector } from "./ab-collector.js";
|
|
102
|
-
import { foldABStream } from "./ab-fold.js";
|
|
103
|
-
import { type ABSnapshot, buildABSnapshot } from "./ab-snapshot.js";
|
|
104
95
|
import {
|
|
105
96
|
type AdvertiseHostMcp,
|
|
106
97
|
resolveAdvertisedTools,
|
|
@@ -185,7 +176,12 @@ import {
|
|
|
185
176
|
SCHEDULE_CHANNEL_PREFIX,
|
|
186
177
|
} from "./prompt-context.js";
|
|
187
178
|
import { assertCloudCanHonorAccountServersFilters } from "./resolved-connections.js";
|
|
188
|
-
import {
|
|
179
|
+
import {
|
|
180
|
+
addTurnUsage,
|
|
181
|
+
applyAuthoredResult,
|
|
182
|
+
RESULT_REPAIR_BUDGET,
|
|
183
|
+
resultRepairPrompt,
|
|
184
|
+
} from "./result-output.js";
|
|
189
185
|
import type { AgentRunner, SteerAckOutcome } from "./sdk-runner.js";
|
|
190
186
|
import { sessionExternalLinks } from "./session-links.js";
|
|
191
187
|
import { SessionStore } from "./session-store.js";
|
|
@@ -252,6 +248,21 @@ export class SessionBusyError extends Error {
|
|
|
252
248
|
}
|
|
253
249
|
}
|
|
254
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Hosted enqueue-only admission could not coalesce into an active turn.
|
|
253
|
+
* Distinct from {@link SessionBusyError}: the caller asked not to start work.
|
|
254
|
+
*/
|
|
255
|
+
export class HostedEnqueueNotActiveError extends Error {
|
|
256
|
+
constructor(sessionId?: string) {
|
|
257
|
+
super(
|
|
258
|
+
sessionId === undefined
|
|
259
|
+
? "Hosted enqueue requires an active accepting session"
|
|
260
|
+
: `Hosted enqueue requires an active turn on session ${sessionId}`
|
|
261
|
+
);
|
|
262
|
+
this.name = "HostedEnqueueNotActiveError";
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
255
266
|
// Defined in auth.js (HTTP/session-store callers import it without this
|
|
256
267
|
// module); re-exported here because this is its historical public home.
|
|
257
268
|
export { SessionAuthError } from "./auth.js";
|
|
@@ -423,6 +434,12 @@ export interface EngineSendOptions extends SendMessageOptions {
|
|
|
423
434
|
* authors cannot choose a session id through the public SendMessageOptions.
|
|
424
435
|
*/
|
|
425
436
|
hostedSessionId?: string;
|
|
437
|
+
/**
|
|
438
|
+
* Hosted active-guest enqueue: admit only by coalescing into an already
|
|
439
|
+
* running turn. Never creates a session or starts a turn. Private host
|
|
440
|
+
* plumbing — not part of public SendMessageOptions.
|
|
441
|
+
*/
|
|
442
|
+
hostedEnqueueOnly?: boolean;
|
|
426
443
|
}
|
|
427
444
|
|
|
428
445
|
interface CoalescedQueuedTurn {
|
|
@@ -438,6 +455,39 @@ interface AdmitTurnOptions {
|
|
|
438
455
|
* coalesce drain so asks that arrived during drain are not wiped.
|
|
439
456
|
*/
|
|
440
457
|
retainCoalesced?: boolean;
|
|
458
|
+
/** See {@link EngineSendOptions.hostedEnqueueOnly}. */
|
|
459
|
+
hostedEnqueueOnly?: boolean;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/** Marker that we `git init`'d this shared harness so scaffold is ours to write. */
|
|
463
|
+
const OWNED_HARNESS = join(".agent-serve", "owned-harness");
|
|
464
|
+
|
|
465
|
+
function pathExists(path: string): Promise<boolean> {
|
|
466
|
+
return access(path).then(
|
|
467
|
+
() => true,
|
|
468
|
+
() => false
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Nested dirs get their own git root so the harness does not ripwalk the
|
|
474
|
+
* enclosing checkout. A real `workspaceDir` checkout (already a git root)
|
|
475
|
+
* is left alone.
|
|
476
|
+
*/
|
|
477
|
+
async function ownSharedHarness(dir: string): Promise<boolean> {
|
|
478
|
+
if (await pathExists(join(dir, OWNED_HARNESS))) {
|
|
479
|
+
return true;
|
|
480
|
+
}
|
|
481
|
+
if (!(await isNestedInGitRepo(dir))) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
await ensureOwnGitRoot(dir);
|
|
485
|
+
if (await isNestedInGitRepo(dir)) {
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
await mkdir(join(dir, ".agent-serve"), { recursive: true });
|
|
489
|
+
await writeFile(join(dir, OWNED_HARNESS), "");
|
|
490
|
+
return true;
|
|
441
491
|
}
|
|
442
492
|
|
|
443
493
|
export class SessionEngine {
|
|
@@ -455,8 +505,8 @@ export class SessionEngine {
|
|
|
455
505
|
/**
|
|
456
506
|
* Runtime for `agent/storage.ts` (`defineStorage`), when
|
|
457
507
|
* authored. All durable state changes funnel through it (session
|
|
458
|
-
* records, event chunks
|
|
459
|
-
*
|
|
508
|
+
* records, event chunks); the eval run store attaches via
|
|
509
|
+
* {@link StorageCoordinator.evalRuns} at serve start.
|
|
460
510
|
*/
|
|
461
511
|
readonly storage: StorageCoordinator | undefined;
|
|
462
512
|
/** In-flight lazy restores, deduped per channel + continuation key. */
|
|
@@ -464,8 +514,6 @@ export class SessionEngine {
|
|
|
464
514
|
string,
|
|
465
515
|
Promise<SessionRecord | undefined>
|
|
466
516
|
>();
|
|
467
|
-
/** Once-per-process cache for the A/B snapshot backfill (see abSnapshot). */
|
|
468
|
-
private restoredAbSnapshot: Promise<ABSnapshot | undefined> | undefined;
|
|
469
517
|
/** In-flight authored files → Agent Store syncs (see syncToCloudStore). */
|
|
470
518
|
private readonly cloudSyncs = new Map<CloudSyncSurface, Promise<boolean>>();
|
|
471
519
|
|
|
@@ -504,6 +552,8 @@ export class SessionEngine {
|
|
|
504
552
|
private readonly turnAborts = new Map<string, AbortController>();
|
|
505
553
|
/** Serializes turn admission per session (latest follow-up wins). */
|
|
506
554
|
private readonly admissionChains = new Map<string, Promise<unknown>>();
|
|
555
|
+
/** Live turn snapshot so a coalesced Slack wake can repaint on this process. */
|
|
556
|
+
private readonly liveTurns = new Map<string, EventDispatchContext>();
|
|
507
557
|
/** FIFO turn slots under `concurrency.maxRunningTurns` (unlimited when unset). */
|
|
508
558
|
private readonly turnGovernor: TurnGovernor;
|
|
509
559
|
/**
|
|
@@ -528,7 +578,6 @@ export class SessionEngine {
|
|
|
528
578
|
private probeCursorAccount:
|
|
529
579
|
| ((connection: string) => Promise<string | undefined>)
|
|
530
580
|
| undefined;
|
|
531
|
-
private readonly abCollector: ABCollector;
|
|
532
581
|
private readonly otel: OtelCollector | undefined;
|
|
533
582
|
private readonly otelHost: HostOtelSessionApi;
|
|
534
583
|
private readonly stopMemoryTelemetry: (() => void) | undefined;
|
|
@@ -559,6 +608,8 @@ export class SessionEngine {
|
|
|
559
608
|
string,
|
|
560
609
|
{ root: FileSystem; cwd: string }
|
|
561
610
|
>();
|
|
611
|
+
/** In-flight `prewarmSharedWorkspace`; first turn waits so it lands hot. */
|
|
612
|
+
private sharedWarm: Promise<void> | undefined;
|
|
562
613
|
|
|
563
614
|
constructor(options: SessionEngineOptions) {
|
|
564
615
|
this.project = options.project;
|
|
@@ -587,7 +638,7 @@ export class SessionEngine {
|
|
|
587
638
|
);
|
|
588
639
|
this.outbox = new TurnOutbox(join(options.stateRoot, "outbox"));
|
|
589
640
|
this.logs = new EventLogStore(
|
|
590
|
-
|
|
641
|
+
sessionId => this.sessions.eventFilePath(sessionId),
|
|
591
642
|
(sessionId, error) =>
|
|
592
643
|
this.logger(
|
|
593
644
|
`[agent-sdk] failed to persist events for ${sessionId}: ${describeError(error)}`
|
|
@@ -639,13 +690,6 @@ export class SessionEngine {
|
|
|
639
690
|
config: options.project.artifacts,
|
|
640
691
|
sink: managedV2Files?.(),
|
|
641
692
|
});
|
|
642
|
-
this.abCollector = new ABCollector(
|
|
643
|
-
options.project.abs,
|
|
644
|
-
this.logger,
|
|
645
|
-
async (sessionId) => (await this.logs.get(sessionId)).snapshot(0),
|
|
646
|
-
// Samples flow to the defineStorage `abs` table (no-op without one).
|
|
647
|
-
{ persistSample: (sample) => this.storage?.abSample(sample) }
|
|
648
|
-
);
|
|
649
693
|
// Peer and Cursor-account transports are symbolic until the serve host
|
|
650
694
|
// resolves them; the host-side MCP registry starts with the concrete
|
|
651
695
|
// connections and gains the rest via setResolvedConnections.
|
|
@@ -654,7 +698,7 @@ export class SessionEngine {
|
|
|
654
698
|
...options.project.agent.connections,
|
|
655
699
|
...(options.project.agent.hostConnections ?? []),
|
|
656
700
|
].filter(
|
|
657
|
-
|
|
701
|
+
connection => !isSymbolicConnectionTransport(connection.transport)
|
|
658
702
|
)
|
|
659
703
|
);
|
|
660
704
|
const basePlatforms = options.platforms ?? createHostPlatforms();
|
|
@@ -707,8 +751,8 @@ export class SessionEngine {
|
|
|
707
751
|
|
|
708
752
|
private authoredConnection(name: string): DiscoveredConnection | undefined {
|
|
709
753
|
return (
|
|
710
|
-
this.project.agent.connections.find(
|
|
711
|
-
this.project.agent.hostConnections?.find(
|
|
754
|
+
this.project.agent.connections.find(item => item.name === name) ??
|
|
755
|
+
this.project.agent.hostConnections?.find(item => item.name === name)
|
|
712
756
|
);
|
|
713
757
|
}
|
|
714
758
|
|
|
@@ -777,7 +821,7 @@ export class SessionEngine {
|
|
|
777
821
|
*/
|
|
778
822
|
artifactsApi(binding?: { sessionId: string; turnId?: string }): ArtifactsApi {
|
|
779
823
|
return {
|
|
780
|
-
tag: async
|
|
824
|
+
tag: async input => {
|
|
781
825
|
if (binding === undefined) {
|
|
782
826
|
return this.tagArtifact(input);
|
|
783
827
|
}
|
|
@@ -795,7 +839,7 @@ export class SessionEngine {
|
|
|
795
839
|
turnId: input.turnId ?? binding.turnId,
|
|
796
840
|
});
|
|
797
841
|
},
|
|
798
|
-
list:
|
|
842
|
+
list: filter => this.artifactsStore.list(filter),
|
|
799
843
|
};
|
|
800
844
|
}
|
|
801
845
|
|
|
@@ -944,11 +988,11 @@ export class SessionEngine {
|
|
|
944
988
|
|
|
945
989
|
private slackNudgeHostApi(): SlackNudgeHostApi {
|
|
946
990
|
return {
|
|
947
|
-
append:
|
|
948
|
-
drainFormatted:
|
|
991
|
+
append: input => this.nudgeStore.append(input),
|
|
992
|
+
drainFormatted: continuationKey =>
|
|
949
993
|
this.nudgeStore.drainFormatted(continuationKey),
|
|
950
|
-
clear:
|
|
951
|
-
hasUndelivered:
|
|
994
|
+
clear: continuationKey => this.nudgeStore.clear(continuationKey),
|
|
995
|
+
hasUndelivered: continuationKey =>
|
|
952
996
|
this.nudgeStore.hasUndelivered(continuationKey),
|
|
953
997
|
isDelivered: (continuationKey, sourceTs) =>
|
|
954
998
|
this.nudgeStore.isDelivered(continuationKey, sourceTs),
|
|
@@ -1058,61 +1102,76 @@ export class SessionEngine {
|
|
|
1058
1102
|
// Refresh harness cwd when the caller supplies a newer worktree (e.g. PR
|
|
1059
1103
|
// synchronize). Leave the durable continuation key unchanged.
|
|
1060
1104
|
let record = existing;
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
:
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
current
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1105
|
+
const enqueueOnly = sendOptions.hostedEnqueueOnly === true;
|
|
1106
|
+
if (!enqueueOnly) {
|
|
1107
|
+
const refreshWorkspace =
|
|
1108
|
+
sendOptions.workspaceDir !== undefined &&
|
|
1109
|
+
sendOptions.workspaceDir !== existing.workspaceOverride;
|
|
1110
|
+
if (
|
|
1111
|
+
refreshWorkspace ||
|
|
1112
|
+
sendOptions.workspaceFiles !== undefined ||
|
|
1113
|
+
sendOptions.images !== undefined
|
|
1114
|
+
) {
|
|
1115
|
+
record = await this.updateRecord(existing.sessionId, current => ({
|
|
1116
|
+
...current,
|
|
1117
|
+
workspaceOverride: refreshWorkspace
|
|
1118
|
+
? sendOptions.workspaceDir
|
|
1119
|
+
: current.workspaceOverride,
|
|
1120
|
+
pendingWorkspaceFiles: mergePendingWorkspaceFiles(
|
|
1121
|
+
current.pendingWorkspaceFiles,
|
|
1122
|
+
sendOptions.workspaceFiles
|
|
1123
|
+
),
|
|
1124
|
+
pendingImages: mergePendingImages(
|
|
1125
|
+
current.pendingImages,
|
|
1126
|
+
sendOptions.images
|
|
1127
|
+
),
|
|
1128
|
+
}));
|
|
1129
|
+
}
|
|
1130
|
+
// Refresh the cloud attach the same way: a follow-up send carries the
|
|
1131
|
+
// caller's CURRENT cloud options (e.g. a PR attach re-derived per wake),
|
|
1132
|
+
// and the first send's snapshot must not pin this session's turns to a
|
|
1133
|
+
// stale repo/prUrl for the session's lifetime.
|
|
1134
|
+
if (
|
|
1135
|
+
sendOptions.cloud !== undefined &&
|
|
1136
|
+
JSON.stringify(sendOptions.cloud) !==
|
|
1137
|
+
JSON.stringify(record.cloudOverride)
|
|
1138
|
+
) {
|
|
1139
|
+
record = await this.updateRecord(record.sessionId, current => ({
|
|
1140
|
+
...current,
|
|
1141
|
+
cloudOverride: sendOptions.cloud,
|
|
1142
|
+
}));
|
|
1143
|
+
}
|
|
1144
|
+
// Refresh wake-derived channel state (GitHub headSha / refs) without
|
|
1145
|
+
// wiping sticky fields. Null patch values are skipped.
|
|
1146
|
+
if (sendOptions.refreshState !== undefined) {
|
|
1147
|
+
record = await this.updateRecord(record.sessionId, current => ({
|
|
1148
|
+
...current,
|
|
1149
|
+
channelState: mergeChannelStateSkipNull(
|
|
1150
|
+
current.channelState,
|
|
1151
|
+
sendOptions.refreshState
|
|
1152
|
+
),
|
|
1153
|
+
}));
|
|
1154
|
+
}
|
|
1108
1155
|
}
|
|
1109
1156
|
const since = (await this.logs.get(record.sessionId)).count;
|
|
1110
1157
|
const coalesced = await this.startTurn(record.sessionId, message, {
|
|
1111
|
-
admission:
|
|
1158
|
+
admission: enqueueOnly
|
|
1159
|
+
? "coalesce"
|
|
1160
|
+
: (sendOptions.admission ?? "preempt"),
|
|
1112
1161
|
...(sendOptions.coalesceSourceTs === undefined
|
|
1113
1162
|
? {}
|
|
1114
1163
|
: { sourceTs: sendOptions.coalesceSourceTs }),
|
|
1164
|
+
...(enqueueOnly ? { hostedEnqueueOnly: true } : {}),
|
|
1115
1165
|
});
|
|
1166
|
+
if (enqueueOnly && !coalesced) {
|
|
1167
|
+
throw new HostedEnqueueNotActiveError(record.sessionId);
|
|
1168
|
+
}
|
|
1169
|
+
if (!enqueueOnly && coalesced && sendOptions.refreshState !== undefined) {
|
|
1170
|
+
await this.repaintOnCoalescedRefresh(
|
|
1171
|
+
record.sessionId,
|
|
1172
|
+
sendOptions.refreshState
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1116
1175
|
return this.channelSession(
|
|
1117
1176
|
record.sessionId,
|
|
1118
1177
|
record,
|
|
@@ -1122,6 +1181,10 @@ export class SessionEngine {
|
|
|
1122
1181
|
);
|
|
1123
1182
|
}
|
|
1124
1183
|
|
|
1184
|
+
if (sendOptions.hostedEnqueueOnly === true) {
|
|
1185
|
+
throw new HostedEnqueueNotActiveError(sendOptions.hostedSessionId);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1125
1188
|
if (sendOptions.hostedSessionId !== undefined) {
|
|
1126
1189
|
const collision = await this.getOrRestoreSession(
|
|
1127
1190
|
sendOptions.hostedSessionId
|
|
@@ -1138,7 +1201,7 @@ export class SessionEngine {
|
|
|
1138
1201
|
const purpose = sendOptions.purpose === "eval" ? "eval" : "live";
|
|
1139
1202
|
const frozenAsOf = normalizeAsOf(sendOptions.asOf);
|
|
1140
1203
|
assertTimeArgs(this.project.agent.tools, frozenAsOf);
|
|
1141
|
-
|
|
1204
|
+
const record: SessionRecord = {
|
|
1142
1205
|
sessionId: sendOptions.hostedSessionId ?? newSessionId(),
|
|
1143
1206
|
channelId,
|
|
1144
1207
|
mode: sendOptions.mode ?? "chat",
|
|
@@ -1167,7 +1230,6 @@ export class SessionEngine {
|
|
|
1167
1230
|
dryRun: record.dryRun === true ? true : undefined,
|
|
1168
1231
|
},
|
|
1169
1232
|
});
|
|
1170
|
-
record = await this.enrollABs(record);
|
|
1171
1233
|
const since = (await this.logs.get(record.sessionId)).count;
|
|
1172
1234
|
await this.startTurn(record.sessionId, message, {
|
|
1173
1235
|
admission: sendOptions.admission ?? "preempt",
|
|
@@ -1191,7 +1253,7 @@ export class SessionEngine {
|
|
|
1191
1253
|
const stale = new Error("stale HTTP continuation");
|
|
1192
1254
|
let previous: string | undefined;
|
|
1193
1255
|
try {
|
|
1194
|
-
await this.updateRecord(sessionId,
|
|
1256
|
+
await this.updateRecord(sessionId, record => {
|
|
1195
1257
|
const expectedChannel =
|
|
1196
1258
|
record.httpContinuationKey === undefined
|
|
1197
1259
|
? record.channelId
|
|
@@ -1214,7 +1276,7 @@ export class SessionEngine {
|
|
|
1214
1276
|
await this.startTurn(sessionId, message);
|
|
1215
1277
|
return next;
|
|
1216
1278
|
} catch (error) {
|
|
1217
|
-
await this.updateRecord(sessionId,
|
|
1279
|
+
await this.updateRecord(sessionId, record =>
|
|
1218
1280
|
record.httpContinuationKey === next
|
|
1219
1281
|
? { ...record, httpContinuationKey: previous }
|
|
1220
1282
|
: record
|
|
@@ -1241,97 +1303,6 @@ export class SessionEngine {
|
|
|
1241
1303
|
return existing !== undefined;
|
|
1242
1304
|
}
|
|
1243
1305
|
|
|
1244
|
-
/**
|
|
1245
|
-
* Sticky A/B enrollment at session creation — before the first turn, so
|
|
1246
|
-
* variants are in the durable stream (and on {@link SessionRecord.abs})
|
|
1247
|
-
* ahead of model/instructions work. Failures persist as `variant: null`
|
|
1248
|
-
* (sticky skip). Eval harness sessions (`purpose: "eval"`) are never
|
|
1249
|
-
* enrolled.
|
|
1250
|
-
*/
|
|
1251
|
-
private async enrollABs(record: SessionRecord): Promise<SessionRecord> {
|
|
1252
|
-
if (!this.abCollector.enabled || record.purpose === "eval") {
|
|
1253
|
-
return record;
|
|
1254
|
-
}
|
|
1255
|
-
const sessionInfo = this.sessionInfo(record);
|
|
1256
|
-
const abs: Record<string, string | null> = {};
|
|
1257
|
-
for (const experiment of this.project.abs) {
|
|
1258
|
-
const def = experiment.definition as ABDefinition;
|
|
1259
|
-
const variantKeys = Object.keys(def.variants);
|
|
1260
|
-
let variant: string | null = null;
|
|
1261
|
-
try {
|
|
1262
|
-
variant = await resolveABSplit(def.split, {
|
|
1263
|
-
agent: { name: this.project.name },
|
|
1264
|
-
channel: { id: record.channelId },
|
|
1265
|
-
session: sessionInfo,
|
|
1266
|
-
experiment: experiment.name,
|
|
1267
|
-
variants: variantKeys,
|
|
1268
|
-
});
|
|
1269
|
-
if (variant !== null && !(variant in def.variants)) {
|
|
1270
|
-
throw new Error(
|
|
1271
|
-
`split resolved to ${JSON.stringify(variant)}; expected one of ${variantKeys.join(", ")} or null to skip`
|
|
1272
|
-
);
|
|
1273
|
-
}
|
|
1274
|
-
} catch (error) {
|
|
1275
|
-
this.logger(
|
|
1276
|
-
`[agent-sdk] ab "${experiment.name}" enrollment failed (sticky skip): ${describeError(error)}`
|
|
1277
|
-
);
|
|
1278
|
-
variant = null;
|
|
1279
|
-
}
|
|
1280
|
-
abs[experiment.name] = variant;
|
|
1281
|
-
await this.appendEvent(record.sessionId, {
|
|
1282
|
-
type: "ab.assigned",
|
|
1283
|
-
data: { experiment: experiment.name, variant },
|
|
1284
|
-
});
|
|
1285
|
-
}
|
|
1286
|
-
return this.updateRecord(record.sessionId, (current) => ({
|
|
1287
|
-
...current,
|
|
1288
|
-
abs,
|
|
1289
|
-
}));
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
/**
|
|
1293
|
-
* Ensure {@link SessionRecord.abs} is populated (hydrate from the durable
|
|
1294
|
-
* `ab.assigned` stream when missing — e.g. older sessions after upgrade).
|
|
1295
|
-
*/
|
|
1296
|
-
private async ensureAbs(record: SessionRecord): Promise<SessionRecord> {
|
|
1297
|
-
if (record.abs !== undefined || record.purpose === "eval") {
|
|
1298
|
-
return record;
|
|
1299
|
-
}
|
|
1300
|
-
if (!this.abCollector.enabled) {
|
|
1301
|
-
return record;
|
|
1302
|
-
}
|
|
1303
|
-
const events = await this.listEvents(record.sessionId, 0);
|
|
1304
|
-
const folded = foldABStream(events);
|
|
1305
|
-
if (folded.arms.size === 0) {
|
|
1306
|
-
return record;
|
|
1307
|
-
}
|
|
1308
|
-
const abs = Object.fromEntries(folded.arms);
|
|
1309
|
-
return this.updateRecord(record.sessionId, (current) => ({
|
|
1310
|
-
...current,
|
|
1311
|
-
abs,
|
|
1312
|
-
}));
|
|
1313
|
-
}
|
|
1314
|
-
|
|
1315
|
-
/**
|
|
1316
|
-
* Agent config for this session: base project agent plus any per-variant
|
|
1317
|
-
* `instructions` overlays from enrolled A/B arms.
|
|
1318
|
-
*/
|
|
1319
|
-
private agentForSession(record: SessionRecord): ResolvedAgent {
|
|
1320
|
-
const base = this.project.agent;
|
|
1321
|
-
const instructions = mergeABInstructions(
|
|
1322
|
-
base.instructions,
|
|
1323
|
-
record.abs,
|
|
1324
|
-
this.project.abs.map((experiment) => ({
|
|
1325
|
-
name: experiment.name,
|
|
1326
|
-
definition: experiment.definition as ABDefinition,
|
|
1327
|
-
}))
|
|
1328
|
-
);
|
|
1329
|
-
if (instructions === base.instructions) {
|
|
1330
|
-
return base;
|
|
1331
|
-
}
|
|
1332
|
-
return { ...base, instructions };
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
1306
|
/** Look up a session as a channel-scoped handle. */
|
|
1336
1307
|
async getChannelSession(
|
|
1337
1308
|
channelId: string,
|
|
@@ -1396,6 +1367,53 @@ export class SessionEngine {
|
|
|
1396
1367
|
// Turn execution
|
|
1397
1368
|
// ==========================================================================
|
|
1398
1369
|
|
|
1370
|
+
/**
|
|
1371
|
+
* Repaint on the follow-up wake without retargeting the live turn.
|
|
1372
|
+
* Persist already took the refresh; in-flight writes stay on the carrier ts.
|
|
1373
|
+
*/
|
|
1374
|
+
private async repaintOnCoalescedRefresh(
|
|
1375
|
+
sessionId: string,
|
|
1376
|
+
patch: JsonValue | undefined
|
|
1377
|
+
): Promise<void> {
|
|
1378
|
+
const live = this.liveTurns.get(sessionId);
|
|
1379
|
+
if (live === undefined || patch === undefined) {
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
const repaintState =
|
|
1383
|
+
mergeChannelStateSkipNull(live.channelState, patch) ?? live.channelState;
|
|
1384
|
+
const record = await this.sessions.get(sessionId);
|
|
1385
|
+
if (record === undefined) {
|
|
1386
|
+
return;
|
|
1387
|
+
}
|
|
1388
|
+
const handler = this.channelEventHandlersFor(record.channelId)?.[
|
|
1389
|
+
"message.received"
|
|
1390
|
+
];
|
|
1391
|
+
if (handler === undefined) {
|
|
1392
|
+
return;
|
|
1393
|
+
}
|
|
1394
|
+
await handler(
|
|
1395
|
+
{
|
|
1396
|
+
type: "message.received",
|
|
1397
|
+
data: { text: "" },
|
|
1398
|
+
index: 0,
|
|
1399
|
+
sessionId,
|
|
1400
|
+
at: new Date().toISOString(),
|
|
1401
|
+
},
|
|
1402
|
+
{
|
|
1403
|
+
channelId: record.channelId,
|
|
1404
|
+
state: repaintState,
|
|
1405
|
+
continuationToken: record.continuationKey,
|
|
1406
|
+
setContinuationToken: (token: string | null) =>
|
|
1407
|
+
this.setContinuationToken(sessionId, token),
|
|
1408
|
+
},
|
|
1409
|
+
{
|
|
1410
|
+
session: live.session,
|
|
1411
|
+
host: this.hostForSession(sessionId),
|
|
1412
|
+
artifacts: this.artifactsApi({ sessionId }),
|
|
1413
|
+
}
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1399
1417
|
/**
|
|
1400
1418
|
* Admit a turn for `sessionId`.
|
|
1401
1419
|
*
|
|
@@ -1417,7 +1435,12 @@ export class SessionEngine {
|
|
|
1417
1435
|
.catch(() => {})
|
|
1418
1436
|
.then(async () => {
|
|
1419
1437
|
// Another server holds the turn: hand the message to it and coalesce.
|
|
1438
|
+
// Enqueue-only must not report coalesced success without a local
|
|
1439
|
+
// enqueue — the outbox drain may never run on this process.
|
|
1420
1440
|
if (await this.turnLeases.runningElsewhere(sessionId)) {
|
|
1441
|
+
if (options.hostedEnqueueOnly === true) {
|
|
1442
|
+
throw new HostedEnqueueNotActiveError(sessionId);
|
|
1443
|
+
}
|
|
1421
1444
|
await this.outbox.post(sessionId, { message, options });
|
|
1422
1445
|
return true;
|
|
1423
1446
|
}
|
|
@@ -1434,7 +1457,7 @@ export class SessionEngine {
|
|
|
1434
1457
|
private drainOutbox(sessionId: string): void {
|
|
1435
1458
|
void this.outbox
|
|
1436
1459
|
.takeAll(sessionId)
|
|
1437
|
-
.then(
|
|
1460
|
+
.then(items => {
|
|
1438
1461
|
for (const item of items) {
|
|
1439
1462
|
void this.startTurn(sessionId, item.message, item.options).catch(
|
|
1440
1463
|
() => {}
|
|
@@ -1448,7 +1471,7 @@ export class SessionEngine {
|
|
|
1448
1471
|
const queue = this.coalesceQueues.get(sessionId) ?? [];
|
|
1449
1472
|
if (
|
|
1450
1473
|
item.sourceTs !== undefined &&
|
|
1451
|
-
queue.some(
|
|
1474
|
+
queue.some(entry => entry.sourceTs === item.sourceTs)
|
|
1452
1475
|
) {
|
|
1453
1476
|
return;
|
|
1454
1477
|
}
|
|
@@ -1529,7 +1552,7 @@ export class SessionEngine {
|
|
|
1529
1552
|
}
|
|
1530
1553
|
const parts = [
|
|
1531
1554
|
"<slack_followups>",
|
|
1532
|
-
|
|
1555
|
+
`${items.length} asks arrived while you were busy.`,
|
|
1533
1556
|
"",
|
|
1534
1557
|
];
|
|
1535
1558
|
for (let i = 0; i < items.length; i++) {
|
|
@@ -1623,11 +1646,21 @@ export class SessionEngine {
|
|
|
1623
1646
|
// enqueue: `drainCoalescedFollowups` reads only this process's queue, so
|
|
1624
1647
|
// the shared nudge store is the carrier. Not redundant with `acquire`
|
|
1625
1648
|
// below — this returns before preempt's `clearCoalesced` drops the queue.
|
|
1649
|
+
// Enqueue-only cannot claim coalesced here: nothing joined a local turn.
|
|
1626
1650
|
if (await this.turnLeases.runningElsewhere(sessionId)) {
|
|
1651
|
+
if (options.hostedEnqueueOnly === true) {
|
|
1652
|
+
throw new HostedEnqueueNotActiveError(sessionId);
|
|
1653
|
+
}
|
|
1627
1654
|
this.logger(`[session] coalesce; another server owns ${sessionId}`);
|
|
1628
1655
|
return true;
|
|
1629
1656
|
}
|
|
1630
1657
|
|
|
1658
|
+
// Enqueue-only must never start a turn (or preempt/interrupt). Steer and
|
|
1659
|
+
// coalesce above already returned true when they absorbed the message.
|
|
1660
|
+
if (options.hostedEnqueueOnly === true) {
|
|
1661
|
+
throw new HostedEnqueueNotActiveError(sessionId);
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1631
1664
|
// Interrupt any turn in flight and wait for it to settle so the SDK run is
|
|
1632
1665
|
// terminal before this turn's send (the follow-up also force-expires as a
|
|
1633
1666
|
// belt-and-suspenders — see buildTurnRequest). Drain-resume skips interrupt:
|
|
@@ -1656,12 +1689,10 @@ export class SessionEngine {
|
|
|
1656
1689
|
|
|
1657
1690
|
let lifecycleInstalled = false;
|
|
1658
1691
|
try {
|
|
1659
|
-
|
|
1692
|
+
const record = await this.updateRecord(sessionId, current => ({
|
|
1660
1693
|
...current,
|
|
1661
1694
|
turnCount: current.turnCount + 1,
|
|
1662
1695
|
}));
|
|
1663
|
-
// Arms must be on the record before tools/instructions see SessionInfo.
|
|
1664
|
-
record = await this.ensureAbs(record);
|
|
1665
1696
|
const turnId = `turn_${record.turnCount}`;
|
|
1666
1697
|
const isFirstTurn = record.turnCount === 1;
|
|
1667
1698
|
|
|
@@ -1704,6 +1735,7 @@ export class SessionEngine {
|
|
|
1704
1735
|
};
|
|
1705
1736
|
} finally {
|
|
1706
1737
|
clearInterval(poll);
|
|
1738
|
+
this.liveTurns.delete(sessionId);
|
|
1707
1739
|
}
|
|
1708
1740
|
this.lastOutcomes.set(sessionId, outcome);
|
|
1709
1741
|
const wasCurrent = this.activeTurns.get(sessionId) === lifecycle;
|
|
@@ -1713,14 +1745,19 @@ export class SessionEngine {
|
|
|
1713
1745
|
if (this.turnAborts.get(sessionId) === abort) {
|
|
1714
1746
|
this.turnAborts.delete(sessionId);
|
|
1715
1747
|
}
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1748
|
+
// Failed/cancelled owners must not start a coalesced successor.
|
|
1749
|
+
// Hosted execute would then 503 and Temporal/FIFO would re-run the
|
|
1750
|
+
// same follow-ups as full deliveries.
|
|
1751
|
+
if (
|
|
1752
|
+
wasCurrent &&
|
|
1753
|
+
!abort.signal.aborted &&
|
|
1754
|
+
outcome.status === "finished"
|
|
1755
|
+
) {
|
|
1756
|
+
const drain = this.drainCoalescedFollowups(sessionId).catch(error => {
|
|
1757
|
+
this.logger(
|
|
1758
|
+
`[session] coalesce drain failed for ${sessionId}: ${describeError(error)}`
|
|
1759
|
+
);
|
|
1760
|
+
});
|
|
1724
1761
|
this.coalesceDrains.set(sessionId, drain);
|
|
1725
1762
|
try {
|
|
1726
1763
|
await drain;
|
|
@@ -1980,7 +2017,7 @@ export class SessionEngine {
|
|
|
1980
2017
|
if (turn === undefined) {
|
|
1981
2018
|
return tools;
|
|
1982
2019
|
}
|
|
1983
|
-
return tools.map(
|
|
2020
|
+
return tools.map(tool => {
|
|
1984
2021
|
const execute = tool.definition.execute;
|
|
1985
2022
|
if (typeof execute !== "function") {
|
|
1986
2023
|
return tool;
|
|
@@ -2157,6 +2194,13 @@ export class SessionEngine {
|
|
|
2157
2194
|
* Best effort — warming is an optimization, and a turn rebuilds on its own.
|
|
2158
2195
|
*/
|
|
2159
2196
|
async prewarmSharedWorkspace(): Promise<void> {
|
|
2197
|
+
if (this.sharedWarm === undefined) {
|
|
2198
|
+
this.sharedWarm = this.warmSharedWorkspace();
|
|
2199
|
+
}
|
|
2200
|
+
await this.sharedWarm;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
private async warmSharedWorkspace(): Promise<void> {
|
|
2160
2204
|
const agent = this.project.agent;
|
|
2161
2205
|
const workspaceDir = agent.local?.workspaceDir;
|
|
2162
2206
|
if (
|
|
@@ -2169,6 +2213,15 @@ export class SessionEngine {
|
|
|
2169
2213
|
}
|
|
2170
2214
|
const startedAt = Date.now();
|
|
2171
2215
|
try {
|
|
2216
|
+
await mkdir(workspaceDir, { recursive: true });
|
|
2217
|
+
if (await ownSharedHarness(workspaceDir)) {
|
|
2218
|
+
await materializeWorkspace({
|
|
2219
|
+
agent,
|
|
2220
|
+
workspaceDir,
|
|
2221
|
+
seed: true,
|
|
2222
|
+
stateRoot: this.stateRoot,
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
2172
2225
|
const harness = resolveHostHarnessToolOptions(agent.allowedTools);
|
|
2173
2226
|
const outcome = await this.runner.prewarm({
|
|
2174
2227
|
workspaceDir,
|
|
@@ -2182,7 +2235,10 @@ export class SessionEngine {
|
|
|
2182
2235
|
// warmed without an identity; the per-send flag still has to match
|
|
2183
2236
|
// the turns' requests or the warmed executor is one no turn asks for.
|
|
2184
2237
|
mcpServers: this.buildMcpServers("local"),
|
|
2185
|
-
...(this.hasAttachedAuthedConnections()
|
|
2238
|
+
...(this.hasAttachedAuthedConnections() ||
|
|
2239
|
+
this.project.agent.connections.some(connection =>
|
|
2240
|
+
isCursorAccountTransport(connection.transport)
|
|
2241
|
+
)
|
|
2186
2242
|
? { perSendMcpServers: true }
|
|
2187
2243
|
: {}),
|
|
2188
2244
|
subagents: buildRunnerSubagents(agent),
|
|
@@ -2226,6 +2282,7 @@ export class SessionEngine {
|
|
|
2226
2282
|
channelState: structuredClone(turnChannelState),
|
|
2227
2283
|
session: this.sessionInfo(record),
|
|
2228
2284
|
};
|
|
2285
|
+
this.liveTurns.set(sessionId, eventContext);
|
|
2229
2286
|
// Hold the open log so tool events append synchronously. Fire-and-forget
|
|
2230
2287
|
// `appendEvent` races parallel tool completions and delays the live stream
|
|
2231
2288
|
// until the next await tick — often after *all* parallel tools finish.
|
|
@@ -2243,7 +2300,7 @@ export class SessionEngine {
|
|
|
2243
2300
|
// Read by closure, so the mapper still sees it while draining after the
|
|
2244
2301
|
// registry entry below is gone.
|
|
2245
2302
|
const stubbed = new Set<string>();
|
|
2246
|
-
const mapper = new TurnEventMapper(emit,
|
|
2303
|
+
const mapper = new TurnEventMapper(emit, callId => stubbed.has(callId));
|
|
2247
2304
|
|
|
2248
2305
|
// Take a turn slot before any work happens. When every slot is busy the
|
|
2249
2306
|
// turn waits FIFO — durable `turn.queued` marks the wait — and a
|
|
@@ -2252,7 +2309,7 @@ export class SessionEngine {
|
|
|
2252
2309
|
const permit = await this.turnGovernor.acquire({
|
|
2253
2310
|
sessionId,
|
|
2254
2311
|
signal,
|
|
2255
|
-
onQueued:
|
|
2312
|
+
onQueued: position => {
|
|
2256
2313
|
const maxRunningTurns = this.turnGovernor.maxRunningTurns ?? 0;
|
|
2257
2314
|
emit({ type: "turn.queued", data: { position, maxRunningTurns } });
|
|
2258
2315
|
this.logger(
|
|
@@ -2268,13 +2325,17 @@ export class SessionEngine {
|
|
|
2268
2325
|
} else {
|
|
2269
2326
|
emit({ type: "turn.started", data: {} });
|
|
2270
2327
|
try {
|
|
2328
|
+
if (
|
|
2329
|
+
record.workspaceOverride === undefined &&
|
|
2330
|
+
this.project.agent.local?.workspaceDir !== undefined
|
|
2331
|
+
) {
|
|
2332
|
+
await this.prewarmSharedWorkspace();
|
|
2333
|
+
}
|
|
2271
2334
|
// Scaffold agent files into the session workspace even when the harness
|
|
2272
|
-
// cwd is overridden (e.g. a PR worktree).
|
|
2273
|
-
// overlays are applied via agentForSession.
|
|
2274
|
-
const agent = this.agentForSession(record);
|
|
2335
|
+
// cwd is overridden (e.g. a PR worktree).
|
|
2275
2336
|
if (!this.hasRootOverride()) {
|
|
2276
2337
|
await materializeWorkspace({
|
|
2277
|
-
agent,
|
|
2338
|
+
agent: this.project.agent,
|
|
2278
2339
|
workspaceDir,
|
|
2279
2340
|
seed: isFirstTurn,
|
|
2280
2341
|
stateRoot: this.stateRoot,
|
|
@@ -2296,7 +2357,7 @@ export class SessionEngine {
|
|
|
2296
2357
|
const pendingFiles = record.pendingWorkspaceFiles;
|
|
2297
2358
|
const pendingImages = record.pendingImages;
|
|
2298
2359
|
const runtime = resolveSessionRuntime({
|
|
2299
|
-
agentRuntime: agent.runtime,
|
|
2360
|
+
agentRuntime: this.project.agent.runtime,
|
|
2300
2361
|
cloudOverride: record.cloudOverride,
|
|
2301
2362
|
});
|
|
2302
2363
|
const hasPendingFiles =
|
|
@@ -2314,7 +2375,7 @@ export class SessionEngine {
|
|
|
2314
2375
|
(hasPendingFiles && runtime !== "cloud") ||
|
|
2315
2376
|
(pendingImages !== undefined && pendingImages.length > 0)
|
|
2316
2377
|
) {
|
|
2317
|
-
await this.updateRecord(sessionId,
|
|
2378
|
+
await this.updateRecord(sessionId, current => ({
|
|
2318
2379
|
...current,
|
|
2319
2380
|
pendingWorkspaceFiles:
|
|
2320
2381
|
hasPendingFiles &&
|
|
@@ -2328,49 +2389,39 @@ export class SessionEngine {
|
|
|
2328
2389
|
: current.pendingImages,
|
|
2329
2390
|
}));
|
|
2330
2391
|
}
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2392
|
+
const onUpdate: RunnerTurnRequest["onUpdate"] = async update => {
|
|
2393
|
+
const turn = this.turnRoots.get(sessionId);
|
|
2394
|
+
if (turn !== undefined) {
|
|
2395
|
+
update = await applyWebScratchUpdate({
|
|
2396
|
+
cwd: turn.cwd,
|
|
2397
|
+
root: turn.root,
|
|
2398
|
+
update,
|
|
2399
|
+
});
|
|
2400
|
+
}
|
|
2401
|
+
mapper.handleUpdate(update);
|
|
2402
|
+
// Yield so the HTTP NDJSON writer can flush tool start/result
|
|
2403
|
+
// events while sibling parallel tools are still executing.
|
|
2404
|
+
if (
|
|
2405
|
+
update.type === "tool-call-started" ||
|
|
2406
|
+
update.type === "tool-call-completed" ||
|
|
2407
|
+
// Nested subagent progress (newer SDKs); string check keeps
|
|
2408
|
+
// typecheck green against older published `@cursor/sdk` pins.
|
|
2409
|
+
(update as { type: string }).type === "tool-call-delta"
|
|
2410
|
+
) {
|
|
2411
|
+
// Same boundary the carrier hook runs on, so a drain is visible
|
|
2412
|
+
// by the time this fires.
|
|
2413
|
+
await this.emitDeliveredNudges(record, emit);
|
|
2414
|
+
await yieldEventLoop();
|
|
2415
|
+
}
|
|
2416
|
+
};
|
|
2340
2417
|
const request = await this.buildTurnRequest(
|
|
2341
2418
|
record,
|
|
2342
|
-
agent,
|
|
2343
2419
|
turnId,
|
|
2344
2420
|
message,
|
|
2345
2421
|
isFirstTurn,
|
|
2346
|
-
instructionsInvisibleToHarness,
|
|
2347
2422
|
emit,
|
|
2348
2423
|
eventContext,
|
|
2349
|
-
|
|
2350
|
-
const turn = this.turnRoots.get(sessionId);
|
|
2351
|
-
if (turn !== undefined) {
|
|
2352
|
-
update = await applyWebScratchUpdate({
|
|
2353
|
-
cwd: turn.cwd,
|
|
2354
|
-
root: turn.root,
|
|
2355
|
-
update,
|
|
2356
|
-
});
|
|
2357
|
-
}
|
|
2358
|
-
mapper.handleUpdate(update);
|
|
2359
|
-
// Yield so the HTTP NDJSON writer can flush tool start/result
|
|
2360
|
-
// events while sibling parallel tools are still executing.
|
|
2361
|
-
if (
|
|
2362
|
-
update.type === "tool-call-started" ||
|
|
2363
|
-
update.type === "tool-call-completed" ||
|
|
2364
|
-
// Nested subagent progress (newer SDKs); string check keeps
|
|
2365
|
-
// typecheck green against older published `@cursor/sdk` pins.
|
|
2366
|
-
(update as { type: string }).type === "tool-call-delta"
|
|
2367
|
-
) {
|
|
2368
|
-
// Same boundary the carrier hook runs on, so a drain is visible
|
|
2369
|
-
// by the time this fires.
|
|
2370
|
-
await this.emitDeliveredNudges(record, emit);
|
|
2371
|
-
await yieldEventLoop();
|
|
2372
|
-
}
|
|
2373
|
-
},
|
|
2424
|
+
onUpdate,
|
|
2374
2425
|
signal,
|
|
2375
2426
|
pendingImages
|
|
2376
2427
|
);
|
|
@@ -2380,6 +2431,20 @@ export class SessionEngine {
|
|
|
2380
2431
|
outcome = await this.runTurnExecute(record, turnId, () =>
|
|
2381
2432
|
this.runner.runTurn(request)
|
|
2382
2433
|
);
|
|
2434
|
+
// Commit before dropping the turn FS so `ctx.reject` can
|
|
2435
|
+
// re-run the model with tools still mounted.
|
|
2436
|
+
outcome = await this.settleAuthoredResult({
|
|
2437
|
+
record,
|
|
2438
|
+
turnId,
|
|
2439
|
+
emit,
|
|
2440
|
+
eventContext,
|
|
2441
|
+
turnChannelState,
|
|
2442
|
+
harnessCwd,
|
|
2443
|
+
signal,
|
|
2444
|
+
onUpdate,
|
|
2445
|
+
mapper,
|
|
2446
|
+
outcome,
|
|
2447
|
+
});
|
|
2383
2448
|
} finally {
|
|
2384
2449
|
this.activeToolContexts.delete(sessionId);
|
|
2385
2450
|
this.stubbedCallIds.delete(sessionId);
|
|
@@ -2409,7 +2474,7 @@ export class SessionEngine {
|
|
|
2409
2474
|
|
|
2410
2475
|
if (mapper.title !== undefined) {
|
|
2411
2476
|
const title = mapper.title;
|
|
2412
|
-
await this.updateRecord(sessionId,
|
|
2477
|
+
await this.updateRecord(sessionId, current => ({ ...current, title }));
|
|
2413
2478
|
eventContext.session = { ...eventContext.session, title };
|
|
2414
2479
|
}
|
|
2415
2480
|
|
|
@@ -2428,32 +2493,6 @@ export class SessionEngine {
|
|
|
2428
2493
|
outcome = { ...outcome, cost: finalCost };
|
|
2429
2494
|
}
|
|
2430
2495
|
|
|
2431
|
-
const authored = this.project.result;
|
|
2432
|
-
if (outcome.status === "finished" && authored !== undefined) {
|
|
2433
|
-
const settled = await applyAuthoredResult({
|
|
2434
|
-
definition: authored,
|
|
2435
|
-
text: finalResult,
|
|
2436
|
-
dryRun: record.dryRun === true,
|
|
2437
|
-
ctx: {
|
|
2438
|
-
session: eventContext.session,
|
|
2439
|
-
channelState: turnChannelState,
|
|
2440
|
-
host: this.hostForSession(sessionId),
|
|
2441
|
-
artifacts: this.artifactsApi({ sessionId, turnId }),
|
|
2442
|
-
stateRoot: this.stateRoot,
|
|
2443
|
-
workspaceDir: harnessCwd,
|
|
2444
|
-
},
|
|
2445
|
-
});
|
|
2446
|
-
if (!settled.ok) {
|
|
2447
|
-
outcome = {
|
|
2448
|
-
status: "error",
|
|
2449
|
-
result: finalResult,
|
|
2450
|
-
errorMessage: `turn output failed: ${settled.message}`,
|
|
2451
|
-
usage: finalUsage,
|
|
2452
|
-
cost: finalCost,
|
|
2453
|
-
};
|
|
2454
|
-
}
|
|
2455
|
-
}
|
|
2456
|
-
|
|
2457
2496
|
if (outcome.status === "finished") {
|
|
2458
2497
|
await this.appendEvent(
|
|
2459
2498
|
sessionId,
|
|
@@ -2523,6 +2562,89 @@ export class SessionEngine {
|
|
|
2523
2562
|
};
|
|
2524
2563
|
}
|
|
2525
2564
|
|
|
2565
|
+
/**
|
|
2566
|
+
* Run `defineResult` while the turn FS and tools are still up.
|
|
2567
|
+
* `ctx.reject` re-invokes `runTurn` on this turnId until commit
|
|
2568
|
+
* succeeds, throws, or the repair budget is gone.
|
|
2569
|
+
*/
|
|
2570
|
+
private async settleAuthoredResult(args: {
|
|
2571
|
+
record: SessionRecord;
|
|
2572
|
+
turnId: string;
|
|
2573
|
+
emit: (payload: SessionEventPayload) => void;
|
|
2574
|
+
eventContext: EventDispatchContext;
|
|
2575
|
+
turnChannelState: JsonValue;
|
|
2576
|
+
harnessCwd: string;
|
|
2577
|
+
signal: AbortSignal;
|
|
2578
|
+
onUpdate: RunnerTurnRequest["onUpdate"];
|
|
2579
|
+
mapper: TurnEventMapper;
|
|
2580
|
+
outcome: TurnOutcome;
|
|
2581
|
+
}): Promise<TurnOutcome> {
|
|
2582
|
+
const authored = this.project.result;
|
|
2583
|
+
if (args.outcome.status !== "finished" || authored === undefined) {
|
|
2584
|
+
return args.outcome;
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2587
|
+
let outcome = args.outcome;
|
|
2588
|
+
let usage = outcome.usage;
|
|
2589
|
+
let repairs = 0;
|
|
2590
|
+
|
|
2591
|
+
while (true) {
|
|
2592
|
+
const settled = await applyAuthoredResult({
|
|
2593
|
+
definition: authored,
|
|
2594
|
+
text: outcome.result ?? args.mapper.pendingText,
|
|
2595
|
+
dryRun: args.record.dryRun === true,
|
|
2596
|
+
ctx: {
|
|
2597
|
+
session: args.eventContext.session,
|
|
2598
|
+
channelState: args.turnChannelState,
|
|
2599
|
+
host: this.hostForSession(args.record.sessionId),
|
|
2600
|
+
artifacts: this.artifactsApi({
|
|
2601
|
+
sessionId: args.record.sessionId,
|
|
2602
|
+
turnId: args.turnId,
|
|
2603
|
+
}),
|
|
2604
|
+
stateRoot: this.stateRoot,
|
|
2605
|
+
workspaceDir: args.harnessCwd,
|
|
2606
|
+
},
|
|
2607
|
+
});
|
|
2608
|
+
if (settled.ok) {
|
|
2609
|
+
return { ...outcome, result: settled.text, usage };
|
|
2610
|
+
}
|
|
2611
|
+
if (settled.kind === "error" || repairs >= RESULT_REPAIR_BUDGET) {
|
|
2612
|
+
return {
|
|
2613
|
+
status: "error",
|
|
2614
|
+
result: outcome.result,
|
|
2615
|
+
errorMessage: `turn output failed: ${settled.message}`,
|
|
2616
|
+
usage,
|
|
2617
|
+
};
|
|
2618
|
+
}
|
|
2619
|
+
repairs += 1;
|
|
2620
|
+
// Close the rejected stream without posting it (empty `stop`)
|
|
2621
|
+
// so Slack does not append a repair onto that block, and so an
|
|
2622
|
+
// empty repair cannot recommit `lastAssistantText`.
|
|
2623
|
+
args.mapper.abandonPendingText();
|
|
2624
|
+
this.logger(
|
|
2625
|
+
`[session] ${args.record.sessionId} ${args.turnId} result rejected; repairing (${repairs}/${RESULT_REPAIR_BUDGET})`
|
|
2626
|
+
);
|
|
2627
|
+
const repairRequest = await this.buildTurnRequest(
|
|
2628
|
+
args.record,
|
|
2629
|
+
args.turnId,
|
|
2630
|
+
resultRepairPrompt(settled.message),
|
|
2631
|
+
false,
|
|
2632
|
+
args.emit,
|
|
2633
|
+
args.eventContext,
|
|
2634
|
+
args.onUpdate,
|
|
2635
|
+
args.signal
|
|
2636
|
+
);
|
|
2637
|
+
const repaired = await this.runTurnExecute(args.record, args.turnId, () =>
|
|
2638
|
+
this.runner.runTurn(repairRequest)
|
|
2639
|
+
);
|
|
2640
|
+
usage = addTurnUsage(usage, repaired.usage);
|
|
2641
|
+
if (repaired.status !== "finished") {
|
|
2642
|
+
return { ...repaired, usage };
|
|
2643
|
+
}
|
|
2644
|
+
outcome = { ...repaired, usage };
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2526
2648
|
/**
|
|
2527
2649
|
* Sync authored skills onto the Agent Store at `skills/<name>/…` (hosted)
|
|
2528
2650
|
* or `agent-serve/<agent>/skills/<name>/…` (personal-key local+cloud)
|
|
@@ -2615,7 +2737,7 @@ export class SessionEngine {
|
|
|
2615
2737
|
sessionId: string,
|
|
2616
2738
|
pending: NonNullable<SessionRecord["pendingWorkspaceFiles"]>
|
|
2617
2739
|
): Promise<void> {
|
|
2618
|
-
await this.updateRecord(sessionId,
|
|
2740
|
+
await this.updateRecord(sessionId, current => ({
|
|
2619
2741
|
...current,
|
|
2620
2742
|
pendingWorkspaceFiles:
|
|
2621
2743
|
current.pendingWorkspaceFiles === pending
|
|
@@ -2648,7 +2770,7 @@ export class SessionEngine {
|
|
|
2648
2770
|
}
|
|
2649
2771
|
let sync = run().then(
|
|
2650
2772
|
() => true,
|
|
2651
|
-
|
|
2773
|
+
error => {
|
|
2652
2774
|
this.logger(
|
|
2653
2775
|
`[${surface}] ${store.label} sync failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2654
2776
|
);
|
|
@@ -2667,11 +2789,17 @@ export class SessionEngine {
|
|
|
2667
2789
|
/**
|
|
2668
2790
|
* Hosted deployments own the deployment store. Local `serve`/`run` with
|
|
2669
2791
|
* a personal API key writes into the USER store under `agent-serve/`.
|
|
2792
|
+
* A persistent deployment's version container has no cloud store at all:
|
|
2793
|
+
* its state directory is the durable copy, and its service-account key
|
|
2794
|
+
* must not be mistaken for a personal one.
|
|
2670
2795
|
*/
|
|
2671
2796
|
private cloudStore(): CloudStoreTarget | undefined {
|
|
2672
2797
|
const v2Hosting = resolveAgentV2Hosting({
|
|
2673
2798
|
architecture: this.project.agent.architecture,
|
|
2674
2799
|
});
|
|
2800
|
+
if (v2Hosting.kind === "cursor-managed-persistent") {
|
|
2801
|
+
return undefined;
|
|
2802
|
+
}
|
|
2675
2803
|
const deployment = {
|
|
2676
2804
|
mountPath: DEPLOYMENT_STORE_MOUNT_PATH,
|
|
2677
2805
|
skillsPrefix: agentStoreKeys.skillsPrefix(),
|
|
@@ -2713,17 +2841,16 @@ export class SessionEngine {
|
|
|
2713
2841
|
|
|
2714
2842
|
private async buildTurnRequest(
|
|
2715
2843
|
record: SessionRecord,
|
|
2716
|
-
agent: ResolvedAgent,
|
|
2717
2844
|
turnId: string,
|
|
2718
2845
|
prompt: string,
|
|
2719
2846
|
isFirstTurn: boolean,
|
|
2720
|
-
instructionsInvisibleToHarness: boolean,
|
|
2721
2847
|
emit: (payload: SessionEventPayload) => void,
|
|
2722
2848
|
eventContext: EventDispatchContext,
|
|
2723
2849
|
onUpdate: RunnerTurnRequest["onUpdate"],
|
|
2724
2850
|
signal: AbortSignal,
|
|
2725
2851
|
images?: Array<{ data: string; mimeType: string }>
|
|
2726
2852
|
): Promise<RunnerTurnRequest> {
|
|
2853
|
+
const agent = this.project.agent;
|
|
2727
2854
|
// Per-session cloud attach (channel/tool handoff) forces cloud runtime
|
|
2728
2855
|
// even when the agent defaults to local for chat server tools.
|
|
2729
2856
|
const runtime = resolveSessionRuntime({
|
|
@@ -2758,7 +2885,7 @@ export class SessionEngine {
|
|
|
2758
2885
|
// agents already fail discovery; this guards hybrid agents' per-send
|
|
2759
2886
|
// cloud sessions.
|
|
2760
2887
|
const perSessionConnection = agent.connections.find(
|
|
2761
|
-
|
|
2888
|
+
connection =>
|
|
2762
2889
|
connection.advertiseTools === true || connection.auth !== undefined
|
|
2763
2890
|
);
|
|
2764
2891
|
if (runtime !== "local" && perSessionConnection !== undefined) {
|
|
@@ -2812,7 +2939,7 @@ export class SessionEngine {
|
|
|
2812
2939
|
: this.withTurnScratchTools(
|
|
2813
2940
|
authoredRoot
|
|
2814
2941
|
? fileTools
|
|
2815
|
-
: fileTools.filter(
|
|
2942
|
+
: fileTools.filter(tool => tool.name !== "SemanticSearch"),
|
|
2816
2943
|
record.sessionId
|
|
2817
2944
|
);
|
|
2818
2945
|
let turnPrompt = prompt;
|
|
@@ -2888,6 +3015,9 @@ export class SessionEngine {
|
|
|
2888
3015
|
}
|
|
2889
3016
|
}
|
|
2890
3017
|
} else if (pending !== undefined && Object.keys(pending).length > 0) {
|
|
3018
|
+
this.logger(
|
|
3019
|
+
`[workspace] no cloud store on this hosting; dropping workspaceFiles for session ${record.sessionId}: ${Object.keys(pending).join(", ")}`
|
|
3020
|
+
);
|
|
2891
3021
|
await this.clearPendingWorkspaceFiles(record.sessionId, pending);
|
|
2892
3022
|
}
|
|
2893
3023
|
if (isFirstTurn && hosted) {
|
|
@@ -2895,45 +3025,33 @@ export class SessionEngine {
|
|
|
2895
3025
|
}
|
|
2896
3026
|
if (preamble !== "" || sections.length > 0) {
|
|
2897
3027
|
turnPrompt = [preamble, ...sections, turnPrompt]
|
|
2898
|
-
.filter(
|
|
3028
|
+
.filter(part => part !== "")
|
|
2899
3029
|
.join("\n\n");
|
|
2900
3030
|
}
|
|
2901
3031
|
} else if (isFirstTurn && runtime === "local" && authoredRoot) {
|
|
2902
|
-
//
|
|
2903
|
-
|
|
2904
|
-
const preamble = buildAgentsMdContent(
|
|
2905
|
-
{ ...agent, tools: [...agent.tools, ...synthesized] },
|
|
2906
|
-
{ includeScripts: true }
|
|
2907
|
-
);
|
|
2908
|
-
const workspaceInfo = `<user_info>\nWorkspace Path: /\n</user_info>`;
|
|
2909
|
-
turnPrompt =
|
|
2910
|
-
preamble === ""
|
|
2911
|
-
? `${workspaceInfo}\n\n${turnPrompt}`
|
|
2912
|
-
: `${workspaceInfo}\n\n${preamble}\n\n${turnPrompt}`;
|
|
2913
|
-
} else if (
|
|
2914
|
-
isFirstTurn &&
|
|
2915
|
-
runtime === "local" &&
|
|
2916
|
-
instructionsInvisibleToHarness
|
|
2917
|
-
) {
|
|
2918
|
-
// Local workspace whose AGENTS.md the harness will not load. With a
|
|
2919
|
-
// borrowed harness cwd, agent tool scripts live only in the durable
|
|
2920
|
-
// scaffold dir — embed bodies like cloud. Otherwise the catalog can
|
|
2921
|
-
// reference on-disk paths under the harness cwd. Grokbot turns are
|
|
2922
|
-
// excluded: their instructions ride the request's `instructions`
|
|
2923
|
-
// field into the Sand system prompt instead.
|
|
2924
|
-
const includeScripts = this.hasBorrowedWorkspace(record);
|
|
2925
|
-
const preamble = buildAgentsMdContent(agent, { includeScripts });
|
|
2926
|
-
turnPrompt = `${preamble}\n\n${turnPrompt}`;
|
|
3032
|
+
// The harness reports no path for a root it never mounted.
|
|
3033
|
+
turnPrompt = `<user_info>\nWorkspace Path: /\n</user_info>\n\n${turnPrompt}`;
|
|
2927
3034
|
}
|
|
3035
|
+
// A virtual root has no scaffold dir either, so its catalog carries the
|
|
3036
|
+
// synthesized file tools and embedded script bodies.
|
|
3037
|
+
const localInstructions =
|
|
3038
|
+
runtime === "local"
|
|
3039
|
+
? authoredRoot
|
|
3040
|
+
? buildAgentsMdContent(
|
|
3041
|
+
{ ...agent, tools: [...agent.tools, ...synthesized] },
|
|
3042
|
+
{ includeScripts: true }
|
|
3043
|
+
)
|
|
3044
|
+
: buildAgentsMdContent(agent, {
|
|
3045
|
+
includeScripts: this.hasBorrowedWorkspace(record),
|
|
3046
|
+
})
|
|
3047
|
+
: undefined;
|
|
2928
3048
|
return {
|
|
2929
3049
|
sessionId: record.sessionId,
|
|
2930
3050
|
...(record.sdkAgentId === undefined
|
|
2931
3051
|
? {}
|
|
2932
3052
|
: { sdkAgentId: record.sdkAgentId }),
|
|
2933
3053
|
workspaceDir: this.harnessCwd(record),
|
|
2934
|
-
sandbox: authoredRoot
|
|
2935
|
-
? false
|
|
2936
|
-
: this.project.agent.local?.sandbox === true,
|
|
3054
|
+
sandbox: authoredRoot ? false : agent.local?.sandbox === true,
|
|
2937
3055
|
...(runtime === "local" && harnessTools !== undefined
|
|
2938
3056
|
? {
|
|
2939
3057
|
...(harnessTools.tools === undefined
|
|
@@ -2952,34 +3070,35 @@ export class SessionEngine {
|
|
|
2952
3070
|
runtime,
|
|
2953
3071
|
agentName: agent.name,
|
|
2954
3072
|
...(mergedCloud === undefined ? {} : { cloud: mergedCloud }),
|
|
2955
|
-
//
|
|
2956
|
-
// turns carry
|
|
2957
|
-
//
|
|
2958
|
-
// the
|
|
2959
|
-
//
|
|
3073
|
+
// Local turns send the composed instructions as the harness system
|
|
3074
|
+
// prompt; grokbot turns carry them into the hosted session, which
|
|
3075
|
+
// surfaces them in the Sand system prompt. Cloud turns inline them into
|
|
3076
|
+
// the first prompt above instead. Script bodies are embedded whenever
|
|
3077
|
+
// the harness cannot reach the scaffold dir: always for grokbot (the
|
|
3078
|
+
// box never sees the session workspace) and for a borrowed local cwd
|
|
3079
|
+
// (PR worktree, shared checkout); otherwise the catalog references the
|
|
3080
|
+
// on-disk paths under the harness cwd.
|
|
2960
3081
|
instructions:
|
|
2961
3082
|
runtime === "grokbot"
|
|
2962
3083
|
? buildAgentsMdContent(agent, { includeScripts: true })
|
|
2963
|
-
:
|
|
3084
|
+
: localInstructions,
|
|
2964
3085
|
...(runtime === "cloud" && !isCursorHostedFilesAvailable()
|
|
2965
3086
|
? { agentServeAgent: this.project.name }
|
|
2966
3087
|
: {}),
|
|
2967
3088
|
customTools:
|
|
2968
3089
|
runtime === "local"
|
|
2969
|
-
? await this.buildCustomTools(
|
|
2970
|
-
record,
|
|
2971
|
-
agent,
|
|
2972
|
-
turnId,
|
|
2973
|
-
emit,
|
|
2974
|
-
synthesized
|
|
2975
|
-
)
|
|
3090
|
+
? await this.buildCustomTools(record, turnId, emit, synthesized)
|
|
2976
3091
|
: {},
|
|
2977
3092
|
mcpServers: this.buildMcpServers(
|
|
2978
3093
|
runtime,
|
|
2979
3094
|
record.sessionId,
|
|
2980
3095
|
await this.evaluateConnectionAuth(record)
|
|
2981
3096
|
),
|
|
2982
|
-
...(runtime === "local" &&
|
|
3097
|
+
...(runtime === "local" &&
|
|
3098
|
+
(this.hasAttachedAuthedConnections() ||
|
|
3099
|
+
this.project.agent.connections.some(connection =>
|
|
3100
|
+
isCursorAccountTransport(connection.transport)
|
|
3101
|
+
))
|
|
2983
3102
|
? { perSendMcpServers: true }
|
|
2984
3103
|
: {}),
|
|
2985
3104
|
subagents: buildRunnerSubagents(agent),
|
|
@@ -2988,14 +3107,14 @@ export class SessionEngine {
|
|
|
2988
3107
|
// Local follow-ups expire any lingering active run so a preempted turn
|
|
2989
3108
|
// (or one orphaned by a crashed process) never blocks this send.
|
|
2990
3109
|
forceExpireActiveRun: runtime === "local" && !isFirstTurn,
|
|
2991
|
-
onRequestId:
|
|
3110
|
+
onRequestId: requestId => {
|
|
2992
3111
|
emit({ type: "turn.bound", data: { requestId } });
|
|
2993
3112
|
},
|
|
2994
|
-
onSdkAgentId: async
|
|
3113
|
+
onSdkAgentId: async sdkAgentId => {
|
|
2995
3114
|
if (record.sdkAgentId === sdkAgentId) {
|
|
2996
3115
|
return;
|
|
2997
3116
|
}
|
|
2998
|
-
await this.updateRecord(record.sessionId,
|
|
3117
|
+
await this.updateRecord(record.sessionId, current => ({
|
|
2999
3118
|
...current,
|
|
3000
3119
|
sdkAgentId,
|
|
3001
3120
|
}));
|
|
@@ -3097,12 +3216,12 @@ export class SessionEngine {
|
|
|
3097
3216
|
// attached MCP server (each tool appears exactly once).
|
|
3098
3217
|
const advertisedNames = new Set(
|
|
3099
3218
|
this.project.agent.connections
|
|
3100
|
-
.filter(
|
|
3101
|
-
.map(
|
|
3219
|
+
.filter(connection => connection.advertiseTools === true)
|
|
3220
|
+
.map(connection => connection.name)
|
|
3102
3221
|
);
|
|
3103
3222
|
const hostConnectionNames = new Set(
|
|
3104
3223
|
(this.project.agent.hostConnections ?? []).map(
|
|
3105
|
-
|
|
3224
|
+
connection => connection.name
|
|
3106
3225
|
)
|
|
3107
3226
|
);
|
|
3108
3227
|
const bridgedNames = new Set(
|
|
@@ -3116,7 +3235,7 @@ export class SessionEngine {
|
|
|
3116
3235
|
assertCloudCanHonorAccountServersFilters({
|
|
3117
3236
|
runtime,
|
|
3118
3237
|
resolvedConnections: this.resolvedConnections.filter(
|
|
3119
|
-
|
|
3238
|
+
resolved =>
|
|
3120
3239
|
!advertisedNames.has(resolved.name) &&
|
|
3121
3240
|
!hostConnectionNames.has(resolved.name)
|
|
3122
3241
|
),
|
|
@@ -3189,6 +3308,20 @@ export class SessionEngine {
|
|
|
3189
3308
|
}
|
|
3190
3309
|
continue;
|
|
3191
3310
|
}
|
|
3311
|
+
const authored = this.authoredConnection(resolved.name);
|
|
3312
|
+
if (
|
|
3313
|
+
sessionId !== undefined &&
|
|
3314
|
+
authored !== undefined &&
|
|
3315
|
+
isCursorAccountTransport(authored.transport)
|
|
3316
|
+
) {
|
|
3317
|
+
const bound = new URL(url);
|
|
3318
|
+
bound.searchParams.set("agentkitSessionId", sessionId);
|
|
3319
|
+
servers[resolved.name] = {
|
|
3320
|
+
url: bound.toString(),
|
|
3321
|
+
headers: resolved.headers,
|
|
3322
|
+
};
|
|
3323
|
+
continue;
|
|
3324
|
+
}
|
|
3192
3325
|
servers[resolved.name] = {
|
|
3193
3326
|
url,
|
|
3194
3327
|
headers: resolved.headers,
|
|
@@ -3198,7 +3331,7 @@ export class SessionEngine {
|
|
|
3198
3331
|
runtime === "cloud" &&
|
|
3199
3332
|
sessionId !== undefined &&
|
|
3200
3333
|
this.cloudServerToolsConnection !== undefined &&
|
|
3201
|
-
this.project.agent.tools.some(
|
|
3334
|
+
this.project.agent.tools.some(tool => tool.execution === "server")
|
|
3202
3335
|
) {
|
|
3203
3336
|
if (servers[SERVER_TOOLS_MCP_SERVER_NAME] !== undefined) {
|
|
3204
3337
|
throw new Error(
|
|
@@ -3226,7 +3359,7 @@ export class SessionEngine {
|
|
|
3226
3359
|
*/
|
|
3227
3360
|
private hasAttachedAuthedConnections(): boolean {
|
|
3228
3361
|
return this.project.agent.connections.some(
|
|
3229
|
-
|
|
3362
|
+
connection =>
|
|
3230
3363
|
connection.auth !== undefined && connection.advertiseTools !== true
|
|
3231
3364
|
);
|
|
3232
3365
|
}
|
|
@@ -3242,7 +3375,7 @@ export class SessionEngine {
|
|
|
3242
3375
|
record: SessionRecord
|
|
3243
3376
|
): Promise<ReadonlyMap<string, Record<string, string>> | undefined> {
|
|
3244
3377
|
const authed = this.project.agent.connections.filter(
|
|
3245
|
-
|
|
3378
|
+
connection =>
|
|
3246
3379
|
connection.auth !== undefined && connection.advertiseTools !== true
|
|
3247
3380
|
);
|
|
3248
3381
|
if (authed.length === 0) {
|
|
@@ -3269,11 +3402,11 @@ export class SessionEngine {
|
|
|
3269
3402
|
|
|
3270
3403
|
private async buildCustomTools(
|
|
3271
3404
|
record: SessionRecord,
|
|
3272
|
-
agent: ResolvedAgent,
|
|
3273
3405
|
turnId: string,
|
|
3274
3406
|
emit: (payload: SessionEventPayload) => void,
|
|
3275
3407
|
extraTools: DiscoveredTool[] = []
|
|
3276
3408
|
): Promise<Record<string, SDKCustomTool>> {
|
|
3409
|
+
const agent = this.project.agent;
|
|
3277
3410
|
const tools: Record<string, SDKCustomTool> = {};
|
|
3278
3411
|
const register = (tool: ResolvedAgent["tools"][number]): void => {
|
|
3279
3412
|
tools[tool.name] = {
|
|
@@ -3358,7 +3491,7 @@ export class SessionEngine {
|
|
|
3358
3491
|
);
|
|
3359
3492
|
}
|
|
3360
3493
|
const tool = this.project.agent.tools.find(
|
|
3361
|
-
|
|
3494
|
+
candidate =>
|
|
3362
3495
|
candidate.name === toolName && candidate.execution === "server"
|
|
3363
3496
|
);
|
|
3364
3497
|
if (tool === undefined) {
|
|
@@ -3605,11 +3738,11 @@ export class SessionEngine {
|
|
|
3605
3738
|
args.sessionId,
|
|
3606
3739
|
pendingRecord
|
|
3607
3740
|
);
|
|
3608
|
-
await this.updateRecord(args.sessionId,
|
|
3741
|
+
await this.updateRecord(args.sessionId, current => ({
|
|
3609
3742
|
...current,
|
|
3610
3743
|
pendingApprovals: [
|
|
3611
3744
|
...(current.pendingApprovals ?? []).filter(
|
|
3612
|
-
|
|
3745
|
+
item => item.callId !== args.callId
|
|
3613
3746
|
),
|
|
3614
3747
|
pendingRecord,
|
|
3615
3748
|
],
|
|
@@ -3626,10 +3759,10 @@ export class SessionEngine {
|
|
|
3626
3759
|
`[session] tool ${args.toolName} awaiting approval (${args.callId})`
|
|
3627
3760
|
);
|
|
3628
3761
|
const { decision, by } = await resolutionPromise;
|
|
3629
|
-
await this.updateRecord(args.sessionId,
|
|
3762
|
+
await this.updateRecord(args.sessionId, current => ({
|
|
3630
3763
|
...current,
|
|
3631
3764
|
pendingApprovals: (current.pendingApprovals ?? []).filter(
|
|
3632
|
-
|
|
3765
|
+
item => item.callId !== args.callId
|
|
3633
3766
|
),
|
|
3634
3767
|
}));
|
|
3635
3768
|
args.emit({
|
|
@@ -3656,7 +3789,7 @@ export class SessionEngine {
|
|
|
3656
3789
|
) {
|
|
3657
3790
|
return;
|
|
3658
3791
|
}
|
|
3659
|
-
await this.updateRecord(sessionId,
|
|
3792
|
+
await this.updateRecord(sessionId, record => ({
|
|
3660
3793
|
...record,
|
|
3661
3794
|
pendingApprovals: [],
|
|
3662
3795
|
}));
|
|
@@ -3699,8 +3832,8 @@ export class SessionEngine {
|
|
|
3699
3832
|
throw new SessionAuthError(sessionId);
|
|
3700
3833
|
}
|
|
3701
3834
|
const pending =
|
|
3702
|
-
(record.pendingApprovals ?? []).find(
|
|
3703
|
-
this.approvals.list(sessionId).find(
|
|
3835
|
+
(record.pendingApprovals ?? []).find(item => item.callId === callId) ??
|
|
3836
|
+
this.approvals.list(sessionId).find(item => item.callId === callId);
|
|
3704
3837
|
if (pending === undefined) {
|
|
3705
3838
|
throw new ApprovalNotFoundError(sessionId, callId);
|
|
3706
3839
|
}
|
|
@@ -3716,10 +3849,10 @@ export class SessionEngine {
|
|
|
3716
3849
|
sessionId: string,
|
|
3717
3850
|
callId: string
|
|
3718
3851
|
): Promise<void> {
|
|
3719
|
-
await this.updateRecord(sessionId,
|
|
3852
|
+
await this.updateRecord(sessionId, current => ({
|
|
3720
3853
|
...current,
|
|
3721
3854
|
pendingApprovals: (current.pendingApprovals ?? []).filter(
|
|
3722
|
-
|
|
3855
|
+
item => item.callId !== callId
|
|
3723
3856
|
),
|
|
3724
3857
|
}));
|
|
3725
3858
|
}
|
|
@@ -3727,7 +3860,7 @@ export class SessionEngine {
|
|
|
3727
3860
|
private wrapMcp(inner: McpHost): HostMcpRegistry {
|
|
3728
3861
|
return {
|
|
3729
3862
|
names: () => inner.names(),
|
|
3730
|
-
listTools:
|
|
3863
|
+
listTools: name => this.withMcpAuth(name, () => inner.listTools(name)),
|
|
3731
3864
|
callTool: (name, tool, args) =>
|
|
3732
3865
|
this.withMcpAuth(name, () => inner.callTool(name, tool, args)),
|
|
3733
3866
|
};
|
|
@@ -3735,11 +3868,11 @@ export class SessionEngine {
|
|
|
3735
3868
|
|
|
3736
3869
|
private advertiseMcp(): AdvertiseHostMcp {
|
|
3737
3870
|
return {
|
|
3738
|
-
listTools:
|
|
3871
|
+
listTools: name =>
|
|
3739
3872
|
this.withMcpListAuth(name, () => this.mcpHost.listTools(name)),
|
|
3740
3873
|
callTool: (name, tool, args) =>
|
|
3741
3874
|
this.withMcpAuth(name, () => this.mcpHost.callTool(name, tool, args)),
|
|
3742
|
-
oneOff:
|
|
3875
|
+
oneOff: connection => {
|
|
3743
3876
|
const inner = this.mcpHost.oneOff(connection);
|
|
3744
3877
|
return {
|
|
3745
3878
|
listTools: () =>
|
|
@@ -3892,11 +4025,11 @@ export class SessionEngine {
|
|
|
3892
4025
|
requestedAt,
|
|
3893
4026
|
};
|
|
3894
4027
|
const resolutionPromise = this.auths.wait(args.sessionId, pendingRecord);
|
|
3895
|
-
await this.updateRecord(args.sessionId,
|
|
4028
|
+
await this.updateRecord(args.sessionId, current => ({
|
|
3896
4029
|
...current,
|
|
3897
4030
|
pendingAuths: [
|
|
3898
4031
|
...(current.pendingAuths ?? []).filter(
|
|
3899
|
-
|
|
4032
|
+
item => item.callId !== args.callId
|
|
3900
4033
|
),
|
|
3901
4034
|
pendingRecord,
|
|
3902
4035
|
],
|
|
@@ -3914,10 +4047,10 @@ export class SessionEngine {
|
|
|
3914
4047
|
`[session] tool ${args.toolName} awaiting MCP auth ${args.connection} (${args.callId})`
|
|
3915
4048
|
);
|
|
3916
4049
|
const { decision, by } = await resolutionPromise;
|
|
3917
|
-
await this.updateRecord(args.sessionId,
|
|
4050
|
+
await this.updateRecord(args.sessionId, current => ({
|
|
3918
4051
|
...current,
|
|
3919
4052
|
pendingAuths: (current.pendingAuths ?? []).filter(
|
|
3920
|
-
|
|
4053
|
+
item => item.callId !== args.callId
|
|
3921
4054
|
),
|
|
3922
4055
|
}));
|
|
3923
4056
|
args.emit({
|
|
@@ -3946,7 +4079,7 @@ export class SessionEngine {
|
|
|
3946
4079
|
) {
|
|
3947
4080
|
return;
|
|
3948
4081
|
}
|
|
3949
|
-
await this.updateRecord(sessionId,
|
|
4082
|
+
await this.updateRecord(sessionId, record => ({
|
|
3950
4083
|
...record,
|
|
3951
4084
|
pendingAuths: [],
|
|
3952
4085
|
}));
|
|
@@ -3980,8 +4113,8 @@ export class SessionEngine {
|
|
|
3980
4113
|
throw new SessionAuthError(sessionId);
|
|
3981
4114
|
}
|
|
3982
4115
|
const pending =
|
|
3983
|
-
(record.pendingAuths ?? []).find(
|
|
3984
|
-
this.auths.list(sessionId).find(
|
|
4116
|
+
(record.pendingAuths ?? []).find(item => item.callId === callId) ??
|
|
4117
|
+
this.auths.list(sessionId).find(item => item.callId === callId);
|
|
3985
4118
|
if (pending === undefined) {
|
|
3986
4119
|
throw new AuthNotFoundError(sessionId, callId);
|
|
3987
4120
|
}
|
|
@@ -4000,10 +4133,10 @@ export class SessionEngine {
|
|
|
4000
4133
|
sessionId: string,
|
|
4001
4134
|
callId: string
|
|
4002
4135
|
): Promise<void> {
|
|
4003
|
-
await this.updateRecord(sessionId,
|
|
4136
|
+
await this.updateRecord(sessionId, current => ({
|
|
4004
4137
|
...current,
|
|
4005
4138
|
pendingAuths: (current.pendingAuths ?? []).filter(
|
|
4006
|
-
|
|
4139
|
+
item => item.callId !== callId
|
|
4007
4140
|
),
|
|
4008
4141
|
}));
|
|
4009
4142
|
}
|
|
@@ -4211,17 +4344,17 @@ export class SessionEngine {
|
|
|
4211
4344
|
}
|
|
4212
4345
|
> {
|
|
4213
4346
|
const authored = this.project.agent.tools.find(
|
|
4214
|
-
|
|
4347
|
+
tool => tool.name === toolName
|
|
4215
4348
|
);
|
|
4216
4349
|
if (authored !== undefined) {
|
|
4217
4350
|
return { tool: authored };
|
|
4218
4351
|
}
|
|
4219
4352
|
const catalog = await this.listCatalogTools(options);
|
|
4220
|
-
const tool = catalog.tools.find(
|
|
4353
|
+
const tool = catalog.tools.find(entry => entry.name === toolName);
|
|
4221
4354
|
if (tool === undefined) {
|
|
4222
4355
|
return {
|
|
4223
4356
|
tool: undefined,
|
|
4224
|
-
availableTools: catalog.tools.map(
|
|
4357
|
+
availableTools: catalog.tools.map(entry => entry.name),
|
|
4225
4358
|
connectionErrors: catalog.connectionErrors,
|
|
4226
4359
|
};
|
|
4227
4360
|
}
|
|
@@ -4263,10 +4396,10 @@ export class SessionEngine {
|
|
|
4263
4396
|
if (native !== undefined) {
|
|
4264
4397
|
return native;
|
|
4265
4398
|
}
|
|
4266
|
-
let tool = this.project.agent.tools.find(
|
|
4399
|
+
let tool = this.project.agent.tools.find(t => t.name === toolName);
|
|
4267
4400
|
if (
|
|
4268
4401
|
tool === undefined &&
|
|
4269
|
-
this.project.agent.connections.some(
|
|
4402
|
+
this.project.agent.connections.some(c => c.advertiseTools === true)
|
|
4270
4403
|
) {
|
|
4271
4404
|
// Advertised passthroughs are ordinary server tools in the session's
|
|
4272
4405
|
// namespace; resolve the live listing so direct calls address them by
|
|
@@ -4277,14 +4410,14 @@ export class SessionEngine {
|
|
|
4277
4410
|
session,
|
|
4278
4411
|
hostMcp: this.advertiseMcp(),
|
|
4279
4412
|
});
|
|
4280
|
-
tool = advertised.find(
|
|
4413
|
+
tool = advertised.find(t => t.name === toolName);
|
|
4281
4414
|
}
|
|
4282
4415
|
if (tool === undefined) {
|
|
4283
4416
|
throw new UnknownToolError(
|
|
4284
4417
|
toolName,
|
|
4285
4418
|
this.project.agent.tools
|
|
4286
|
-
.filter(
|
|
4287
|
-
.map(
|
|
4419
|
+
.filter(t => t.execution === "server")
|
|
4420
|
+
.map(t => t.name)
|
|
4288
4421
|
);
|
|
4289
4422
|
}
|
|
4290
4423
|
const execute = tool.definition.execute;
|
|
@@ -4655,7 +4788,7 @@ export class SessionEngine {
|
|
|
4655
4788
|
): Promise<HostMcpToolInfo | undefined> {
|
|
4656
4789
|
try {
|
|
4657
4790
|
const listed = await this.host.mcp.listTools(connectionName);
|
|
4658
|
-
return listed.find(
|
|
4791
|
+
return listed.find(tool => tool.name === toolName);
|
|
4659
4792
|
} catch {
|
|
4660
4793
|
return undefined;
|
|
4661
4794
|
}
|
|
@@ -4687,7 +4820,7 @@ export class SessionEngine {
|
|
|
4687
4820
|
const chain = this.dispatchChains.get(sessionId) ?? Promise.resolve();
|
|
4688
4821
|
const next = chain
|
|
4689
4822
|
.then(() => this.dispatchEvent(sessionId, event, context))
|
|
4690
|
-
.catch(
|
|
4823
|
+
.catch(error => {
|
|
4691
4824
|
this.logger(
|
|
4692
4825
|
`[agent-sdk] event dispatch failed for ${sessionId}: ${describeError(error)}`
|
|
4693
4826
|
);
|
|
@@ -4754,11 +4887,11 @@ export class SessionEngine {
|
|
|
4754
4887
|
}
|
|
4755
4888
|
if (context === undefined || channelStateBefore === undefined) {
|
|
4756
4889
|
// Handlers mutate live channel state in place; save the current record.
|
|
4757
|
-
await this.updateRecord(sessionId,
|
|
4890
|
+
await this.updateRecord(sessionId, current => ({ ...current }));
|
|
4758
4891
|
} else {
|
|
4759
4892
|
const updatedState = channelCtx.state as JsonValue;
|
|
4760
4893
|
context.channelState = updatedState;
|
|
4761
|
-
await this.updateRecord(sessionId,
|
|
4894
|
+
await this.updateRecord(sessionId, current => ({
|
|
4762
4895
|
...current,
|
|
4763
4896
|
channelState: mergeChannelStateMutation({
|
|
4764
4897
|
current: current.channelState,
|
|
@@ -4796,14 +4929,6 @@ export class SessionEngine {
|
|
|
4796
4929
|
}
|
|
4797
4930
|
}
|
|
4798
4931
|
|
|
4799
|
-
if (this.abCollector.enabled) {
|
|
4800
|
-
await this.abCollector.onEvent(
|
|
4801
|
-
event,
|
|
4802
|
-
sessionCtx.session,
|
|
4803
|
-
this.project.name
|
|
4804
|
-
);
|
|
4805
|
-
}
|
|
4806
|
-
|
|
4807
4932
|
this.otel?.onEvent(event, sessionCtx.session);
|
|
4808
4933
|
}
|
|
4809
4934
|
|
|
@@ -4850,8 +4975,10 @@ export class SessionEngine {
|
|
|
4850
4975
|
async waitForCompletion(sessionId: string): Promise<TurnOutcome> {
|
|
4851
4976
|
// Drain admission first so pendingTurns → activeTurns is visible before we
|
|
4852
4977
|
// decide the session is idle (reminders use this for queueBehindTurn).
|
|
4853
|
-
//
|
|
4854
|
-
// follow-up
|
|
4978
|
+
// Wait for coalesce drain and any successor turn so hosted execute does
|
|
4979
|
+
// not park mid-follow-up, but report the root turn's outcome: a drained
|
|
4980
|
+
// successor failure must not un-ACK an already-finished owner.
|
|
4981
|
+
let root: TurnOutcome | undefined;
|
|
4855
4982
|
for (;;) {
|
|
4856
4983
|
const chain = this.admissionChains.get(sessionId);
|
|
4857
4984
|
if (chain !== undefined) {
|
|
@@ -4859,14 +4986,15 @@ export class SessionEngine {
|
|
|
4859
4986
|
}
|
|
4860
4987
|
const active = this.activeTurns.get(sessionId);
|
|
4861
4988
|
if (active !== undefined) {
|
|
4862
|
-
await active;
|
|
4989
|
+
const outcome = await active;
|
|
4990
|
+
root ??= outcome;
|
|
4863
4991
|
continue;
|
|
4864
4992
|
}
|
|
4865
4993
|
const dispatch = this.dispatchChains.get(sessionId);
|
|
4866
4994
|
if (dispatch !== undefined) {
|
|
4867
4995
|
await dispatch.catch(() => {});
|
|
4868
4996
|
}
|
|
4869
|
-
return this.lastOutcomes.get(sessionId) ?? { status: "finished" };
|
|
4997
|
+
return root ?? this.lastOutcomes.get(sessionId) ?? { status: "finished" };
|
|
4870
4998
|
}
|
|
4871
4999
|
}
|
|
4872
5000
|
|
|
@@ -4905,7 +5033,7 @@ export class SessionEngine {
|
|
|
4905
5033
|
}
|
|
4906
5034
|
const owned = await this.ownedSessionIds(caller);
|
|
4907
5035
|
return records.filter(
|
|
4908
|
-
|
|
5036
|
+
record => record.sessionId !== undefined && owned.has(record.sessionId)
|
|
4909
5037
|
);
|
|
4910
5038
|
}
|
|
4911
5039
|
|
|
@@ -4942,8 +5070,8 @@ export class SessionEngine {
|
|
|
4942
5070
|
const sessions = await this.sessions.list();
|
|
4943
5071
|
return new Set(
|
|
4944
5072
|
sessions
|
|
4945
|
-
.filter(
|
|
4946
|
-
.map(
|
|
5073
|
+
.filter(record => samePrincipal(record.auth, caller))
|
|
5074
|
+
.map(record => record.sessionId)
|
|
4947
5075
|
);
|
|
4948
5076
|
}
|
|
4949
5077
|
|
|
@@ -5087,8 +5215,8 @@ export class SessionEngine {
|
|
|
5087
5215
|
includeAll: boolean
|
|
5088
5216
|
): SessionSummary[] {
|
|
5089
5217
|
return records
|
|
5090
|
-
.filter(
|
|
5091
|
-
.map(
|
|
5218
|
+
.filter(record => includeAll || samePrincipal(record.auth, caller))
|
|
5219
|
+
.map(record => {
|
|
5092
5220
|
const links = sessionExternalLinks(record);
|
|
5093
5221
|
return {
|
|
5094
5222
|
sessionId: record.sessionId,
|
|
@@ -5123,61 +5251,6 @@ export class SessionEngine {
|
|
|
5123
5251
|
});
|
|
5124
5252
|
}
|
|
5125
5253
|
|
|
5126
|
-
/**
|
|
5127
|
-
* Fold durable session streams into per-session A/B assignments and
|
|
5128
|
-
* aggregate arm metrics (`GET /v1/abs`). Collector-independent: always
|
|
5129
|
-
* reads `events.ndjson`.
|
|
5130
|
-
*/
|
|
5131
|
-
async abSnapshot(
|
|
5132
|
-
caller: AuthContext | null,
|
|
5133
|
-
options?: { includeAll?: boolean }
|
|
5134
|
-
): Promise<ABSnapshot> {
|
|
5135
|
-
const sessions = await this.listSessions(caller, options);
|
|
5136
|
-
const abConfig = this.project.abConfig;
|
|
5137
|
-
const maxPlaygroundSessions = resolveABMaxPlaygroundSessions(
|
|
5138
|
-
abConfig?.maxPlaygroundSessions
|
|
5139
|
-
);
|
|
5140
|
-
const foldedSessions = sessions.slice(0, maxPlaygroundSessions);
|
|
5141
|
-
// Backfill for a replacement host with nothing local to fold (e.g.
|
|
5142
|
-
// lazy-only restore before any session resumed): serve the persisted
|
|
5143
|
-
// aggregate instead of an empty surface. Gated on the host having no
|
|
5144
|
-
// sessions AT ALL — the persisted snapshot spans every principal, so a
|
|
5145
|
-
// caller who merely owns no sessions must not see it. Loaded once per
|
|
5146
|
-
// process (playground polls this route ~every 4s); skip the persist
|
|
5147
|
-
// side effect below — re-saving a restored snapshot would echo stale
|
|
5148
|
-
// data back into the store.
|
|
5149
|
-
if (
|
|
5150
|
-
foldedSessions.length === 0 &&
|
|
5151
|
-
this.storage !== undefined &&
|
|
5152
|
-
(await this.sessions.list()).length === 0
|
|
5153
|
-
) {
|
|
5154
|
-
this.restoredAbSnapshot ??= this.storage.getLatestAbSnapshot();
|
|
5155
|
-
const restoredSnapshot = await this.restoredAbSnapshot;
|
|
5156
|
-
if (restoredSnapshot !== undefined) {
|
|
5157
|
-
return restoredSnapshot;
|
|
5158
|
-
}
|
|
5159
|
-
}
|
|
5160
|
-
const abTable = this.project.storage?.abs;
|
|
5161
|
-
const snapshot = await buildABSnapshot({
|
|
5162
|
-
experiments: this.project.abs,
|
|
5163
|
-
agentName: this.project.name,
|
|
5164
|
-
sessions: foldedSessions,
|
|
5165
|
-
loadRecord: (sessionId) => this.sessions.get(sessionId),
|
|
5166
|
-
loadEvents: (sessionId) => this.listEvents(sessionId, 0),
|
|
5167
|
-
sessionInfo: (record) => this.sessionInfo(record),
|
|
5168
|
-
logger: this.logger,
|
|
5169
|
-
config: {
|
|
5170
|
-
maxPlaygroundSessions,
|
|
5171
|
-
durableSamples: abTable !== undefined,
|
|
5172
|
-
durableSnapshots: abTable?.putSnapshot !== undefined,
|
|
5173
|
-
},
|
|
5174
|
-
});
|
|
5175
|
-
// Side effect on the read path: playground polls GET /v1/abs ~every 4s;
|
|
5176
|
-
// the coordinator throttles the actual table write.
|
|
5177
|
-
this.storage?.abSnapshot(snapshot);
|
|
5178
|
-
return snapshot;
|
|
5179
|
-
}
|
|
5180
|
-
|
|
5181
5254
|
async eventStream(
|
|
5182
5255
|
sessionId: string,
|
|
5183
5256
|
startIndex = 0
|
|
@@ -5202,7 +5275,7 @@ export class SessionEngine {
|
|
|
5202
5275
|
if (existing === undefined) {
|
|
5203
5276
|
throw new Error(`Unknown session: ${sessionId}`);
|
|
5204
5277
|
}
|
|
5205
|
-
const record = await this.updateRecord(sessionId,
|
|
5278
|
+
const record = await this.updateRecord(sessionId, current => ({
|
|
5206
5279
|
...current,
|
|
5207
5280
|
turnCount: current.turnCount + 1,
|
|
5208
5281
|
}));
|
|
@@ -5337,7 +5410,7 @@ export class SessionEngine {
|
|
|
5337
5410
|
return pending;
|
|
5338
5411
|
}
|
|
5339
5412
|
const work = this.runCloudTurnCostBackfill(sessionId)
|
|
5340
|
-
.catch(
|
|
5413
|
+
.catch(error => {
|
|
5341
5414
|
this.logger(
|
|
5342
5415
|
`[agent-sdk] cloud cost backfill failed for ${sessionId}: ${describeError(error)}`
|
|
5343
5416
|
);
|
|
@@ -5352,10 +5425,10 @@ export class SessionEngine {
|
|
|
5352
5425
|
private async runCloudTurnCostBackfill(sessionId: string): Promise<void> {
|
|
5353
5426
|
const log = await this.logs.get(sessionId);
|
|
5354
5427
|
const events = await log.snapshot(0);
|
|
5355
|
-
if (!events.some(
|
|
5428
|
+
if (!events.some(event => isUnpricedCompletedTurn(event))) {
|
|
5356
5429
|
if (
|
|
5357
5430
|
!this.isTurnRunning(sessionId) &&
|
|
5358
|
-
events.some(
|
|
5431
|
+
events.some(event => event.type === "turn.completed")
|
|
5359
5432
|
) {
|
|
5360
5433
|
this.cloudCostBackfillDone.add(sessionId);
|
|
5361
5434
|
}
|
|
@@ -5386,7 +5459,7 @@ export class SessionEngine {
|
|
|
5386
5459
|
log.replace(i, next);
|
|
5387
5460
|
}
|
|
5388
5461
|
if (
|
|
5389
|
-
!(await log.snapshot(0)).some(
|
|
5462
|
+
!(await log.snapshot(0)).some(event => isUnpricedCompletedTurn(event))
|
|
5390
5463
|
) {
|
|
5391
5464
|
this.cloudCostBackfillDone.add(sessionId);
|
|
5392
5465
|
}
|
|
@@ -5397,7 +5470,7 @@ export class SessionEngine {
|
|
|
5397
5470
|
token: string | null
|
|
5398
5471
|
): Promise<void> {
|
|
5399
5472
|
const previous = await this.sessions.get(sessionId);
|
|
5400
|
-
await this.updateRecord(sessionId,
|
|
5473
|
+
await this.updateRecord(sessionId, current => ({
|
|
5401
5474
|
...current,
|
|
5402
5475
|
continuationKey: token,
|
|
5403
5476
|
}));
|
|
@@ -5437,7 +5510,6 @@ export class SessionEngine {
|
|
|
5437
5510
|
asOf: record.asOf,
|
|
5438
5511
|
auth: record.auth,
|
|
5439
5512
|
continuationKey: record.continuationKey,
|
|
5440
|
-
...(record.abs === undefined ? {} : { abs: record.abs }),
|
|
5441
5513
|
...(record.title === undefined ? {} : { title: record.title }),
|
|
5442
5514
|
...(record.sdkAgentId === undefined
|
|
5443
5515
|
? {}
|
|
@@ -5539,9 +5611,9 @@ export class SessionEngine {
|
|
|
5539
5611
|
* serve start, before channels accept traffic: any persisted session
|
|
5540
5612
|
* missing from the local `--state-root` is materialized there — events
|
|
5541
5613
|
* as `events.ndjson`, record as `session.json` — after which every
|
|
5542
|
-
* existing read path (continuation lookup, event replay/streams
|
|
5543
|
-
*
|
|
5544
|
-
*
|
|
5614
|
+
* existing read path (continuation lookup, event replay/streams) works
|
|
5615
|
+
* unchanged. Local state always wins over the sink, so restarts on the
|
|
5616
|
+
* same host are no-ops.
|
|
5545
5617
|
*
|
|
5546
5618
|
* Failures are logged and skipped; a broken store (including rows that
|
|
5547
5619
|
* violate the SessionRecord shape) never blocks serve start.
|
|
@@ -5575,7 +5647,7 @@ export class SessionEngine {
|
|
|
5575
5647
|
// the lazy continuation-lookup path.
|
|
5576
5648
|
const cutoff = Date.now() - policy.maxAgeMs;
|
|
5577
5649
|
const candidates = loaded
|
|
5578
|
-
.map(
|
|
5650
|
+
.map(record => ({
|
|
5579
5651
|
record,
|
|
5580
5652
|
// Numeric timestamp for both the age filter and the sort; a
|
|
5581
5653
|
// non-string updatedAt (e.g. a raw DB Date from an untyped sink)
|
|
@@ -5607,7 +5679,7 @@ export class SessionEngine {
|
|
|
5607
5679
|
) {
|
|
5608
5680
|
const chunk = candidates.slice(i, i + RESTORE_FETCH_CONCURRENCY);
|
|
5609
5681
|
const fetched = await Promise.all(
|
|
5610
|
-
chunk.map(async
|
|
5682
|
+
chunk.map(async record => {
|
|
5611
5683
|
try {
|
|
5612
5684
|
// Local state always wins over the sink.
|
|
5613
5685
|
if ((await this.sessions.get(record.sessionId)) !== undefined) {
|
|
@@ -5864,7 +5936,7 @@ function eventsNdjson(events: SessionEvent[]): string | undefined {
|
|
|
5864
5936
|
if (events.length === 0) {
|
|
5865
5937
|
return undefined;
|
|
5866
5938
|
}
|
|
5867
|
-
return `${events.map(
|
|
5939
|
+
return `${events.map(event => JSON.stringify(event)).join("\n")}\n`;
|
|
5868
5940
|
}
|
|
5869
5941
|
|
|
5870
5942
|
function subagentPrompt(subagent: ResolvedAgent): string {
|
|
@@ -5880,7 +5952,7 @@ function subagentPrompt(subagent: ResolvedAgent): string {
|
|
|
5880
5952
|
* executor that turn will run on.
|
|
5881
5953
|
*/
|
|
5882
5954
|
function buildRunnerSubagents(agent: ResolvedAgent): RunnerSubagent[] {
|
|
5883
|
-
return agent.subagents.map(
|
|
5955
|
+
return agent.subagents.map(subagent => ({
|
|
5884
5956
|
name: subagent.name,
|
|
5885
5957
|
description: subagent.description ?? subagent.name,
|
|
5886
5958
|
prompt: subagentPrompt(subagent),
|
|
@@ -5904,7 +5976,7 @@ async function defaultGetCloudUsage(
|
|
|
5904
5976
|
return {
|
|
5905
5977
|
usage: mapSdkTokenUsage(billed.usage),
|
|
5906
5978
|
cost: billed.cost,
|
|
5907
|
-
runs: billed.runs.map(
|
|
5979
|
+
runs: billed.runs.map(run => ({
|
|
5908
5980
|
runId: run.runId,
|
|
5909
5981
|
usage: mapSdkTokenUsage(run.usage),
|
|
5910
5982
|
cost: run.cost,
|
|
@@ -5956,7 +6028,7 @@ function approvalResolverLabel(auth: AuthContext | null): string | undefined {
|
|
|
5956
6028
|
|
|
5957
6029
|
/** Let the HTTP NDJSON writer flush before the next SDK update. */
|
|
5958
6030
|
function yieldEventLoop(): Promise<void> {
|
|
5959
|
-
return new Promise(
|
|
6031
|
+
return new Promise(resolve => {
|
|
5960
6032
|
setImmediate(resolve);
|
|
5961
6033
|
});
|
|
5962
6034
|
}
|