@cursor/july 0.1.97 → 0.1.100
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 +5 -3
- package/dist/bin/agent-serve.js +6 -7
- package/dist/channels/github/defaults.d.ts.map +1 -1
- package/dist/channels/github/defaults.js +28 -3
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +16 -0
- package/dist/channels/github/progress.d.ts +7 -0
- package/dist/channels/github/progress.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.d.ts +2 -0
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +37 -4
- package/dist/channels/slack/api.d.ts +16 -7
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +29 -13
- package/dist/channels/slack/constants.d.ts +6 -0
- package/dist/channels/slack/constants.d.ts.map +1 -1
- package/dist/channels/slack/constants.js +6 -0
- package/dist/channels/slack/defaults.d.ts +9 -4
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +221 -122
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +3 -3
- package/dist/channels/slack/inbound.d.ts +9 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +14 -0
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/live-delivery.d.ts +6 -1
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +110 -20
- package/dist/channels/slack/progress-delivery.d.ts +28 -0
- package/dist/channels/slack/progress-delivery.d.ts.map +1 -0
- package/dist/channels/slack/progress-delivery.js +115 -0
- package/dist/channels/slack/reasoning-card.d.ts +38 -0
- package/dist/channels/slack/reasoning-card.d.ts.map +1 -0
- package/dist/channels/slack/reasoning-card.js +104 -0
- package/dist/channels/slack/redact.d.ts +2 -0
- package/dist/channels/slack/redact.d.ts.map +1 -0
- package/dist/channels/slack/redact.js +5 -0
- package/dist/channels/slack/reply-options.d.ts +40 -0
- package/dist/channels/slack/reply-options.d.ts.map +1 -0
- package/dist/channels/slack/reply-options.js +150 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +8 -4
- package/dist/channels/slack/stream.d.ts +22 -10
- package/dist/channels/slack/stream.d.ts.map +1 -1
- package/dist/channels/slack/stream.js +9 -16
- package/dist/channels/slack/tool-cards.d.ts +22 -0
- package/dist/channels/slack/tool-cards.d.ts.map +1 -0
- package/dist/channels/slack/tool-cards.js +178 -0
- package/dist/channels/slack/types.d.ts +154 -7
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +6 -6
- package/dist/docs/ab.md +1 -1
- package/dist/docs/assets/{ab.md.DJo5r4R-.js → ab.md.mlVgqvSk.js} +1 -1
- package/dist/docs/assets/{app.B3rWNYE1.js → app.DZ1e0Ycq.js} +1 -1
- package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.js → building-with-agents.md.CUSWxlP_.js} +2 -2
- package/dist/docs/assets/chunks/@localSearchIndexroot.j70vvPL4.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.C1lhqJJR.js → VPLocalSearchBox.l8omwc6D.js} +1 -1
- package/dist/docs/assets/chunks/{theme.B40_SXuv.js → theme.JVcD6gel.js} +2 -2
- package/dist/docs/assets/{evals.md.lfJoEVc8.js → evals.md.CPzDAwoH.js} +1 -1
- package/dist/docs/assets/{guides_github.md.Cnh2mL4a.js → guides_github.md.BtPr9GaP.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.js → guides_mcp-oauth.md.Dp6cDP7f.js} +1 -1
- package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.js → guides_opentelemetry.md.BVTXDCRg.js} +2 -2
- package/dist/docs/assets/{guides_slack.md.VDXQV3ja.js → guides_slack.md.9oHPye9o.js} +19 -3
- package/dist/docs/assets/{guides_slack.md.VDXQV3ja.lean.js → guides_slack.md.9oHPye9o.lean.js} +1 -1
- package/dist/docs/assets/hillclimbing.md.CpTGTCle.js +4 -0
- package/dist/docs/assets/{index.md.CVeRUOeZ.js → index.md.Bb4k8kUm.js} +1 -1
- package/dist/docs/assets/{quickstart.md.Nj_LjW_a.js → quickstart.md.DdQOF7Y8.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.RyZf5OTE.js → reference_cli.md.DfoeyvL0.js} +4 -4
- package/dist/docs/assets/{reference_cli.md.RyZf5OTE.lean.js → reference_cli.md.DfoeyvL0.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.DxldvyIB.js → reference_connections.md.BiGoBAk2.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.5zOAbV86.js → reference_http-api.md.BEJx9XVj.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.B84gw9Ii.js → reference_tools.md.CvAHsdSp.js} +10 -2
- package/dist/docs/assets/{reference_tools.md.B84gw9Ii.lean.js → reference_tools.md.CvAHsdSp.lean.js} +1 -1
- package/dist/docs/assets/scaffolding-agents.md.em43xlY1.js +1 -0
- package/dist/docs/assets/skills_ab.md.CsFNatVx.js +26 -0
- package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +1 -0
- package/dist/docs/assets/skills_create-agent.md.BVoWPcan.js +8 -0
- package/dist/docs/assets/skills_create-agent.md.BVoWPcan.lean.js +1 -0
- package/dist/docs/assets/skills_debug.md.CDbPhHfg.js +1 -0
- package/dist/docs/assets/skills_debug.md.CDbPhHfg.lean.js +1 -0
- package/dist/docs/assets/skills_evals.md.723kpUmA.js +25 -0
- package/dist/docs/assets/skills_evals.md.723kpUmA.lean.js +1 -0
- package/dist/docs/assets/skills_framework-map.md.BTi817yv.js +1 -0
- package/dist/docs/assets/skills_framework-map.md.BTi817yv.lean.js +1 -0
- package/dist/docs/assets/skills_github.md.D0JahM8c.js +16 -0
- package/dist/docs/assets/skills_github.md.D0JahM8c.lean.js +1 -0
- package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.js +7 -0
- package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.lean.js +1 -0
- package/dist/docs/assets/skills_index.md.DKwIxzGg.js +1 -0
- package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +1 -0
- package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.js +18 -0
- package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.lean.js +1 -0
- package/dist/docs/assets/skills_otel.md.CgiZryR3.js +8 -0
- package/dist/docs/assets/skills_otel.md.CgiZryR3.lean.js +1 -0
- package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.js +20 -0
- package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.lean.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.js → troubleshooting.md.Cus_YZga.js} +1 -1
- package/dist/docs/building-with-agents.html +6 -6
- package/dist/docs/building-with-agents.md +14 -11
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +4 -4
- package/dist/docs/design/runtime-abstraction.md +1757 -0
- package/dist/docs/evals.html +6 -6
- package/dist/docs/evals.md +1 -1
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +5 -5
- package/dist/docs/guides/github.md +1 -1
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +5 -5
- package/dist/docs/guides/mcp-oauth.md +1 -1
- package/dist/docs/guides/opentelemetry.html +7 -7
- package/dist/docs/guides/opentelemetry.md +2 -2
- package/dist/docs/guides/slack.html +22 -6
- package/dist/docs/guides/slack.md +80 -1
- package/dist/docs/guides/webhooks.html +5 -5
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +6 -6
- package/dist/docs/hillclimbing.md +5 -5
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +1 -1
- package/dist/docs/llms-full.txt +2830 -37
- package/dist/docs/llms.txt +15 -0
- package/dist/docs/quickstart.html +5 -5
- package/dist/docs/quickstart.md +1 -1
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +7 -7
- package/dist/docs/reference/cli.md +1 -7
- package/dist/docs/reference/connections.html +6 -6
- package/dist/docs/reference/connections.md +1 -1
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +1 -0
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +14 -6
- package/dist/docs/reference/tools.md +25 -0
- package/dist/docs/scaffolding-agents.html +5 -5
- package/dist/docs/scaffolding-agents.md +3 -3
- package/dist/docs/skills/ab.html +52 -0
- package/dist/docs/skills/ab.md +50 -0
- package/dist/docs/skills/create-agent.html +34 -0
- package/dist/docs/skills/create-agent.md +160 -0
- package/dist/docs/skills/debug.html +27 -0
- package/dist/docs/skills/debug.md +36 -0
- package/dist/docs/skills/evals.html +51 -0
- package/dist/docs/skills/evals.md +99 -0
- package/dist/docs/skills/framework-map.html +27 -0
- package/dist/docs/skills/framework-map.md +95 -0
- package/dist/docs/skills/github.html +42 -0
- package/dist/docs/skills/github.md +93 -0
- package/dist/docs/skills/hillclimb.html +33 -0
- package/dist/docs/skills/hillclimb.md +55 -0
- package/dist/docs/skills/index.html +27 -0
- package/dist/docs/skills/index.md +21 -0
- package/dist/docs/skills/mcp-auth.html +44 -0
- package/dist/docs/skills/mcp-auth.md +76 -0
- package/dist/docs/skills/otel.html +34 -0
- package/dist/docs/skills/otel.md +48 -0
- package/dist/docs/skills/setup-slack.html +46 -0
- package/dist/docs/skills/setup-slack.md +141 -0
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +4 -4
- package/dist/docs/templates/code-wiki.html +4 -4
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +4 -4
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +1 -1
- package/dist/files-backends/cursor-hosted.d.ts +9 -2
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +9 -11
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/as-of.d.ts +19 -0
- package/dist/internal/as-of.d.ts.map +1 -0
- package/dist/internal/as-of.js +82 -0
- package/dist/internal/cli-deploy.d.ts +2 -1
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +102 -7
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +3 -4
- package/dist/internal/cursor/hosted-store-secrets.d.ts +15 -0
- package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -0
- package/dist/internal/cursor/hosted-store-secrets.js +48 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -1
- package/dist/internal/cursor-event-relay.js +5 -6
- package/dist/internal/deploy-client.d.ts +6 -6
- package/dist/internal/deploy-client.js +7 -7
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +11 -1
- package/dist/internal/framework-file-storage.d.ts +5 -4
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +6 -4
- package/dist/internal/framework-storage-selection.d.ts +13 -11
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +28 -23
- package/dist/internal/hosted-admission-adapter.d.ts +28 -0
- package/dist/internal/hosted-admission-adapter.d.ts.map +1 -0
- package/dist/internal/hosted-admission-adapter.js +7 -0
- package/dist/internal/hosted-delivery-protocol.d.ts +6 -1
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +1 -1
- package/dist/internal/hosted-delivery.d.ts +15 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +47 -21
- package/dist/internal/hosted-execution-diag.d.ts +11 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
- package/dist/internal/hosted-execution-diag.js +39 -2
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +4 -1
- package/dist/internal/server.d.ts +3 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +82 -19
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +24 -4
- package/dist/internal/session-run-log.d.ts +120 -0
- package/dist/internal/session-run-log.d.ts.map +1 -0
- package/dist/internal/session-run-log.js +358 -0
- package/dist/internal/tool-policy.d.ts +20 -8
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +11 -0
- package/dist/playground/assets/index-BszoQDc6.css +1 -0
- package/dist/playground/assets/index-DVs98vPL.js +69 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted-v2.d.ts +83 -0
- package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -0
- package/dist/storage-backends/cursor-hosted-v2.js +164 -0
- package/dist/storage-backends/cursor-hosted.d.ts +6 -0
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +6 -1
- package/dist/storage-protocol.d.ts +8 -0
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +8 -0
- package/dist/tools.d.ts +12 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +1 -1
- package/docs/ab.md +1 -1
- package/docs/building-with-agents.md +14 -11
- package/docs/design/runtime-abstraction.md +1757 -0
- package/docs/evals.md +1 -1
- package/docs/guides/github.md +1 -1
- package/docs/guides/mcp-oauth.md +1 -1
- package/docs/guides/opentelemetry.md +2 -2
- package/docs/guides/slack.md +80 -1
- package/docs/hillclimbing.md +5 -5
- package/docs/quickstart.md +1 -1
- package/docs/reference/cli.md +1 -7
- package/docs/reference/connections.md +1 -1
- package/docs/reference/http-api.md +1 -0
- package/docs/reference/tools.md +25 -0
- package/docs/scaffolding-agents.md +3 -3
- package/docs/skills/index.md +26 -0
- package/docs/troubleshooting.md +1 -1
- package/package.json +1 -1
- package/src/bin/agent-serve.ts +6 -7
- package/src/channels/github/defaults.ts +36 -3
- package/src/channels/github/github-channel.ts +17 -0
- package/src/channels/github/progress.ts +7 -0
- package/src/channels/origin/origin-channel.ts +74 -10
- package/src/channels/slack/api.ts +35 -17
- package/src/channels/slack/constants.ts +6 -0
- package/src/channels/slack/defaults.ts +253 -144
- package/src/channels/slack/dispatch.ts +10 -1
- package/src/channels/slack/inbound.ts +17 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/live-delivery.ts +135 -22
- package/src/channels/slack/progress-delivery.ts +133 -0
- package/src/channels/slack/reasoning-card.ts +140 -0
- package/src/channels/slack/redact.ts +6 -0
- package/src/channels/slack/reply-options.ts +229 -0
- package/src/channels/slack/slack-channel.ts +7 -2
- package/src/channels/slack/stream.ts +31 -24
- package/src/channels/slack/tool-cards.ts +221 -0
- package/src/channels/slack/types.ts +168 -7
- package/src/files-backends/cursor-hosted.ts +18 -7
- package/src/index.ts +4 -0
- package/src/internal/as-of.ts +107 -0
- package/src/internal/cli-deploy.ts +130 -10
- package/src/internal/conversation-mirror.ts +3 -8
- package/src/internal/cursor/hosted-store-secrets.ts +72 -0
- package/src/internal/cursor-event-relay.ts +5 -6
- package/src/internal/deploy-client.ts +10 -10
- package/src/internal/discovery.ts +9 -1
- package/src/internal/framework-file-storage.ts +6 -4
- package/src/internal/framework-storage-selection.ts +28 -25
- package/src/internal/hosted-admission-adapter.ts +42 -0
- package/src/internal/hosted-delivery-protocol.ts +7 -2
- package/src/internal/hosted-delivery.ts +88 -36
- package/src/internal/hosted-execution-diag.ts +45 -0
- package/src/internal/http-channel.ts +8 -0
- package/src/internal/server.ts +100 -2
- package/src/internal/session-engine.ts +32 -1
- package/src/internal/session-run-log.ts +579 -0
- package/src/internal/tool-policy.ts +31 -9
- package/src/storage-backends/cursor-hosted-v2.ts +219 -0
- package/src/storage-backends/cursor-hosted.ts +6 -1
- package/src/storage-protocol.ts +10 -0
- package/src/tools.ts +12 -2
- package/src/types.ts +30 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.BU9nHdnQ.js +0 -1
- package/dist/docs/assets/hillclimbing.md.DhESf3OO.js +0 -4
- package/dist/docs/assets/scaffolding-agents.md.D7UUkWw0.js +0 -1
- package/dist/playground/assets/index-DrkI6y5O.js +0 -88
- package/dist/playground/assets/index-DzNGwm7q.css +0 -1
- /package/dist/docs/assets/{ab.md.DJo5r4R-.lean.js → ab.md.mlVgqvSk.lean.js} +0 -0
- /package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.lean.js → building-with-agents.md.CUSWxlP_.lean.js} +0 -0
- /package/dist/docs/assets/{evals.md.lfJoEVc8.lean.js → evals.md.CPzDAwoH.lean.js} +0 -0
- /package/dist/docs/assets/{guides_github.md.Cnh2mL4a.lean.js → guides_github.md.BtPr9GaP.lean.js} +0 -0
- /package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.lean.js → guides_mcp-oauth.md.Dp6cDP7f.lean.js} +0 -0
- /package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.lean.js → guides_opentelemetry.md.BVTXDCRg.lean.js} +0 -0
- /package/dist/docs/assets/{hillclimbing.md.DhESf3OO.lean.js → hillclimbing.md.CpTGTCle.lean.js} +0 -0
- /package/dist/docs/assets/{index.md.CVeRUOeZ.lean.js → index.md.Bb4k8kUm.lean.js} +0 -0
- /package/dist/docs/assets/{quickstart.md.Nj_LjW_a.lean.js → quickstart.md.DdQOF7Y8.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.DxldvyIB.lean.js → reference_connections.md.BiGoBAk2.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.5zOAbV86.lean.js → reference_http-api.md.BEJx9XVj.lean.js} +0 -0
- /package/dist/docs/assets/{scaffolding-agents.md.D7UUkWw0.lean.js → scaffolding-agents.md.em43xlY1.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.lean.js → troubleshooting.md.Cus_YZga.lean.js} +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task-time bind paths for hosted deployment file-store source ids.
|
|
3
|
+
*
|
|
4
|
+
* Freeze v2 snapshots start `agent-serve serve` at bake time without a service
|
|
5
|
+
* account, so neither store id is in process env. Execute-from-freeze binds
|
|
6
|
+
* the deployment credential and store ids into `/run/cursor/secrets/` without
|
|
7
|
+
* restarting July — the same pattern as {@link DEFAULT_CURSOR_API_KEY_FILE}.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
|
|
12
|
+
export const DEFAULT_AGENT_SERVE_STORE_SOURCE_ID_FILE =
|
|
13
|
+
"/run/cursor/secrets/AGENT_SERVE_STORE_SOURCE_ID";
|
|
14
|
+
|
|
15
|
+
export const DEFAULT_AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID_FILE =
|
|
16
|
+
"/run/cursor/secrets/AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID";
|
|
17
|
+
|
|
18
|
+
const STORE_SOURCE_ID_ENV = "AGENT_SERVE_STORE_SOURCE_ID";
|
|
19
|
+
const FRAMEWORK_STORE_SOURCE_ID_ENV = "AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID";
|
|
20
|
+
const STORE_SOURCE_ID_FILE_ENV = "AGENT_SERVE_STORE_SOURCE_ID_FILE";
|
|
21
|
+
const FRAMEWORK_STORE_SOURCE_ID_FILE_ENV =
|
|
22
|
+
"AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID_FILE";
|
|
23
|
+
|
|
24
|
+
function readTrimmedFile(path: string): string | undefined {
|
|
25
|
+
try {
|
|
26
|
+
const raw = readFileSync(path, "utf8").trim();
|
|
27
|
+
return raw === "" ? undefined : raw;
|
|
28
|
+
} catch {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function readBoundSecretFile(
|
|
34
|
+
fileEnvVar: string,
|
|
35
|
+
defaultPath: string,
|
|
36
|
+
env: NodeJS.ProcessEnv
|
|
37
|
+
): string | undefined {
|
|
38
|
+
const configured = env[fileEnvVar]?.trim();
|
|
39
|
+
const path =
|
|
40
|
+
configured !== undefined && configured !== "" ? configured : defaultPath;
|
|
41
|
+
return readTrimmedFile(path);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Deployment user-land store: env, then task-bind file. */
|
|
45
|
+
export function resolveDeploymentStoreSourceIdSync(
|
|
46
|
+
env: NodeJS.ProcessEnv = process.env
|
|
47
|
+
): string | undefined {
|
|
48
|
+
const fromEnv = env[STORE_SOURCE_ID_ENV]?.trim();
|
|
49
|
+
if (fromEnv !== undefined && fromEnv !== "") {
|
|
50
|
+
return fromEnv;
|
|
51
|
+
}
|
|
52
|
+
return readBoundSecretFile(
|
|
53
|
+
STORE_SOURCE_ID_FILE_ENV,
|
|
54
|
+
DEFAULT_AGENT_SERVE_STORE_SOURCE_ID_FILE,
|
|
55
|
+
env
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Engine framework store: env, then task-bind file. */
|
|
60
|
+
export function resolveFrameworkStoreSourceIdSync(
|
|
61
|
+
env: NodeJS.ProcessEnv = process.env
|
|
62
|
+
): string | undefined {
|
|
63
|
+
const fromEnv = env[FRAMEWORK_STORE_SOURCE_ID_ENV]?.trim();
|
|
64
|
+
if (fromEnv !== undefined && fromEnv !== "") {
|
|
65
|
+
return fromEnv;
|
|
66
|
+
}
|
|
67
|
+
return readBoundSecretFile(
|
|
68
|
+
FRAMEWORK_STORE_SOURCE_ID_FILE_ENV,
|
|
69
|
+
DEFAULT_AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID_FILE,
|
|
70
|
+
env
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -616,12 +616,11 @@ export class CursorEventRelay {
|
|
|
616
616
|
events: [...subscription.events],
|
|
617
617
|
})),
|
|
618
618
|
}),
|
|
619
|
-
//
|
|
620
|
-
//
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
}),
|
|
619
|
+
// No deregistration on stop: the backend only records events for a
|
|
620
|
+
// repo that some consumer is subscribed to, so dropping the
|
|
621
|
+
// registration leaves a hole in the log until the next process
|
|
622
|
+
// registers, and the durable offset cannot replay what was never
|
|
623
|
+
// written. A consumer that does not come back lapses by TTL.
|
|
625
624
|
applyRegistrationResponse: (json) => {
|
|
626
625
|
const result = json as { repos?: SubscriptionStatus[] };
|
|
627
626
|
const statuses = result.repos ?? [];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Thin client for the Agent Serve deployment management API
|
|
3
3
|
* (`/internal/agent-serve/deployments` on the Cursor backend) and the v2
|
|
4
|
-
* AgentSDK accept path (`/internal/
|
|
4
|
+
* AgentSDK accept path (`/internal/agentsdk/deployments`). Pure
|
|
5
5
|
* request/response + error mapping — no console I/O, no polling loops;
|
|
6
6
|
* rendering lives in `cli-deploy.ts`.
|
|
7
7
|
*
|
|
@@ -214,7 +214,7 @@ export interface StopAccepted {
|
|
|
214
214
|
export type DeleteAccepted = StopAccepted;
|
|
215
215
|
|
|
216
216
|
/**
|
|
217
|
-
* `POST /internal/
|
|
217
|
+
* `POST /internal/agentsdk/deployments` 202 body. Distinct from v1
|
|
218
218
|
* {@link DeployAccepted}: the v2 control plane returns catalog ids, not
|
|
219
219
|
* an engine alias or one-shot alias token.
|
|
220
220
|
*/
|
|
@@ -234,7 +234,7 @@ export interface AgentkitDeployComponent {
|
|
|
234
234
|
agentPath?: string;
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
/** Customer-visible v2 deploy status (`GET /internal/
|
|
237
|
+
/** Customer-visible v2 deploy status (`GET /internal/agentsdk/deployments/:slug`). */
|
|
238
238
|
export type AgentkitCustomerStatus =
|
|
239
239
|
| "pending"
|
|
240
240
|
| "deploying"
|
|
@@ -273,7 +273,7 @@ export const TERMINAL_AGENTKIT_DEPLOY_STATUSES: ReadonlySet<AgentkitCustomerStat
|
|
|
273
273
|
new Set(["running", "failed", "stopped"]);
|
|
274
274
|
|
|
275
275
|
/**
|
|
276
|
-
* `POST /internal/
|
|
276
|
+
* `POST /internal/agentsdk/deployments/:slug/stop` 202 body. Like v1
|
|
277
277
|
* {@link StopAccepted} but keyed by catalog ids instead of the numeric
|
|
278
278
|
* deployment row id.
|
|
279
279
|
*/
|
|
@@ -594,7 +594,7 @@ export class AgentServeDeployClient {
|
|
|
594
594
|
|
|
595
595
|
/**
|
|
596
596
|
* Create or redeploy onto the v2 control plane
|
|
597
|
-
* (`POST /internal/
|
|
597
|
+
* (`POST /internal/agentsdk/deployments`). 202 means accepted; poll
|
|
598
598
|
* {@link getAgentkitDeploy} until a terminal status. `components` deploys
|
|
599
599
|
* one application with several release components (one per agent
|
|
600
600
|
* directory); it is mutually exclusive with `agentPath`.
|
|
@@ -625,7 +625,7 @@ export class AgentServeDeployClient {
|
|
|
625
625
|
}
|
|
626
626
|
const raw = await this.request({
|
|
627
627
|
method: "POST",
|
|
628
|
-
path: "/internal/
|
|
628
|
+
path: "/internal/agentsdk/deployments",
|
|
629
629
|
body: {
|
|
630
630
|
teamId: args.teamId,
|
|
631
631
|
slug: args.slug,
|
|
@@ -650,14 +650,14 @@ export class AgentServeDeployClient {
|
|
|
650
650
|
}): Promise<AgentkitDeployStatus> {
|
|
651
651
|
const raw = await this.request({
|
|
652
652
|
method: "GET",
|
|
653
|
-
path: `/internal/
|
|
653
|
+
path: `/internal/agentsdk/deployments/${encodeURIComponent(args.slug)}?teamId=${args.teamId}`,
|
|
654
654
|
context: { verb: "get deployment", slug: args.slug },
|
|
655
655
|
});
|
|
656
656
|
return agentkitDeployStatusSchema.parse(raw);
|
|
657
657
|
}
|
|
658
658
|
|
|
659
659
|
/**
|
|
660
|
-
* Stop a v2 deployment (`POST /internal/
|
|
660
|
+
* Stop a v2 deployment (`POST /internal/agentsdk/deployments/:slug/stop`).
|
|
661
661
|
* 202 means accepted; poll {@link getAgentkitDeploy} until `stopped`.
|
|
662
662
|
*/
|
|
663
663
|
async stopAgentkit(args: {
|
|
@@ -666,7 +666,7 @@ export class AgentServeDeployClient {
|
|
|
666
666
|
}): Promise<AgentkitStopAccepted> {
|
|
667
667
|
const raw = await this.request({
|
|
668
668
|
method: "POST",
|
|
669
|
-
path: `/internal/
|
|
669
|
+
path: `/internal/agentsdk/deployments/${encodeURIComponent(args.slug)}/stop?teamId=${args.teamId}`,
|
|
670
670
|
context: { verb: "stop", slug: args.slug },
|
|
671
671
|
});
|
|
672
672
|
return agentkitStopAcceptedSchema.parse(raw);
|
|
@@ -977,7 +977,7 @@ function mapErrorResponse(
|
|
|
977
977
|
// (api2 vs api.cursor.com), not a missing deployment / closed gate.
|
|
978
978
|
if (/Route \S+ not found/i.test(bodyText)) {
|
|
979
979
|
return new DeployApiError(
|
|
980
|
-
`Agent Serve deploy API not found on this host — use the default api.cursor.com (unset CURSOR_API_BASE_URL), or point CURSOR_API_BASE_URL at a backend that mounts /internal/agent-serve/* and /internal/
|
|
980
|
+
`Agent Serve deploy API not found on this host — use the default api.cursor.com (unset CURSOR_API_BASE_URL), or point CURSOR_API_BASE_URL at a backend that mounts /internal/agent-serve/* and /internal/agentsdk/*.`,
|
|
981
981
|
404
|
|
982
982
|
);
|
|
983
983
|
}
|
|
@@ -1928,7 +1928,15 @@ async function loadChannels(
|
|
|
1928
1928
|
});
|
|
1929
1929
|
continue;
|
|
1930
1930
|
}
|
|
1931
|
-
|
|
1931
|
+
const definition = mod.default as ChannelDefinition;
|
|
1932
|
+
for (const notice of definition.meta?.deprecations ?? []) {
|
|
1933
|
+
ctx.diagnostics.push({
|
|
1934
|
+
severity: "warning",
|
|
1935
|
+
path: displayPath(ctx, entryPath),
|
|
1936
|
+
message: notice,
|
|
1937
|
+
});
|
|
1938
|
+
}
|
|
1939
|
+
channels.push({ id, definition });
|
|
1932
1940
|
}
|
|
1933
1941
|
return { channels, httpChannelDefinition };
|
|
1934
1942
|
}
|
|
@@ -8,15 +8,16 @@
|
|
|
8
8
|
* is browsable from the dashboard and mountable on cloud-runtime VMs;
|
|
9
9
|
* - the **framework-level** store (`AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID`)
|
|
10
10
|
* holds engine-owned session state — session records, event transcripts,
|
|
11
|
-
* the continuation index, and the SDK
|
|
12
|
-
* exposed to authors or models.
|
|
11
|
+
* hosted-execution run logs, the continuation index, and the SDK
|
|
12
|
+
* conversation mirror — and is never exposed to authors or models.
|
|
13
13
|
*
|
|
14
14
|
* This module puts framework session state on the framework store. The
|
|
15
15
|
* {@link storageKeys} scheme was designed for exactly this: keys are a
|
|
16
16
|
* stable versioned contract that sinks may route on, so
|
|
17
17
|
* {@link composeFrameworkStorage} splits one {@link StorageConfig} by key
|
|
18
|
-
* kind — `session` / `session-events` / `
|
|
19
|
-
* file store (file-shaped; the store accepts values
|
|
18
|
+
* kind — `session` / `session-events` / `session-runs` / `continuation`
|
|
19
|
+
* go to the framework file store (file-shaped; the store accepts values
|
|
20
|
+
* up to 64 MiB per
|
|
20
21
|
* object without chunking, versus the KV proxy's 1 MiB row cap), while
|
|
21
22
|
* author `kv`, eval runs, A/B samples, and conditional writes stay on the
|
|
22
23
|
* control-plane KV proxy (the dashboard reads them there, and CAS needs a
|
|
@@ -40,6 +41,7 @@ import { mapBounded } from "./bounded.js";
|
|
|
40
41
|
const FRAMEWORK_FILE_KINDS: ReadonlySet<string> = new Set([
|
|
41
42
|
"session",
|
|
42
43
|
"session-events",
|
|
44
|
+
"session-runs",
|
|
43
45
|
"continuation",
|
|
44
46
|
]);
|
|
45
47
|
|
|
@@ -17,17 +17,19 @@
|
|
|
17
17
|
*
|
|
18
18
|
* - **Cursor-managed hosting** (the deployment-generation environment
|
|
19
19
|
* variable is set, same signal that registers `GET /v1/manifest`):
|
|
20
|
-
* the
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* the KV proxy
|
|
29
|
-
*
|
|
30
|
-
*
|
|
20
|
+
* the deployment's **framework-level file store**
|
|
21
|
+
* (`AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID`, bound at task time) holds
|
|
22
|
+
* session records, event transcripts, and the continuation index —
|
|
23
|
+
* file-shaped state on file storage, apart from the author-facing user
|
|
24
|
+
* store. Author `host.kv`, eval runs, A/B samples, and conditional writes
|
|
25
|
+
* ride the AgentSDK v2 KV proxy (cursor-hosted-v2.ts), which resolves the
|
|
26
|
+
* pod service account to the factorydb deployment row (the v1 Bugbot
|
|
27
|
+
* proxy cannot resolve v2 pods at all). Framework session state never
|
|
28
|
+
* routes to the KV proxy — the composite splits by key kind — so
|
|
29
|
+
* transcripts stay off the author-reachable KV namespace. The API key
|
|
30
|
+
* resolves through the full credential chain on every call because hosted
|
|
31
|
+
* freeze snapshots listen unsigned and the binder drops the key file
|
|
32
|
+
* after restore.
|
|
31
33
|
* - **Self-hosted**: no mirror. `--state-root` is the durable copy, which
|
|
32
34
|
* is correct when the operator owns the disk.
|
|
33
35
|
*
|
|
@@ -45,7 +47,7 @@ import {
|
|
|
45
47
|
cursorHostedFiles,
|
|
46
48
|
} from "../files-backends/cursor-hosted.js";
|
|
47
49
|
import { defineStorage, type StorageDefinition } from "../storage.js";
|
|
48
|
-
import {
|
|
50
|
+
import { cursorHostedStorageV2 } from "../storage-backends/cursor-hosted-v2.js";
|
|
49
51
|
import type { AgentArchitecture } from "../types.js";
|
|
50
52
|
import { resolveApiKeySync } from "./cursor/credentials.js";
|
|
51
53
|
import { AGENT_SERVE_GENERATION_ENV_VAR } from "./cursor-relay-core.js";
|
|
@@ -96,20 +98,18 @@ export function selectFrameworkStorageDefinition(
|
|
|
96
98
|
// comes up). Follow-ups restore lazily by continuation or session id;
|
|
97
99
|
// GET /v1/sessions lists from the sink either way.
|
|
98
100
|
const policy = { restore: "off" } as const;
|
|
99
|
-
|
|
100
|
-
//
|
|
101
|
+
const envSnapshot = env as NodeJS.ProcessEnv;
|
|
102
|
+
// Full chain (env → bind file → stored login): frozen engines listen
|
|
103
|
+
// unsigned and bind store ids + CURSOR_API_KEY at task time, after this
|
|
101
104
|
// definition is constructed.
|
|
102
105
|
const resolveApiKey = (): string | undefined => resolveApiKeySync()?.apiKey;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
// Framework session state on the framework-level file store; author kv,
|
|
111
|
-
// evals, and A/B tables stay on the KV proxy (spread from `kv`, which
|
|
112
|
-
// also carries the cursor-hosted marker for GET /v1/sessions).
|
|
106
|
+
// v2 pods carry a factorydb-bound service account, which the v1 Bugbot
|
|
107
|
+
// storage proxy cannot resolve; author KV, CAS coordination, and the
|
|
108
|
+
// eval/A-B tables speak the AgentSDK v2 KV proxy instead. It also carries
|
|
109
|
+
// the cursor-hosted marker, so GET /v1/sessions prefers the durable list
|
|
110
|
+
// (session records are on the framework store, which the composed core
|
|
111
|
+
// lists).
|
|
112
|
+
const kv = cursorHostedStorageV2({ resolveApiKey });
|
|
113
113
|
return defineStorage({
|
|
114
114
|
name: "cursor-hosted (framework files)",
|
|
115
115
|
policy,
|
|
@@ -117,7 +117,10 @@ export function selectFrameworkStorageDefinition(
|
|
|
117
117
|
...composeFrameworkStorage({
|
|
118
118
|
kv,
|
|
119
119
|
files: fileSinkStorageCore(
|
|
120
|
-
cursorHostedFiles({
|
|
120
|
+
cursorHostedFiles({
|
|
121
|
+
resolveStoreSourceId: () => cursorFrameworkStoreSourceId(envSnapshot),
|
|
122
|
+
resolveApiKey,
|
|
123
|
+
})
|
|
121
124
|
),
|
|
122
125
|
}),
|
|
123
126
|
// CAS stays on the KV proxy but must refuse framework-file keys, or a
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ChannelHandlerArgs } from "../types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hosted-admission hook a channel pack attaches to its definition.
|
|
5
|
+
*
|
|
6
|
+
* Hosted delivery looks this up from the mounted definition — it does not
|
|
7
|
+
* switch on `channelKind`. A new forge implements `dispatch` / `getOutcome`
|
|
8
|
+
* next to its webhook handler and calls {@link attachHostedAdmissionAdapter}
|
|
9
|
+
* from the channel constructor.
|
|
10
|
+
*/
|
|
11
|
+
export type HostedAdmissionDispatchOutcome = "skip" | "task";
|
|
12
|
+
|
|
13
|
+
export type HostedAdmissionAdapter = {
|
|
14
|
+
kind: string;
|
|
15
|
+
/**
|
|
16
|
+
* Optional wrap of the capturing `send` / `waitUntil` args (GitHub uses
|
|
17
|
+
* this to propagate background-task errors). Identity when omitted.
|
|
18
|
+
*/
|
|
19
|
+
prepareArgs?(args: ChannelHandlerArgs): ChannelHandlerArgs;
|
|
20
|
+
dispatch(input: {
|
|
21
|
+
eventType: string;
|
|
22
|
+
payload: unknown;
|
|
23
|
+
deliveryId: string;
|
|
24
|
+
args: ChannelHandlerArgs;
|
|
25
|
+
}): Promise<Response>;
|
|
26
|
+
getOutcome(response: Response): HostedAdmissionDispatchOutcome | undefined;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const adapters = new WeakMap<object, HostedAdmissionAdapter>();
|
|
30
|
+
|
|
31
|
+
export function attachHostedAdmissionAdapter(
|
|
32
|
+
definition: object,
|
|
33
|
+
adapter: HostedAdmissionAdapter
|
|
34
|
+
): void {
|
|
35
|
+
adapters.set(definition, adapter);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function getHostedAdmissionAdapter(
|
|
39
|
+
definition: object
|
|
40
|
+
): HostedAdmissionAdapter | undefined {
|
|
41
|
+
return adapters.get(definition);
|
|
42
|
+
}
|
|
@@ -18,7 +18,12 @@ export type HostedAdmissionManagedAutomation = {
|
|
|
18
18
|
export type HostedAdmission = {
|
|
19
19
|
v: 2;
|
|
20
20
|
channelId: string;
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Mailbox / subscription channel kind (`github`, `origin`, …). The guest
|
|
23
|
+
* resolves dispatch from the mounted definition's hosted-admission
|
|
24
|
+
* adapter; this field is not an allowlist.
|
|
25
|
+
*/
|
|
26
|
+
channelKind: string;
|
|
22
27
|
eventType: string;
|
|
23
28
|
deliveryId: string;
|
|
24
29
|
sessionMode: "event" | "continuation";
|
|
@@ -107,7 +112,7 @@ export function parseHostedAdmission(
|
|
|
107
112
|
!Object.hasOwn(body, "payload") ||
|
|
108
113
|
body.v !== HOSTED_DELIVERY_PROTOCOL_VERSION ||
|
|
109
114
|
!boundedString(body.channelId, 128) ||
|
|
110
|
-
body.channelKind
|
|
115
|
+
!boundedString(body.channelKind, 128) ||
|
|
111
116
|
!boundedString(body.eventType, 128) ||
|
|
112
117
|
!boundedString(body.deliveryId, 256) ||
|
|
113
118
|
(body.sessionMode !== "event" && body.sessionMode !== "continuation") ||
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
-
import {
|
|
3
|
-
dispatchGitHubWebhook,
|
|
4
|
-
getGitHubChannelOptions,
|
|
5
|
-
getGitHubDispatchOutcome,
|
|
6
|
-
withPropagatingGitHubBackgroundErrors,
|
|
7
|
-
} from "../channels/github/github-channel.js";
|
|
8
2
|
import type {
|
|
9
3
|
AuthPolicy,
|
|
10
4
|
ChannelHandlerArgs,
|
|
@@ -14,6 +8,10 @@ import {
|
|
|
14
8
|
createDeferredChannelSession,
|
|
15
9
|
DeferredChannelSessionError,
|
|
16
10
|
} from "./deferred-channel-session.js";
|
|
11
|
+
import {
|
|
12
|
+
getHostedAdmissionAdapter,
|
|
13
|
+
type HostedAdmissionAdapter,
|
|
14
|
+
} from "./hosted-admission-adapter.js";
|
|
17
15
|
import {
|
|
18
16
|
HostedAdmissionLocalSendError,
|
|
19
17
|
runDuringHostedAdmission,
|
|
@@ -30,12 +28,19 @@ import {
|
|
|
30
28
|
import {
|
|
31
29
|
abortReasonFromTurnStatus,
|
|
32
30
|
HOSTED_EXECUTION_DIAG_RUNNING_STATUS,
|
|
31
|
+
hostedErrorStackSnippet,
|
|
33
32
|
hostedExecutionDiagId,
|
|
34
33
|
writeHostedExecutionDiag,
|
|
35
34
|
} from "./hosted-execution-diag.js";
|
|
36
35
|
import { recordHostedManagedAutomation } from "./hosted-managed-automation.js";
|
|
37
36
|
import { errorResponse, readJsonObject } from "./http-channel.js";
|
|
37
|
+
import type { LogRingEntry } from "./log-ring.js";
|
|
38
38
|
import type { Router } from "./router.js";
|
|
39
|
+
import {
|
|
40
|
+
type SessionRunExecutionWrite,
|
|
41
|
+
serializeSessionRunError,
|
|
42
|
+
snapshotSessionRunLogs,
|
|
43
|
+
} from "./session-run-log.js";
|
|
39
44
|
|
|
40
45
|
type DispatchInput = {
|
|
41
46
|
delivery: HostedAdmission;
|
|
@@ -115,17 +120,20 @@ function nonRetryableRejection(error: unknown): AdmissionDispatch | undefined {
|
|
|
115
120
|
}
|
|
116
121
|
|
|
117
122
|
/**
|
|
118
|
-
* Run authored admission without creating a framework session.
|
|
123
|
+
* Run authored admission without creating a framework session. Authored
|
|
119
124
|
* `task` callbacks execute as sessionless work; the first `send` is captured
|
|
120
125
|
* and executed only after the control plane allocates `ses_…`. Capturing
|
|
121
126
|
* does not terminate the caller — `send` returns an inert deferred handle so
|
|
122
127
|
* a task body runs to completion before the admission response is computed.
|
|
128
|
+
*
|
|
129
|
+
* Dispatch is the adapter the mounted channel attached. Hosted delivery
|
|
130
|
+
* does not switch on `channelKind`.
|
|
123
131
|
*/
|
|
124
132
|
export async function dispatchHostedAdmission(
|
|
125
133
|
input: DispatchInput
|
|
126
134
|
): Promise<AdmissionDispatch> {
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
135
|
+
const adapter = getHostedAdmissionAdapter(input.definition);
|
|
136
|
+
if (adapter === undefined || adapter.kind !== input.delivery.channelKind) {
|
|
129
137
|
return {
|
|
130
138
|
response: Response.json(
|
|
131
139
|
{ ok: false, error: "channel_kind_mismatch" },
|
|
@@ -135,16 +143,16 @@ export async function dispatchHostedAdmission(
|
|
|
135
143
|
}
|
|
136
144
|
// The admission window marker follows the async graph into task bodies so
|
|
137
145
|
// the engine can refuse local sends that would bypass the capture stub.
|
|
138
|
-
return runDuringHostedAdmission(() => runAdmission(input,
|
|
146
|
+
return runDuringHostedAdmission(() => runAdmission(input, adapter));
|
|
139
147
|
}
|
|
140
148
|
|
|
141
149
|
async function runAdmission(
|
|
142
150
|
input: DispatchInput,
|
|
143
|
-
|
|
151
|
+
adapter: HostedAdmissionAdapter
|
|
144
152
|
): Promise<AdmissionDispatch> {
|
|
145
153
|
const background: Promise<unknown>[] = [];
|
|
146
154
|
let captured: { message: string; options: SendMessageOptions } | undefined;
|
|
147
|
-
const
|
|
155
|
+
const capturingArgs: ChannelHandlerArgs = {
|
|
148
156
|
...input.args,
|
|
149
157
|
send: async (message, options = {}) => {
|
|
150
158
|
if (captured !== undefined) {
|
|
@@ -156,12 +164,12 @@ async function runAdmission(
|
|
|
156
164
|
waitUntil: (promise) => {
|
|
157
165
|
background.push(promise);
|
|
158
166
|
},
|
|
159
|
-
}
|
|
167
|
+
};
|
|
168
|
+
const args = adapter.prepareArgs?.(capturingArgs) ?? capturingArgs;
|
|
160
169
|
let dispatched: Response;
|
|
161
170
|
try {
|
|
162
|
-
dispatched = await
|
|
163
|
-
|
|
164
|
-
eventName: input.delivery.eventType,
|
|
171
|
+
dispatched = await adapter.dispatch({
|
|
172
|
+
eventType: input.delivery.eventType,
|
|
165
173
|
payload: input.delivery.payload,
|
|
166
174
|
deliveryId: input.delivery.deliveryId,
|
|
167
175
|
args,
|
|
@@ -212,7 +220,7 @@ async function runAdmission(
|
|
|
212
220
|
},
|
|
213
221
|
};
|
|
214
222
|
}
|
|
215
|
-
const outcome =
|
|
223
|
+
const outcome = adapter.getOutcome(dispatched);
|
|
216
224
|
if (outcome === undefined) {
|
|
217
225
|
return {
|
|
218
226
|
response: Response.json(
|
|
@@ -264,6 +272,15 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
264
272
|
* `hosted-execution.json` from that path after the POST returns.
|
|
265
273
|
*/
|
|
266
274
|
stateRoot?: string;
|
|
275
|
+
/**
|
|
276
|
+
* Upsert this execution into the v2 session-level framework-store log.
|
|
277
|
+
* Called for the pre-turn `running` claim and every terminal outcome so
|
|
278
|
+
* a dead Node process still leaves a leftover. Soft-fail inside the
|
|
279
|
+
* store; this path still awaits so a parked pod cannot shed the write.
|
|
280
|
+
*/
|
|
281
|
+
persistSessionRun?(write: SessionRunExecutionWrite): Promise<void>;
|
|
282
|
+
/** Snapshot of the process log ring at persist time. */
|
|
283
|
+
snapshotLogs?(): LogRingEntry[];
|
|
267
284
|
}): void {
|
|
268
285
|
const pending = new Map<
|
|
269
286
|
string,
|
|
@@ -404,30 +421,64 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
404
421
|
abortReason?:
|
|
405
422
|
| ReturnType<typeof abortReasonFromTurnStatus>
|
|
406
423
|
| "execute_throw";
|
|
424
|
+
error?: unknown;
|
|
407
425
|
}): Promise<void> => {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
426
|
+
const durationMs = Math.max(
|
|
427
|
+
0,
|
|
428
|
+
Math.round(performance.now() - startedAt)
|
|
429
|
+
);
|
|
411
430
|
const message =
|
|
412
431
|
fields.message === undefined
|
|
413
432
|
? undefined
|
|
414
433
|
: boundedMessage(fields.message);
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
:
|
|
427
|
-
|
|
428
|
-
? {}
|
|
429
|
-
|
|
430
|
-
|
|
434
|
+
const stack =
|
|
435
|
+
fields.error === undefined
|
|
436
|
+
? undefined
|
|
437
|
+
: hostedErrorStackSnippet(fields.error);
|
|
438
|
+
if (input.stateRoot !== undefined) {
|
|
439
|
+
await writeHostedExecutionDiag(input.stateRoot, {
|
|
440
|
+
v: 1,
|
|
441
|
+
executionId,
|
|
442
|
+
writtenAt: new Date().toISOString(),
|
|
443
|
+
sessionPublicId: execution.sessionPublicId,
|
|
444
|
+
sessionId: fields.sessionId,
|
|
445
|
+
turnStatus: fields.turnStatus,
|
|
446
|
+
durationMs,
|
|
447
|
+
...(message === undefined ? {} : { message }),
|
|
448
|
+
...(stack === undefined || stack.length === 0 ? {} : { stack }),
|
|
449
|
+
...(message !== undefined && /abort/i.test(message)
|
|
450
|
+
? { signalAborted: true }
|
|
451
|
+
: {}),
|
|
452
|
+
...(fields.abortReason === undefined
|
|
453
|
+
? {}
|
|
454
|
+
: { abortReason: fields.abortReason }),
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
if (input.persistSessionRun === undefined) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const error =
|
|
461
|
+
fields.error === undefined
|
|
462
|
+
? undefined
|
|
463
|
+
: serializeSessionRunError(fields.error);
|
|
464
|
+
try {
|
|
465
|
+
await input.persistSessionRun({
|
|
466
|
+
executionId,
|
|
467
|
+
writtenAt: new Date().toISOString(),
|
|
468
|
+
sessionPublicId: execution.sessionPublicId,
|
|
469
|
+
sessionId: fields.sessionId,
|
|
470
|
+
turnStatus: fields.turnStatus,
|
|
471
|
+
durationMs,
|
|
472
|
+
...(fields.abortReason === undefined
|
|
473
|
+
? {}
|
|
474
|
+
: { abortReason: fields.abortReason }),
|
|
475
|
+
...(message === undefined ? {} : { message }),
|
|
476
|
+
...(error === undefined ? {} : { error }),
|
|
477
|
+
logs: snapshotSessionRunLogs(input.snapshotLogs?.() ?? []),
|
|
478
|
+
});
|
|
479
|
+
} catch {
|
|
480
|
+
// Soft-fail: a store outage must not change the HTTP reply.
|
|
481
|
+
}
|
|
431
482
|
};
|
|
432
483
|
// Claim the file before the turn runs. The host reads it after its
|
|
433
484
|
// own POST returns, which for a 9-minute timeout is while this turn
|
|
@@ -486,6 +537,7 @@ export function registerHostedDeliveryRoute(input: {
|
|
|
486
537
|
turnStatus: "error",
|
|
487
538
|
message: error instanceof Error ? error.message : String(error),
|
|
488
539
|
abortReason: "execute_throw",
|
|
540
|
+
error,
|
|
489
541
|
});
|
|
490
542
|
throw error;
|
|
491
543
|
}
|