@cursor/bdk 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/dist/bin/agent-serve.js +23 -7
- package/dist/channels/github/auth.d.ts.map +1 -1
- package/dist/channels/github/auth.js +36 -5
- package/dist/connections.d.ts +1 -1
- package/dist/connections.js +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.DtYVVVyK.js → app.BOIHhrKi.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot.D5L-b34G.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.D47xT7J4.js → VPLocalSearchBox.D49zVZqM.js} +1 -1
- package/dist/docs/assets/chunks/{arc.CDJ6xzxR.js → arc.hmjb-sc4.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.l1Xnjd3N.js → architectureDiagram-Q4EWVU46.CxEI1KqM.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.x-finShZ.js → baseUniq.DHHvBWoV.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.COC3qynH.js → blockDiagram-DXYQGD6D.DnXW-3bu.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.DdQO850E.js → c4Diagram-AHTNJAMY.e-47O2jM.js} +1 -1
- package/dist/docs/assets/chunks/channel.BbOGaJQP.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.Dpn8omLk.js → chunk-4BX2VUAB.3ry4pYXB.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.C0XWStUN.js → chunk-4TB4RGXK.DGIZFRx6.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.DsKSZfIM.js → chunk-55IACEB6.DKBnqg9U.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.dNU6JDu6.js → chunk-EDXVE4YY.BIU8Ue5k.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.DN41fxKE.js → chunk-FMBD7UC4.DP-TFhjI.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.COpKCZus.js → chunk-OYMX7WX6.Ux0OYj5v.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.HDB-azx2.js → chunk-QZHKN3VN.BzHMwYox.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.DEeX_a2j.js → chunk-YZCP3GAM.D4OGAsSP.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.Db58HCb1.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.Db58HCb1.js +1 -0
- package/dist/docs/assets/chunks/clone.Co4MBflG.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.C3yGL2A8.js → cose-bilkent-S5V4N54A.Jq_7BUNx.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.Bpl24en4.js → dagre-KV5264BT.Di-skR2x.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.nFco6seU.js → diagram-5BDNPKRD.DeREHIdH.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.DXhA6DWR.js → diagram-G4DWMVQ6.C7Kcqxro.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.8GoOYcwk.js → diagram-MMDJMWI5.BK3eohyo.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.DDBlqvlJ.js → diagram-TYMM5635.C6TyymXT.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.vl_N81P4.js → erDiagram-SMLLAGMA.DYGG-gGx.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.Cteg8g7I.js → flowDiagram-DWJPFMVM.C9nBcSV4.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.D4aMhlMM.js → ganttDiagram-T4ZO3ILL.wAg_ymsp.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.DF_J0D4q.js → gitGraphDiagram-UUTBAWPF.B87j9Oeg.js} +1 -1
- package/dist/docs/assets/chunks/{graph.DJs0LDCf.js → graph.CuFMj31w.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.Bb-4RQwg.js → infoDiagram-42DDH7IO.P_mLGumP.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DEtQRSbc.js → ishikawaDiagram-UXIWVN3A.DyuL_MsT.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.DhQQ75FA.js → journeyDiagram-VCZTEJTY.CtP09IoJ.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.C4gEw3Rk.js → kanban-definition-6JOO6SKY.BoeSYPZo.js} +1 -1
- package/dist/docs/assets/chunks/{layout.DT-PGlXa.js → layout.B0lMMtNo.js} +1 -1
- package/dist/docs/assets/chunks/{linear.BMMe__JW.js → linear.HxRBiAFX.js} +1 -1
- package/dist/docs/assets/chunks/{min.XyaU9K9Q.js → min.BGlFFHwS.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.CbBM6xZ-.js → mindmap-definition-QFDTVHPH.JyLBD9M8.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DFJoIVou.js → pieDiagram-DEJITSTG.DnSmNZF8.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CQjkDYqb.js → quadrantDiagram-34T5L4WZ.CUCnbfCa.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.D-mK-JQu.js → requirementDiagram-MS252O5E.py0IVUn5.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.BStQInpd.js → sankeyDiagram-XADWPNL6.Bkc-HWYp.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.CA_eooPJ.js → sequenceDiagram-FGHM5R23.Dqn8Mlv2.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.BXl-b7ad.js → stateDiagram-FHFEXIEX.JikkoQUU.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CMsKhrW0.js +1 -0
- package/dist/docs/assets/chunks/{theme.q37tOs4x.js → theme.b6HQ6zG_.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.vjuaGOSe.js → timeline-definition-GMOUNBTQ.BvpSXiBj.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.BxduJl-F.js → vennDiagram-DHZGUBPP.CU7MVnZx.js} +1 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.BKwC4ctG.js +162 -0
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.D1z3ds0D.js → wardleyDiagram-NUSXRM2D.BfaF6Uhe.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.CRU5Ti9b.js → xychartDiagram-5P7HB3ND.Bg5dcpj4.js} +1 -1
- package/dist/docs/assets/{deployment.md.nGo1yIsa.js → deployment.md.BJ8i7Q6p.js} +5 -8
- package/dist/docs/assets/{deployment.md.nGo1yIsa.lean.js → deployment.md.BJ8i7Q6p.lean.js} +1 -1
- package/dist/docs/assets/{guides_github.md.C2_DSWlE.js → guides_github.md.Bq9kQU9B.js} +9 -3
- package/dist/docs/assets/{guides_github.md.C2_DSWlE.lean.js → guides_github.md.Bq9kQU9B.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.ZbHQETOT.js → guides_slack.md.diqqXTTm.js} +2 -2
- package/dist/docs/assets/{guides_slack.md.ZbHQETOT.lean.js → guides_slack.md.diqqXTTm.lean.js} +1 -1
- package/dist/docs/assets/{quickstart.md.wG4shE1f.js → quickstart.md.CHpHPBUN.js} +5 -3
- package/dist/docs/assets/{quickstart.md.wG4shE1f.lean.js → quickstart.md.CHpHPBUN.lean.js} +1 -1
- package/dist/docs/assets/{reference_artifacts.md.CFMNPreZ.js → reference_artifacts.md.CQfKq8F2.js} +1 -1
- package/dist/docs/assets/reference_cli.md.DgeLTO18.js +91 -0
- package/dist/docs/assets/reference_cli.md.DgeLTO18.lean.js +1 -0
- package/dist/docs/assets/{reference_connections.md._XpKiOaF.js → reference_connections.md.COq--gAm.js} +7 -3
- package/dist/docs/assets/{reference_connections.md._XpKiOaF.lean.js → reference_connections.md.COq--gAm.lean.js} +1 -1
- package/dist/docs/assets/{reference_evals.md.DqNyHMA6.js → reference_evals.md.CJm3uCUm.js} +4 -4
- package/dist/docs/assets/{reference_evals.md.DqNyHMA6.lean.js → reference_evals.md.CJm3uCUm.lean.js} +1 -1
- package/dist/docs/assets/{reference_skills.md.CRFTxt9M.js → reference_skills.md.Cy00QMKS.js} +3 -3
- package/dist/docs/assets/{reference_skills.md.CRFTxt9M.lean.js → reference_skills.md.Cy00QMKS.lean.js} +1 -1
- package/dist/docs/assets/troubleshooting.md.Cw5PKa3t.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.BzZSu1Gz.lean.js → troubleshooting.md.Cw5PKa3t.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +35 -35
- package/dist/docs/deployment.html +40 -43
- package/dist/docs/deployment.md +45 -15
- package/dist/docs/evals.html +35 -35
- package/dist/docs/guides/agent-to-agent.html +35 -35
- package/dist/docs/guides/bitbucket.html +35 -35
- package/dist/docs/guides/cloud-agents.html +35 -35
- package/dist/docs/guides/convert-automation.html +35 -35
- package/dist/docs/guides/github.html +43 -37
- package/dist/docs/guides/github.md +34 -0
- package/dist/docs/guides/gitlab.html +35 -35
- package/dist/docs/guides/grokbot-agents.html +35 -35
- package/dist/docs/guides/hooks.html +35 -35
- package/dist/docs/guides/improve.html +35 -35
- package/dist/docs/guides/jev.html +35 -35
- package/dist/docs/guides/mcp-oauth.html +35 -35
- package/dist/docs/guides/opentelemetry.html +35 -35
- package/dist/docs/guides/slack.html +37 -37
- package/dist/docs/guides/slack.md +5 -0
- package/dist/docs/guides/webhooks.html +35 -35
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +35 -35
- package/dist/docs/index.html +35 -35
- package/dist/docs/llms-full.txt +198 -92
- package/dist/docs/quickstart.html +40 -38
- package/dist/docs/quickstart.md +7 -1
- package/dist/docs/reference/agent-config.html +35 -35
- package/dist/docs/reference/artifacts.html +37 -37
- package/dist/docs/reference/artifacts.md +1 -1
- package/dist/docs/reference/channels.html +35 -35
- package/dist/docs/reference/cli.html +55 -61
- package/dist/docs/reference/cli.md +65 -63
- package/dist/docs/reference/connections.html +42 -38
- package/dist/docs/reference/connections.md +28 -2
- package/dist/docs/reference/evals.html +39 -39
- package/dist/docs/reference/evals.md +6 -7
- package/dist/docs/reference/extensions.html +35 -35
- package/dist/docs/reference/hooks.html +35 -35
- package/dist/docs/reference/http-api.html +35 -35
- package/dist/docs/reference/instructions.html +35 -35
- package/dist/docs/reference/playground.html +35 -35
- package/dist/docs/reference/project-layout.html +35 -35
- package/dist/docs/reference/prompt.html +35 -35
- package/dist/docs/reference/schedules.html +35 -35
- package/dist/docs/reference/sessions.html +35 -35
- package/dist/docs/reference/skills.html +38 -38
- package/dist/docs/reference/subagents.html +35 -35
- package/dist/docs/reference/tools.html +35 -35
- package/dist/docs/templates/agentic-owners.html +35 -35
- package/dist/docs/templates/security-reviewer.html +35 -35
- package/dist/docs/templates/thermo-quality-review.html +35 -35
- package/dist/docs/templates/thermo-review.html +35 -35
- package/dist/docs/templates/triage.html +35 -35
- package/dist/docs/troubleshooting.html +36 -36
- package/dist/docs/troubleshooting.md +7 -3
- package/dist/extensions/cursor-grokbot-agents/extension.d.ts +77 -0
- package/dist/extensions/cursor-grokbot-agents/extension.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/extension.js +63 -0
- package/dist/extensions/cursor-grokbot-agents/lib/agents.d.ts +11 -0
- package/dist/extensions/cursor-grokbot-agents/lib/agents.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/agents.js +31 -0
- package/dist/extensions/cursor-grokbot-agents/lib/backend.d.ts +56 -0
- package/dist/extensions/cursor-grokbot-agents/lib/backend.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/backend.js +158 -0
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.d.ts +28 -0
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.js +59 -0
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.d.ts +53 -0
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.js +206 -0
- package/dist/extensions/cursor-grokbot-agents/lib/inputs.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/lib/inputs.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/inputs.js +15 -0
- package/dist/extensions/cursor-grokbot-agents/lib/lock.d.ts +12 -0
- package/dist/extensions/cursor-grokbot-agents/lib/lock.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/lock.js +25 -0
- package/dist/extensions/cursor-grokbot-agents/skills/consult.md +40 -0
- package/dist/extensions/cursor-grokbot-agents/tools/ask.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/tools/ask.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/tools/ask.js +37 -0
- package/dist/extensions/cursor-grokbot-agents/tools/check.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/tools/check.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/tools/check.js +32 -0
- package/dist/extensions/cursor-grokbot-agents/tools/interrupt.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/tools/interrupt.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/tools/interrupt.js +24 -0
- package/dist/extensions/cursor-grokbot-agents/tools/list.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/tools/list.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/tools/list.js +34 -0
- package/dist/internal/cli-ax.d.ts +1 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +43 -10
- package/dist/internal/cli-deploy.d.ts +5 -1
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +22 -4
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
- package/dist/internal/cli-mcp-oauth.js +2 -1
- package/dist/internal/cli-skills.d.ts +1 -1
- package/dist/internal/cli-skills.d.ts.map +1 -1
- package/dist/internal/cli-skills.js +5 -5
- package/dist/internal/connection-env.d.ts +31 -0
- package/dist/internal/connection-env.d.ts.map +1 -0
- package/dist/internal/connection-env.js +84 -0
- package/dist/internal/cursor/backend-client.js +5 -0
- package/dist/internal/deploy-client.d.ts +30 -6
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +45 -9
- package/dist/internal/discovery/connections.d.ts.map +1 -1
- package/dist/internal/discovery/connections.js +11 -0
- package/dist/internal/hosted-delivery-protocol.d.ts +36 -11
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +31 -8
- package/dist/internal/hosted-delivery.d.ts +2 -2
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +228 -48
- package/dist/internal/hosting.d.ts +2 -2
- package/dist/internal/hosting.d.ts.map +1 -1
- package/dist/internal/hosting.js +9 -3
- package/dist/internal/install-cursor-skills.d.ts +20 -24
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +50 -48
- package/dist/internal/legacy-command-guard.d.ts +2 -0
- package/dist/internal/legacy-command-guard.d.ts.map +1 -1
- package/dist/internal/legacy-command-guard.js +10 -1
- package/dist/internal/mcp-host.d.ts +6 -0
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +35 -16
- package/dist/internal/sdk-runner.d.ts +2 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +10 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +11 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +9 -5
- package/dist/types.d.ts +11 -1
- package/dist/types.d.ts.map +1 -1
- package/docs/deployment.md +45 -15
- package/docs/guides/github.md +34 -0
- package/docs/guides/slack.md +5 -0
- package/docs/quickstart.md +7 -1
- package/docs/reference/artifacts.md +1 -1
- package/docs/reference/cli.md +65 -63
- package/docs/reference/connections.md +28 -2
- package/docs/reference/evals.md +6 -7
- package/docs/troubleshooting.md +7 -3
- package/package.json +1 -3
- package/scripts/install-cursor-skills.mjs +1 -1
- package/skills/create-agent/SKILL.md +1 -1
- package/skills/debug/SKILL.md +1 -1
- package/skills/deploy/SKILL.md +1 -1
- package/skills/evals/SKILL.md +1 -1
- package/skills/framework-map/SKILL.md +1 -1
- package/skills/github/SKILL.md +1 -1
- package/skills/hillclimb/SKILL.md +1 -1
- package/skills/mcp-auth/SKILL.md +1 -1
- package/skills/otel/SKILL.md +1 -1
- package/skills/setup-slack/SKILL.md +1 -1
- package/src/bin/agent-serve.ts +27 -6
- package/src/channels/github/auth.ts +44 -5
- package/src/connections.ts +1 -1
- package/src/extensions/cursor-grokbot-agents/extension.ts +132 -0
- package/src/extensions/cursor-grokbot-agents/lib/agents.ts +42 -0
- package/src/extensions/cursor-grokbot-agents/lib/backend.ts +208 -0
- package/src/extensions/cursor-grokbot-agents/lib/contacts.ts +74 -0
- package/src/extensions/cursor-grokbot-agents/lib/conversation.ts +260 -0
- package/src/extensions/cursor-grokbot-agents/lib/inputs.ts +21 -0
- package/src/extensions/cursor-grokbot-agents/lib/lock.ts +26 -0
- package/src/extensions/cursor-grokbot-agents/skills/consult.md +40 -0
- package/src/extensions/cursor-grokbot-agents/tools/ask.ts +32 -0
- package/src/extensions/cursor-grokbot-agents/tools/check.ts +25 -0
- package/src/extensions/cursor-grokbot-agents/tools/interrupt.ts +17 -0
- package/src/extensions/cursor-grokbot-agents/tools/list.ts +26 -0
- package/src/internal/cli-ax.ts +52 -7
- package/src/internal/cli-deploy.ts +39 -6
- package/src/internal/cli-mcp-oauth.ts +2 -1
- package/src/internal/cli-skills.ts +4 -5
- package/src/internal/connection-env.ts +106 -0
- package/src/internal/cursor/backend-client.ts +6 -0
- package/src/internal/deploy-client.ts +79 -9
- package/src/internal/discovery/connections.ts +11 -0
- package/src/internal/hosted-delivery-protocol.ts +57 -20
- package/src/internal/hosted-delivery.ts +486 -228
- package/src/internal/hosting.ts +10 -3
- package/src/internal/install-cursor-skills.ts +56 -53
- package/src/internal/legacy-command-guard.ts +13 -1
- package/src/internal/mcp-host.ts +45 -17
- package/src/internal/sdk-runner.ts +11 -0
- package/src/internal/server.ts +13 -1
- package/src/internal/session-engine.ts +9 -5
- package/src/types.ts +11 -1
- package/templates/agents-md/bot/lib/collect.ts +1 -4
- package/templates/code-wiki/bot/channels/github.ts +2 -2
- package/templates/demo/bot/channels/github.ts +5 -1
- package/templates/pr-autofixer/bot/lib/start-drive.ts +4 -4
- package/templates/triage/bot/lib/types.ts +6 -6
- package/dist/docs/assets/chunks/@localSearchIndexroot.BgTA2tV1.js +0 -1
- package/dist/docs/assets/chunks/channel.B2nMEx82.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.D8iCH2ve.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.D8iCH2ve.js +0 -1
- package/dist/docs/assets/chunks/clone.5XNLjby0.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.yGM2uLZQ.js +0 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.DKfyIejL.js +0 -162
- package/dist/docs/assets/reference_cli.md.BK2QUH67.js +0 -97
- package/dist/docs/assets/reference_cli.md.BK2QUH67.lean.js +0 -1
- package/dist/docs/assets/troubleshooting.md.BzZSu1Gz.js +0 -1
- /package/dist/docs/assets/{reference_artifacts.md.CFMNPreZ.lean.js → reference_artifacts.md.CQfKq8F2.lean.js} +0 -0
|
@@ -36,7 +36,8 @@ import {
|
|
|
36
36
|
HOSTED_GUEST_RETRY_TERMINAL,
|
|
37
37
|
HOSTED_GUEST_RETRY_TRANSIENT,
|
|
38
38
|
HOSTED_MAX_CONSUMED_DELIVERY_IDS,
|
|
39
|
-
type
|
|
39
|
+
type HostedAdmissionInput,
|
|
40
|
+
type HostedAdmissionStart,
|
|
40
41
|
type HostedGuestRetryDisposition,
|
|
41
42
|
type HostedReminderFireDescriptorPayload,
|
|
42
43
|
hostedFailureClassification,
|
|
@@ -74,7 +75,7 @@ import { type EngineSendOptions, HostedEnqueueNotActiveError } from "./session-e
|
|
|
74
75
|
import type { SessionRunExecutionWrite } from "./session-run-log.js";
|
|
75
76
|
|
|
76
77
|
type DispatchInput = {
|
|
77
|
-
delivery:
|
|
78
|
+
delivery: HostedAdmissionInput;
|
|
78
79
|
definition: object;
|
|
79
80
|
args: ChannelHandlerArgs;
|
|
80
81
|
};
|
|
@@ -94,6 +95,13 @@ type AdmissionDispatch = {
|
|
|
94
95
|
type ExecutionReply = {
|
|
95
96
|
status: number;
|
|
96
97
|
body: Record<string, unknown>;
|
|
98
|
+
serverTiming?: string;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
type AdmissionOperation = {
|
|
102
|
+
execution: Promise<ExecutionReply>;
|
|
103
|
+
settledReply?: ExecutionReply;
|
|
104
|
+
expiresAt: number;
|
|
97
105
|
};
|
|
98
106
|
|
|
99
107
|
type HostedEnqueueOutcome = {
|
|
@@ -109,6 +117,29 @@ type ActiveOwnerContext = {
|
|
|
109
117
|
enqueueResults: Map<string, Promise<HostedEnqueueOutcome>>;
|
|
110
118
|
};
|
|
111
119
|
|
|
120
|
+
async function responseToReply(response: Response): Promise<ExecutionReply> {
|
|
121
|
+
const value = (await response.json()) as unknown;
|
|
122
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
123
|
+
throw new Error("Hosted delivery produced a non-object JSON response.");
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
status: response.status,
|
|
127
|
+
body: value as Record<string, unknown>,
|
|
128
|
+
serverTiming: response.headers.get("server-timing") ?? undefined,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function responseFromReply(reply: ExecutionReply): Response {
|
|
133
|
+
return Response.json(reply.body, {
|
|
134
|
+
status: reply.status,
|
|
135
|
+
headers: reply.serverTiming === undefined ? undefined : { "server-timing": reply.serverTiming },
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function isTransientRetryReply(reply: ExecutionReply): boolean {
|
|
140
|
+
return reply.body.retry === HOSTED_GUEST_RETRY_TRANSIENT;
|
|
141
|
+
}
|
|
142
|
+
|
|
112
143
|
/**
|
|
113
144
|
* A second `send()` in one delivery is a deterministic authored bug — the
|
|
114
145
|
* wire protocol carries exactly one pending send per delivery — so it must
|
|
@@ -137,6 +168,21 @@ function boundedMessage(text: string): string {
|
|
|
137
168
|
: text;
|
|
138
169
|
}
|
|
139
170
|
|
|
171
|
+
/**
|
|
172
|
+
* A channel's non-OK dispatch response body is the only record of why the
|
|
173
|
+
* delivery was refused (e.g. an authored 400 with a validation message).
|
|
174
|
+
* Carry it, bounded, into the terminal channel_dispatch_failed so the
|
|
175
|
+
* control plane's failure log is diagnosable.
|
|
176
|
+
*/
|
|
177
|
+
async function channelDispatchDetail(response: Response): Promise<string | undefined> {
|
|
178
|
+
try {
|
|
179
|
+
const text = (await response.text()).trim();
|
|
180
|
+
return text === "" ? undefined : boundedMessage(text);
|
|
181
|
+
} catch {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
140
186
|
function terminalHostedError(status: number, error: string, message?: string): Response {
|
|
141
187
|
return hostedGuestErrorResponse({
|
|
142
188
|
status,
|
|
@@ -250,7 +296,7 @@ async function dispatchHostedReminderAdmission(
|
|
|
250
296
|
reason?: string;
|
|
251
297
|
}>;
|
|
252
298
|
},
|
|
253
|
-
delivery:
|
|
299
|
+
delivery: HostedAdmissionInput,
|
|
254
300
|
): Promise<Response> {
|
|
255
301
|
const descriptor = parseHostedReminderFireDescriptorPayload(delivery.payload);
|
|
256
302
|
if (descriptor !== undefined) {
|
|
@@ -364,6 +410,7 @@ async function runAdmission(
|
|
|
364
410
|
response: terminalHostedError(
|
|
365
411
|
dispatched.status >= 400 ? dispatched.status : 502,
|
|
366
412
|
"channel_dispatch_failed",
|
|
413
|
+
await channelDispatchDetail(dispatched),
|
|
367
414
|
),
|
|
368
415
|
};
|
|
369
416
|
}
|
|
@@ -564,10 +611,14 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
564
611
|
deliveryId: string;
|
|
565
612
|
sessionPublicId?: string;
|
|
566
613
|
execution?: Promise<ExecutionReply>;
|
|
614
|
+
settledReply?: ExecutionReply;
|
|
567
615
|
}
|
|
568
616
|
>();
|
|
617
|
+
const admissions = new Map<string, AdmissionOperation>();
|
|
569
618
|
const activeOwners = new Map<string, ActiveOwnerContext>();
|
|
570
619
|
const pendingTtlMs = 10 * 60_000;
|
|
620
|
+
/** Keep an in-flight owner turn addressable for status polls. */
|
|
621
|
+
const ownerTurnPendingTtlMs = 12 * 60 * 60_000;
|
|
571
622
|
const waitForNetwork = input.waitForGuestNetwork ?? (() => waitForGuestNetworkReady());
|
|
572
623
|
const consumeBoundSecrets = input.consumeBoundSecrets ?? (() => consumeHostedBoundSecrets());
|
|
573
624
|
/**
|
|
@@ -613,7 +664,81 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
613
664
|
pending.delete(token);
|
|
614
665
|
}
|
|
615
666
|
}
|
|
667
|
+
for (const [deliveryId, operation] of admissions) {
|
|
668
|
+
if (operation.expiresAt <= now) {
|
|
669
|
+
admissions.delete(deliveryId);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
616
672
|
};
|
|
673
|
+
const runAdmissionOperation = async (
|
|
674
|
+
delivery: HostedAdmissionStart,
|
|
675
|
+
definition: object | undefined,
|
|
676
|
+
): Promise<ExecutionReply> =>
|
|
677
|
+
afterHostedWork(input.flushOtel, async () => {
|
|
678
|
+
const startedAt = performance.now();
|
|
679
|
+
let guestNetwork: GuestNetworkWaitStats | undefined;
|
|
680
|
+
const finish = (response: Response) =>
|
|
681
|
+
withServerTiming(response, performance.now() - startedAt, guestNetwork);
|
|
682
|
+
try {
|
|
683
|
+
const network = await finishNetworkWait("admission");
|
|
684
|
+
guestNetwork = network.timing;
|
|
685
|
+
if (network.response !== undefined) {
|
|
686
|
+
return await responseToReply(finish(network.response));
|
|
687
|
+
}
|
|
688
|
+
if (isHostedReminderAdmission(delivery)) {
|
|
689
|
+
return await responseToReply(
|
|
690
|
+
finish(await dispatchHostedReminderAdmission(input, delivery)),
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
if (definition === undefined) {
|
|
694
|
+
return await responseToReply(
|
|
695
|
+
finish(
|
|
696
|
+
terminalHostedError(
|
|
697
|
+
404,
|
|
698
|
+
"channel_not_found",
|
|
699
|
+
`No channel named "${delivery.channelId}" is mounted.`,
|
|
700
|
+
),
|
|
701
|
+
),
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
const admitted = await dispatchHostedAdmission({
|
|
705
|
+
delivery,
|
|
706
|
+
definition,
|
|
707
|
+
args: input.buildHandlerArgs(delivery.channelId),
|
|
708
|
+
});
|
|
709
|
+
if (admitted.pendingSend === undefined) {
|
|
710
|
+
return await responseToReply(finish(admitted.response));
|
|
711
|
+
}
|
|
712
|
+
pruneExpired();
|
|
713
|
+
const admissionToken = randomBytes(24).toString("hex");
|
|
714
|
+
pending.set(admissionToken, {
|
|
715
|
+
send: admitted.pendingSend,
|
|
716
|
+
channelKind: delivery.channelKind,
|
|
717
|
+
expiresAt: Date.now() + pendingTtlMs,
|
|
718
|
+
deliveryId: delivery.deliveryId,
|
|
719
|
+
});
|
|
720
|
+
return await responseToReply(
|
|
721
|
+
finish(
|
|
722
|
+
Response.json({
|
|
723
|
+
ok: true,
|
|
724
|
+
v: HOSTED_DELIVERY_PROTOCOL_VERSION,
|
|
725
|
+
outcome: "send",
|
|
726
|
+
admissionToken,
|
|
727
|
+
}),
|
|
728
|
+
),
|
|
729
|
+
);
|
|
730
|
+
} catch (error) {
|
|
731
|
+
return await responseToReply(
|
|
732
|
+
finish(
|
|
733
|
+
terminalHostedError(
|
|
734
|
+
503,
|
|
735
|
+
"internal_error",
|
|
736
|
+
boundedMessage(error instanceof Error ? error.message : String(error)),
|
|
737
|
+
),
|
|
738
|
+
),
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
});
|
|
617
742
|
|
|
618
743
|
// Hosted callers reach this only through Anyrun's signed pod-port URL.
|
|
619
744
|
// The marker is a second, route-specific fence distinct from channel auth.
|
|
@@ -634,9 +759,8 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
634
759
|
handler: async request =>
|
|
635
760
|
afterHostedWork(input.flushOtel, async () => {
|
|
636
761
|
const startedAt = performance.now();
|
|
637
|
-
let guestNetwork: GuestNetworkWaitStats | undefined;
|
|
638
762
|
const finish = (response: Response) =>
|
|
639
|
-
withServerTiming(response, performance.now() - startedAt
|
|
763
|
+
withServerTiming(response, performance.now() - startedAt);
|
|
640
764
|
const unconsumed = finishBoundSecrets();
|
|
641
765
|
if (unconsumed !== undefined) {
|
|
642
766
|
return finish(unconsumed);
|
|
@@ -661,20 +785,53 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
661
785
|
),
|
|
662
786
|
);
|
|
663
787
|
}
|
|
788
|
+
pruneExpired();
|
|
789
|
+
const existing = admissions.get(delivery.deliveryId);
|
|
790
|
+
if (delivery.mode === "status") {
|
|
791
|
+
if (existing === undefined) {
|
|
792
|
+
return finish(
|
|
793
|
+
transientHostedError(
|
|
794
|
+
409,
|
|
795
|
+
"hosted_admission_unavailable",
|
|
796
|
+
"No hosted admission is in flight for this delivery.",
|
|
797
|
+
),
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
return existing.settledReply === undefined
|
|
801
|
+
? finish(
|
|
802
|
+
Response.json({
|
|
803
|
+
ok: true,
|
|
804
|
+
v: HOSTED_DELIVERY_PROTOCOL_VERSION,
|
|
805
|
+
outcome: "running",
|
|
806
|
+
}),
|
|
807
|
+
)
|
|
808
|
+
: responseFromReply(existing.settledReply);
|
|
809
|
+
}
|
|
810
|
+
if (existing !== undefined) {
|
|
811
|
+
if (existing.settledReply !== undefined && isTransientRetryReply(existing.settledReply)) {
|
|
812
|
+
admissions.delete(delivery.deliveryId);
|
|
813
|
+
} else {
|
|
814
|
+
return existing.settledReply === undefined
|
|
815
|
+
? finish(
|
|
816
|
+
Response.json({
|
|
817
|
+
ok: true,
|
|
818
|
+
v: HOSTED_DELIVERY_PROTOCOL_VERSION,
|
|
819
|
+
outcome: "started",
|
|
820
|
+
}),
|
|
821
|
+
)
|
|
822
|
+
: responseFromReply(existing.settledReply);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
664
826
|
console.info(
|
|
665
827
|
`[agent-sdk] hosted admission received deliveryId=${delivery.deliveryId} channelId=${delivery.channelId} channelKind=${delivery.channelKind} eventType=${delivery.eventType} sessionMode=${delivery.sessionMode} managedAutomation=${delivery.managedAutomation === undefined ? "<absent>" : `automationUuid=${delivery.managedAutomation.automationUuid} mcpServerNames=${String(delivery.managedAutomation.mcpServerNames.length)} slackChannels=${delivery.managedAutomation.slackChannels === undefined ? "<absent>" : JSON.stringify(delivery.managedAutomation.slackChannels)}`}`,
|
|
666
828
|
);
|
|
667
829
|
recordHostedManagedAutomation(delivery);
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
}
|
|
674
|
-
return finish(await dispatchHostedReminderAdmission(input, delivery));
|
|
675
|
-
}
|
|
676
|
-
const channel = input.channels.find(candidate => candidate.id === delivery.channelId);
|
|
677
|
-
if (channel === undefined) {
|
|
830
|
+
const reminder = isHostedReminderAdmission(delivery);
|
|
831
|
+
const definition = reminder
|
|
832
|
+
? undefined
|
|
833
|
+
: input.channels.find(candidate => candidate.id === delivery.channelId)?.definition;
|
|
834
|
+
if (!reminder && definition === undefined) {
|
|
678
835
|
return finish(
|
|
679
836
|
terminalHostedError(
|
|
680
837
|
404,
|
|
@@ -683,33 +840,29 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
683
840
|
),
|
|
684
841
|
);
|
|
685
842
|
}
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
const admitted = await dispatchHostedAdmission({
|
|
692
|
-
delivery,
|
|
693
|
-
definition: channel.definition,
|
|
694
|
-
args: input.buildHandlerArgs(delivery.channelId),
|
|
843
|
+
let operation: AdmissionOperation;
|
|
844
|
+
const execution = runAdmissionOperation(delivery, definition).then(reply => {
|
|
845
|
+
operation.settledReply = reply;
|
|
846
|
+
operation.expiresAt = Date.now() + pendingTtlMs;
|
|
847
|
+
return reply;
|
|
695
848
|
});
|
|
696
|
-
|
|
697
|
-
|
|
849
|
+
operation = {
|
|
850
|
+
execution,
|
|
851
|
+
expiresAt: Date.now() + ownerTurnPendingTtlMs,
|
|
852
|
+
};
|
|
853
|
+
admissions.set(delivery.deliveryId, operation);
|
|
854
|
+
const quickReply = await Promise.race([
|
|
855
|
+
execution,
|
|
856
|
+
new Promise<undefined>(resolve => setImmediate(() => resolve(undefined))),
|
|
857
|
+
]);
|
|
858
|
+
if (quickReply !== undefined) {
|
|
859
|
+
return responseFromReply(quickReply);
|
|
698
860
|
}
|
|
699
|
-
pruneExpired();
|
|
700
|
-
const admissionToken = randomBytes(24).toString("hex");
|
|
701
|
-
pending.set(admissionToken, {
|
|
702
|
-
send: admitted.pendingSend,
|
|
703
|
-
channelKind: delivery.channelKind,
|
|
704
|
-
expiresAt: Date.now() + pendingTtlMs,
|
|
705
|
-
deliveryId: delivery.deliveryId,
|
|
706
|
-
});
|
|
707
861
|
return finish(
|
|
708
862
|
Response.json({
|
|
709
863
|
ok: true,
|
|
710
864
|
v: HOSTED_DELIVERY_PROTOCOL_VERSION,
|
|
711
|
-
outcome: "
|
|
712
|
-
admissionToken,
|
|
865
|
+
outcome: "started",
|
|
713
866
|
}),
|
|
714
867
|
);
|
|
715
868
|
}),
|
|
@@ -762,14 +915,58 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
762
915
|
),
|
|
763
916
|
);
|
|
764
917
|
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
918
|
+
|
|
919
|
+
if (
|
|
920
|
+
execution.mode === "start" &&
|
|
921
|
+
admitted.settledReply !== undefined &&
|
|
922
|
+
isTransientRetryReply(admitted.settledReply)
|
|
923
|
+
) {
|
|
924
|
+
delete admitted.settledReply;
|
|
925
|
+
delete admitted.execution;
|
|
769
926
|
}
|
|
927
|
+
|
|
928
|
+
if (
|
|
929
|
+
execution.mode === "status" ||
|
|
930
|
+
(execution.mode === "start" && admitted.execution !== undefined)
|
|
931
|
+
) {
|
|
932
|
+
if (admitted.settledReply !== undefined) {
|
|
933
|
+
return responseFromReply(admitted.settledReply);
|
|
934
|
+
}
|
|
935
|
+
if (admitted.execution === undefined) {
|
|
936
|
+
return finish(
|
|
937
|
+
transientHostedError(
|
|
938
|
+
409,
|
|
939
|
+
"hosted_admission_unavailable",
|
|
940
|
+
"The hosted admission token has no owner turn in flight.",
|
|
941
|
+
),
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
if (execution.mode === "start") {
|
|
945
|
+
return finish(
|
|
946
|
+
Response.json({
|
|
947
|
+
ok: true,
|
|
948
|
+
v: HOSTED_DELIVERY_PROTOCOL_VERSION,
|
|
949
|
+
outcome: "started",
|
|
950
|
+
}),
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
return finish(
|
|
954
|
+
Response.json({
|
|
955
|
+
ok: true,
|
|
956
|
+
v: HOSTED_DELIVERY_PROTOCOL_VERSION,
|
|
957
|
+
outcome: "running",
|
|
958
|
+
}),
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
|
|
770
962
|
admitted.sessionPublicId = execution.sessionPublicId;
|
|
771
963
|
|
|
772
964
|
if (execution.mode === "enqueue") {
|
|
965
|
+
const network = await finishNetworkWait("execution");
|
|
966
|
+
guestNetwork = network.timing;
|
|
967
|
+
if (network.response !== undefined) {
|
|
968
|
+
return finish(network.response);
|
|
969
|
+
}
|
|
773
970
|
const enqueueOutcome = await enqueueIntoActiveOwner({
|
|
774
971
|
activeOwners,
|
|
775
972
|
sessionPublicId: execution.sessionPublicId,
|
|
@@ -786,198 +983,259 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
786
983
|
);
|
|
787
984
|
}
|
|
788
985
|
|
|
789
|
-
admitted.execution
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
986
|
+
if (admitted.execution === undefined) {
|
|
987
|
+
admitted.expiresAt = Date.now() + ownerTurnPendingTtlMs;
|
|
988
|
+
}
|
|
989
|
+
admitted.execution ??= afterHostedWork(
|
|
990
|
+
input.flushOtel,
|
|
991
|
+
async (): Promise<ExecutionReply> => {
|
|
992
|
+
const network = await finishNetworkWait("execution");
|
|
993
|
+
guestNetwork = network.timing;
|
|
994
|
+
if (network.response !== undefined) {
|
|
995
|
+
return await responseToReply(finish(network.response));
|
|
996
|
+
}
|
|
997
|
+
const startedAt = performance.now();
|
|
998
|
+
const executionId = hostedExecutionDiagId(execution.admissionToken);
|
|
999
|
+
const sinks: HostedExecutionFlushSinks = {
|
|
1000
|
+
...(input.stateRoot === undefined ? {} : { stateRoot: input.stateRoot }),
|
|
1001
|
+
...(input.persistSessionRun === undefined
|
|
1002
|
+
? {}
|
|
1003
|
+
: { persistSessionRun: input.persistSessionRun }),
|
|
1004
|
+
...(input.flushStartLog === undefined ? {} : { flushStartLog: input.flushStartLog }),
|
|
1005
|
+
...(input.snapshotLogs === undefined ? {} : { snapshotLogs: input.snapshotLogs }),
|
|
1006
|
+
};
|
|
1007
|
+
const writeDiag = async (fields: {
|
|
1008
|
+
sessionId: string;
|
|
1009
|
+
turnStatus: string;
|
|
1010
|
+
message?: string;
|
|
1011
|
+
abortReason?: ReturnType<typeof abortReasonFromTurnStatus> | "execute_throw";
|
|
1012
|
+
failureCode?: string;
|
|
1013
|
+
errorCode?: string;
|
|
1014
|
+
error?: unknown;
|
|
1015
|
+
}): Promise<void> => {
|
|
1016
|
+
const classification =
|
|
1017
|
+
fields.failureCode === undefined
|
|
1018
|
+
? undefined
|
|
1019
|
+
: hostedFailureClassification(fields.failureCode);
|
|
1020
|
+
await flushHostedExecutionRecord(sinks, {
|
|
1021
|
+
executionId,
|
|
1022
|
+
sessionPublicId: execution.sessionPublicId,
|
|
1023
|
+
sessionId: fields.sessionId,
|
|
1024
|
+
turnStatus: fields.turnStatus,
|
|
1025
|
+
durationMs: Math.max(0, Math.round(performance.now() - startedAt)),
|
|
1026
|
+
...(fields.message === undefined ? {} : { message: fields.message }),
|
|
1027
|
+
...(fields.abortReason === undefined ? {} : { abortReason: fields.abortReason }),
|
|
1028
|
+
failureCode: fields.failureCode,
|
|
1029
|
+
...(fields.errorCode === undefined ? {} : { errorCode: fields.errorCode }),
|
|
1030
|
+
classification,
|
|
1031
|
+
...(fields.error === undefined ? {} : { error: fields.error }),
|
|
1032
|
+
});
|
|
1033
|
+
};
|
|
1034
|
+
// Claim the file before the turn runs. If a later status request
|
|
1035
|
+
// fails, the host reads this record while the turn may still be
|
|
1036
|
+
// running; the marker prevents it from surfacing the previous
|
|
1037
|
+
// delivery's terminal record.
|
|
1038
|
+
await writeDiag({
|
|
1039
|
+
sessionId: "",
|
|
1040
|
+
turnStatus: HOSTED_EXECUTION_DIAG_RUNNING_STATUS,
|
|
825
1041
|
});
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
return await runWithHostedExecutionLatency(
|
|
845
|
-
{ channelKind: admitted.channelKind },
|
|
846
|
-
async () => {
|
|
847
|
-
let completionAt: number | undefined;
|
|
848
|
-
let drainAt: number | undefined;
|
|
849
|
-
try {
|
|
850
|
-
const args = input.buildHandlerArgs(
|
|
851
|
-
admitted.send.channelId,
|
|
852
|
-
execution.sessionPublicId,
|
|
853
|
-
);
|
|
854
|
-
const session = await args.send(admitted.send.message, {
|
|
855
|
-
...admitted.send.options,
|
|
856
|
-
mailboxContinuation: {
|
|
857
|
-
key: admitted.send.mailboxContinuationKey,
|
|
858
|
-
},
|
|
859
|
-
});
|
|
860
|
-
sessionId = session.id;
|
|
861
|
-
// The pre-turn claim used an empty sessionId. Stamp the
|
|
862
|
-
// engine id now so a dashboard / session-view poll that
|
|
863
|
-
// only has the factory `ses_…` can follow `session-events/`.
|
|
864
|
-
await writeDiag({
|
|
865
|
-
sessionId,
|
|
866
|
-
turnStatus: HOSTED_EXECUTION_DIAG_RUNNING_STATUS,
|
|
867
|
-
});
|
|
868
|
-
const outcome = await session.waitForCompletion();
|
|
869
|
-
completionAt = hostedExecutionNow();
|
|
870
|
-
// Status is the owner turn. waitForCompletion still waited
|
|
871
|
-
// for any drained successor so this process is not parked
|
|
872
|
-
// mid-follow-up; a successor failure must not 503-retry the
|
|
873
|
-
// owner after satellites already ran.
|
|
874
|
-
// Close acceptance at the turn boundary, before durability
|
|
875
|
-
// work creates an idle-but-still-addressable window.
|
|
876
|
-
owner.accepting = false;
|
|
877
|
-
if (owner.inflightInjects.size > 0) {
|
|
878
|
-
await Promise.allSettled([...owner.inflightInjects]);
|
|
879
|
-
}
|
|
880
|
-
// Failed turns drain too: their record/continuation updates must
|
|
881
|
-
// survive the park just like a finished turn's.
|
|
882
|
-
await input.drainSessionDurability?.(session.id);
|
|
883
|
-
drainAt = hostedExecutionNow();
|
|
884
|
-
const consumedDeliveryIds = [owner.primaryDeliveryId, ...owner.acceptedDeliveryIds];
|
|
885
|
-
if (consumedDeliveryIds.length > HOSTED_MAX_CONSUMED_DELIVERY_IDS) {
|
|
886
|
-
throw new Error(
|
|
887
|
-
`hosted execute consumedDeliveryIds length ${String(consumedDeliveryIds.length)} exceeds cap ${String(HOSTED_MAX_CONSUMED_DELIVERY_IDS)}`,
|
|
1042
|
+
let sessionId = "";
|
|
1043
|
+
const owner: ActiveOwnerContext = {
|
|
1044
|
+
primaryDeliveryId: admitted.deliveryId,
|
|
1045
|
+
acceptedDeliveryIds: [],
|
|
1046
|
+
accepting: true,
|
|
1047
|
+
inflightInjects: new Set(),
|
|
1048
|
+
enqueueResults: new Map(),
|
|
1049
|
+
};
|
|
1050
|
+
activeOwners.set(execution.sessionPublicId, owner);
|
|
1051
|
+
return await runWithHostedExecutionLatency(
|
|
1052
|
+
{ channelKind: admitted.channelKind },
|
|
1053
|
+
async () => {
|
|
1054
|
+
let completionAt: number | undefined;
|
|
1055
|
+
let drainAt: number | undefined;
|
|
1056
|
+
try {
|
|
1057
|
+
const args = input.buildHandlerArgs(
|
|
1058
|
+
admitted.send.channelId,
|
|
1059
|
+
execution.sessionPublicId,
|
|
888
1060
|
);
|
|
1061
|
+
const session = await args.send(admitted.send.message, {
|
|
1062
|
+
...admitted.send.options,
|
|
1063
|
+
mailboxContinuation: {
|
|
1064
|
+
key: admitted.send.mailboxContinuationKey,
|
|
1065
|
+
},
|
|
1066
|
+
});
|
|
1067
|
+
sessionId = session.id;
|
|
1068
|
+
// The pre-turn claim used an empty sessionId. Stamp the
|
|
1069
|
+
// engine id now so a dashboard / session-view poll that
|
|
1070
|
+
// only has the factory `ses_…` can follow `session-events/`.
|
|
1071
|
+
await writeDiag({
|
|
1072
|
+
sessionId,
|
|
1073
|
+
turnStatus: HOSTED_EXECUTION_DIAG_RUNNING_STATUS,
|
|
1074
|
+
});
|
|
1075
|
+
const outcome = await session.waitForCompletion();
|
|
1076
|
+
completionAt = hostedExecutionNow();
|
|
1077
|
+
// Status is the owner turn. waitForCompletion still waited
|
|
1078
|
+
// for any drained successor so this process is not parked
|
|
1079
|
+
// mid-follow-up; a successor failure must not 503-retry the
|
|
1080
|
+
// owner after satellites already ran.
|
|
1081
|
+
// Close acceptance at the turn boundary, before durability
|
|
1082
|
+
// work creates an idle-but-still-addressable window.
|
|
1083
|
+
owner.accepting = false;
|
|
1084
|
+
if (owner.inflightInjects.size > 0) {
|
|
1085
|
+
await Promise.allSettled([...owner.inflightInjects]);
|
|
1086
|
+
}
|
|
1087
|
+
// Failed turns drain too: their record/continuation updates must
|
|
1088
|
+
// survive the park just like a finished turn's.
|
|
1089
|
+
await input.drainSessionDurability?.(session.id);
|
|
1090
|
+
drainAt = hostedExecutionNow();
|
|
1091
|
+
const consumedDeliveryIds = [
|
|
1092
|
+
owner.primaryDeliveryId,
|
|
1093
|
+
...owner.acceptedDeliveryIds,
|
|
1094
|
+
];
|
|
1095
|
+
if (consumedDeliveryIds.length > HOSTED_MAX_CONSUMED_DELIVERY_IDS) {
|
|
1096
|
+
throw new Error(
|
|
1097
|
+
`hosted execute consumedDeliveryIds length ${String(consumedDeliveryIds.length)} exceeds cap ${String(HOSTED_MAX_CONSUMED_DELIVERY_IDS)}`,
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
// Evict before the reply: TAS parks and hibernates this process
|
|
1101
|
+
// as soon as the POST returns. A leftover SDK handle freezes a
|
|
1102
|
+
// dead Connect/HTTP2 session that the next wake then reuses.
|
|
1103
|
+
evictHostedSdkSessions(
|
|
1104
|
+
input.evictSdkSession,
|
|
1105
|
+
session.id,
|
|
1106
|
+
execution.sessionPublicId,
|
|
1107
|
+
);
|
|
1108
|
+
const hostedFailure =
|
|
1109
|
+
outcome.status === "finished"
|
|
1110
|
+
? undefined
|
|
1111
|
+
: hostedFailureForUnfinishedTurn(outcome);
|
|
1112
|
+
await writeDiag({
|
|
1113
|
+
sessionId: session.id,
|
|
1114
|
+
turnStatus: outcome.status,
|
|
1115
|
+
message: outcome.errorMessage,
|
|
1116
|
+
abortReason: abortReasonFromTurnStatus(
|
|
1117
|
+
outcome.status,
|
|
1118
|
+
outcome.cancellationReason,
|
|
1119
|
+
),
|
|
1120
|
+
failureCode: hostedFailure?.error,
|
|
1121
|
+
...(outcome.errorCode === undefined ? {} : { errorCode: outcome.errorCode }),
|
|
1122
|
+
});
|
|
1123
|
+
const reply =
|
|
1124
|
+
hostedFailure !== undefined
|
|
1125
|
+
? {
|
|
1126
|
+
status: 503,
|
|
1127
|
+
body: {
|
|
1128
|
+
ok: false,
|
|
1129
|
+
error: hostedFailure.error,
|
|
1130
|
+
retry: hostedFailure.retry,
|
|
1131
|
+
classification: hostedFailureClassification(hostedFailure.error),
|
|
1132
|
+
turnStatus: outcome.status,
|
|
1133
|
+
message: outcome.errorMessage,
|
|
1134
|
+
...(outcome.errorCode === undefined
|
|
1135
|
+
? {}
|
|
1136
|
+
: { errorCode: outcome.errorCode }),
|
|
1137
|
+
},
|
|
1138
|
+
}
|
|
1139
|
+
: {
|
|
1140
|
+
status: 200,
|
|
1141
|
+
body: {
|
|
1142
|
+
ok: true,
|
|
1143
|
+
v: HOSTED_DELIVERY_PROTOCOL_VERSION,
|
|
1144
|
+
outcome: "send",
|
|
1145
|
+
consumedDeliveryIds,
|
|
1146
|
+
},
|
|
1147
|
+
};
|
|
1148
|
+
// Finalize as late as possible so `post_drain` and `total`
|
|
1149
|
+
// include eviction + diag write after durability drain.
|
|
1150
|
+
latencySnapshot = finalizeHostedExecutionLatency({
|
|
1151
|
+
completionAt,
|
|
1152
|
+
drainAt,
|
|
1153
|
+
endedAt: hostedExecutionNow(),
|
|
1154
|
+
});
|
|
1155
|
+
return await responseToReply(
|
|
1156
|
+
finish(Response.json(reply.body, { status: reply.status })),
|
|
1157
|
+
);
|
|
1158
|
+
} catch (error) {
|
|
1159
|
+
owner.accepting = false;
|
|
1160
|
+
if (owner.inflightInjects.size > 0) {
|
|
1161
|
+
await Promise.allSettled([...owner.inflightInjects]);
|
|
1162
|
+
}
|
|
1163
|
+
evictHostedSdkSessions(
|
|
1164
|
+
input.evictSdkSession,
|
|
1165
|
+
sessionId,
|
|
1166
|
+
execution.sessionPublicId,
|
|
1167
|
+
);
|
|
1168
|
+
const thrownErrorCode = describeErrorCode(error);
|
|
1169
|
+
await writeDiag({
|
|
1170
|
+
sessionId: "",
|
|
1171
|
+
turnStatus: "error",
|
|
1172
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1173
|
+
abortReason: "execute_throw",
|
|
1174
|
+
failureCode: "internal_error",
|
|
1175
|
+
error,
|
|
1176
|
+
...(thrownErrorCode === undefined ? {} : { errorCode: thrownErrorCode }),
|
|
1177
|
+
});
|
|
1178
|
+
const endedAt = hostedExecutionNow();
|
|
1179
|
+
// Preserve completion/drain marks when the failure happened
|
|
1180
|
+
// during post-drain work; otherwise collapse to endedAt.
|
|
1181
|
+
latencySnapshot = finalizeHostedExecutionLatency({
|
|
1182
|
+
completionAt: completionAt ?? endedAt,
|
|
1183
|
+
drainAt: drainAt ?? endedAt,
|
|
1184
|
+
endedAt,
|
|
1185
|
+
});
|
|
1186
|
+
throw error;
|
|
1187
|
+
} finally {
|
|
1188
|
+
if (activeOwners.get(execution.sessionPublicId) === owner) {
|
|
1189
|
+
activeOwners.delete(execution.sessionPublicId);
|
|
1190
|
+
}
|
|
889
1191
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
}
|
|
929
|
-
: {
|
|
930
|
-
status: 200,
|
|
931
|
-
body: {
|
|
932
|
-
ok: true,
|
|
933
|
-
v: HOSTED_DELIVERY_PROTOCOL_VERSION,
|
|
934
|
-
outcome: "send",
|
|
935
|
-
consumedDeliveryIds,
|
|
936
|
-
},
|
|
937
|
-
};
|
|
938
|
-
// Finalize as late as possible so `post_drain` and `total`
|
|
939
|
-
// include eviction + diag write after durability drain.
|
|
940
|
-
latencySnapshot = finalizeHostedExecutionLatency({
|
|
941
|
-
completionAt,
|
|
942
|
-
drainAt,
|
|
943
|
-
endedAt: hostedExecutionNow(),
|
|
944
|
-
});
|
|
945
|
-
return reply;
|
|
946
|
-
} catch (error) {
|
|
947
|
-
owner.accepting = false;
|
|
948
|
-
if (owner.inflightInjects.size > 0) {
|
|
949
|
-
await Promise.allSettled([...owner.inflightInjects]);
|
|
950
|
-
}
|
|
951
|
-
evictHostedSdkSessions(input.evictSdkSession, sessionId, execution.sessionPublicId);
|
|
952
|
-
const thrownErrorCode = describeErrorCode(error);
|
|
953
|
-
await writeDiag({
|
|
954
|
-
sessionId: "",
|
|
955
|
-
turnStatus: "error",
|
|
956
|
-
message: error instanceof Error ? error.message : String(error),
|
|
957
|
-
abortReason: "execute_throw",
|
|
958
|
-
failureCode: "internal_error",
|
|
959
|
-
error,
|
|
960
|
-
...(thrownErrorCode === undefined ? {} : { errorCode: thrownErrorCode }),
|
|
961
|
-
});
|
|
962
|
-
const endedAt = hostedExecutionNow();
|
|
963
|
-
// Preserve completion/drain marks when the failure happened
|
|
964
|
-
// during post-drain work; otherwise collapse to endedAt.
|
|
965
|
-
latencySnapshot = finalizeHostedExecutionLatency({
|
|
966
|
-
completionAt: completionAt ?? endedAt,
|
|
967
|
-
drainAt: drainAt ?? endedAt,
|
|
968
|
-
endedAt,
|
|
969
|
-
});
|
|
970
|
-
throw error;
|
|
971
|
-
} finally {
|
|
972
|
-
if (activeOwners.get(execution.sessionPublicId) === owner) {
|
|
973
|
-
activeOwners.delete(execution.sessionPublicId);
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
},
|
|
1192
|
+
},
|
|
1193
|
+
);
|
|
1194
|
+
},
|
|
1195
|
+
).then(
|
|
1196
|
+
reply => {
|
|
1197
|
+
admitted.settledReply = reply;
|
|
1198
|
+
admitted.expiresAt = Date.now() + pendingTtlMs;
|
|
1199
|
+
return reply;
|
|
1200
|
+
},
|
|
1201
|
+
error => {
|
|
1202
|
+
admitted.settledReply = {
|
|
1203
|
+
status: 503,
|
|
1204
|
+
body: {
|
|
1205
|
+
ok: false,
|
|
1206
|
+
error: "internal_error",
|
|
1207
|
+
retry: HOSTED_GUEST_RETRY_TERMINAL,
|
|
1208
|
+
classification: hostedFailureClassification("internal_error"),
|
|
1209
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1210
|
+
},
|
|
1211
|
+
};
|
|
1212
|
+
admitted.expiresAt = Date.now() + pendingTtlMs;
|
|
1213
|
+
return admitted.settledReply;
|
|
1214
|
+
},
|
|
1215
|
+
);
|
|
1216
|
+
if (execution.mode === "start") {
|
|
1217
|
+
const quickReply = await Promise.race([
|
|
1218
|
+
admitted.execution,
|
|
1219
|
+
new Promise<undefined>(resolve => setImmediate(() => resolve(undefined))),
|
|
1220
|
+
]);
|
|
1221
|
+
if (quickReply !== undefined) {
|
|
1222
|
+
return responseFromReply(quickReply);
|
|
1223
|
+
}
|
|
1224
|
+
return finish(
|
|
1225
|
+
Response.json({
|
|
1226
|
+
ok: true,
|
|
1227
|
+
v: HOSTED_DELIVERY_PROTOCOL_VERSION,
|
|
1228
|
+
outcome: "started",
|
|
1229
|
+
}),
|
|
977
1230
|
);
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
|
|
1231
|
+
}
|
|
1232
|
+
return finish(
|
|
1233
|
+
terminalHostedError(
|
|
1234
|
+
400,
|
|
1235
|
+
"invalid_hosted_execution",
|
|
1236
|
+
"Owner execution requires start or status mode.",
|
|
1237
|
+
),
|
|
1238
|
+
);
|
|
981
1239
|
}),
|
|
982
1240
|
});
|
|
983
1241
|
}
|