@cursor/july 0.1.99 → 0.1.101
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 +4 -2
- package/dist/bin/agent-serve.js +3 -2
- package/dist/channels/deployments/deployments-channel.d.ts +41 -5
- package/dist/channels/deployments/deployments-channel.d.ts.map +1 -1
- package/dist/channels/deployments/deployments-channel.js +88 -8
- package/dist/channels/deployments/types.d.ts +4 -3
- package/dist/channels/deployments/types.d.ts.map +1 -1
- package/dist/channels/github/defaults.d.ts.map +1 -1
- package/dist/channels/github/defaults.js +28 -3
- package/dist/channels/github/progress.d.ts +7 -0
- package/dist/channels/github/progress.d.ts.map +1 -1
- package/dist/channels/origin/defaults.d.ts +43 -0
- package/dist/channels/origin/defaults.d.ts.map +1 -0
- package/dist/channels/origin/defaults.js +111 -0
- package/dist/channels/origin/index.d.ts +2 -0
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +2 -0
- package/dist/channels/origin/origin-channel.d.ts +2 -1
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +24 -3
- package/dist/channels/origin/state.d.ts +32 -0
- package/dist/channels/origin/state.d.ts.map +1 -0
- package/dist/channels/origin/state.js +23 -0
- package/dist/channels/origin/types.d.ts +23 -1
- package/dist/channels/origin/types.d.ts.map +1 -1
- 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 +31 -14
- package/dist/channels/slack/code-fences.d.ts +17 -0
- package/dist/channels/slack/code-fences.d.ts.map +1 -0
- package/dist/channels/slack/code-fences.js +168 -0
- 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 +154 -76
- 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 +2 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +2 -0
- package/dist/channels/slack/live-delivery.d.ts +5 -0
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +116 -21
- 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 +145 -6
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/connections.d.ts +18 -2
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +18 -2
- 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.BplEAZ3S.js → app.BASO9Kih.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.DbFXINq2.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.CHXyv4wP.js → VPLocalSearchBox.DwkqxoE0.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BTcsZmjQ.js → theme.CCil_13e.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_connections.md.DxldvyIB.js → reference_connections.md.Di6jJAXF.js} +13 -3
- package/dist/docs/assets/{reference_connections.md.DxldvyIB.lean.js → reference_connections.md.Di6jJAXF.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.BEJx9XVj.js → reference_http-api.md.oySXBO8o.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/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 +1073 -31
- package/dist/docs/llms.txt +14 -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 +4 -4
- package/dist/docs/reference/connections.html +17 -7
- package/dist/docs/reference/connections.md +32 -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 -1
- 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 +4 -4
- 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/extensions/cursor-cloud-agents/extension.d.ts +55 -0
- package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/extension.js +64 -0
- package/dist/extensions/cursor-cloud-agents/lib/cloud.d.ts +30 -0
- package/dist/extensions/cursor-cloud-agents/lib/cloud.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/cloud.js +45 -0
- package/dist/extensions/cursor-cloud-agents/lib/fleet.d.ts +25 -0
- package/dist/extensions/cursor-cloud-agents/lib/fleet.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/fleet.js +85 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts +15 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.js +55 -0
- package/dist/extensions/cursor-cloud-agents/skills/handoff.md +27 -0
- package/dist/extensions/cursor-cloud-agents/tools/follow_up.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/follow_up.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/follow_up.js +37 -0
- package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/launch.js +83 -0
- package/dist/extensions/cursor-cloud-agents/tools/list.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/list.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/list.js +36 -0
- package/dist/extensions/cursor-cloud-agents/tools/status.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/status.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/status.js +41 -0
- package/dist/extensions.d.ts +49 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +75 -0
- package/dist/files-backends/cursor-hosted.d.ts +6 -0
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +6 -9
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/internal/advertise-tools.d.ts +4 -1
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +20 -1
- package/dist/internal/as-of.d.ts +18 -0
- package/dist/internal/as-of.d.ts.map +1 -1
- package/dist/internal/as-of.js +131 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +66 -21
- package/dist/internal/continuation-identity.d.ts.map +1 -1
- package/dist/internal/continuation-identity.js +3 -1
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +3 -4
- package/dist/internal/cursor/hosted-deployment-secrets.d.ts +16 -0
- package/dist/internal/cursor/hosted-deployment-secrets.d.ts.map +1 -0
- package/dist/internal/cursor/hosted-deployment-secrets.js +61 -0
- 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-deployment-relay.d.ts +15 -1
- package/dist/internal/cursor-deployment-relay.d.ts.map +1 -1
- package/dist/internal/cursor-deployment-relay.js +46 -7
- package/dist/internal/deploy-client.d.ts +29 -6
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +61 -19
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +426 -121
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +5 -0
- package/dist/internal/framework-file-storage.d.ts +15 -8
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +70 -10
- package/dist/internal/framework-storage-selection.d.ts +12 -12
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +33 -39
- package/dist/internal/hosted-delivery.d.ts +3 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +19 -32
- package/dist/internal/hosted-execution-diag.d.ts +5 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
- package/dist/internal/hosted-execution-diag.js +5 -0
- package/dist/internal/hosted-execution-flush.d.ts +46 -0
- package/dist/internal/hosted-execution-flush.d.ts.map +1 -0
- package/dist/internal/hosted-execution-flush.js +81 -0
- package/dist/internal/mcp-endpoint.js +1 -0
- package/dist/internal/mcp-host.d.ts +2 -1
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +35 -15
- package/dist/internal/review-comments.d.ts +1 -1
- package/dist/internal/review-comments.d.ts.map +1 -1
- package/dist/internal/review-comments.js +4 -4
- package/dist/internal/server.d.ts +3 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +79 -104
- package/dist/internal/session-engine.d.ts +9 -7
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +45 -34
- package/dist/internal/session-run-log.d.ts +5 -4
- package/dist/internal/session-run-log.d.ts.map +1 -1
- package/dist/internal/session-run-log.js +8 -8
- package/dist/internal/start-log-store.d.ts +60 -0
- package/dist/internal/start-log-store.d.ts.map +1 -0
- package/dist/internal/start-log-store.js +151 -0
- package/dist/internal/storage-coordinator.d.ts +0 -6
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +1 -9
- package/dist/internal/tool-policy.d.ts +8 -0
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +19 -7
- package/dist/playground/assets/{index-jzNbJENa.js → index-BnNN1-EK.js} +45 -45
- package/dist/playground/assets/index-DBQCwFp0.css +1 -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 +24 -0
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +33 -0
- package/dist/storage.d.ts +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +1 -1
- package/dist/types.d.ts +123 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +29 -1
- package/docs/README.md +1 -1
- package/docs/ab.md +1 -1
- package/docs/building-with-agents.md +14 -11
- 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/connections.md +32 -1
- package/docs/reference/http-api.md +1 -1
- package/docs/scaffolding-agents.md +3 -3
- package/docs/skills/index.md +26 -0
- package/docs/troubleshooting.md +1 -1
- package/package.json +18 -4
- package/src/bin/agent-serve.ts +11 -2
- package/src/channels/deployments/deployments-channel.ts +117 -8
- package/src/channels/deployments/types.ts +4 -3
- package/src/channels/github/defaults.ts +36 -3
- package/src/channels/github/progress.ts +7 -0
- package/src/channels/origin/defaults.ts +143 -0
- package/src/channels/origin/index.ts +2 -0
- package/src/channels/origin/origin-channel.ts +37 -1
- package/src/channels/origin/state.ts +54 -0
- package/src/channels/origin/types.ts +24 -0
- package/src/channels/slack/api.ts +37 -18
- package/src/channels/slack/code-fences.ts +183 -0
- package/src/channels/slack/constants.ts +6 -0
- package/src/channels/slack/defaults.ts +173 -92
- package/src/channels/slack/dispatch.ts +8 -1
- package/src/channels/slack/inbound.ts +17 -0
- package/src/channels/slack/index.ts +2 -0
- package/src/channels/slack/live-delivery.ts +142 -28
- 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 +159 -6
- package/src/connections.ts +18 -1
- package/src/extensions/cursor-cloud-agents/extension.ts +118 -0
- package/src/extensions/cursor-cloud-agents/lib/cloud.ts +79 -0
- package/src/extensions/cursor-cloud-agents/lib/fleet.ts +109 -0
- package/src/extensions/cursor-cloud-agents/lib/repos.ts +81 -0
- package/src/extensions/cursor-cloud-agents/skills/handoff.md +27 -0
- package/src/extensions/cursor-cloud-agents/tools/follow_up.ts +29 -0
- package/src/extensions/cursor-cloud-agents/tools/launch.ts +84 -0
- package/src/extensions/cursor-cloud-agents/tools/list.ts +31 -0
- package/src/extensions/cursor-cloud-agents/tools/status.ts +39 -0
- package/src/extensions.ts +98 -0
- package/src/files-backends/cursor-hosted.ts +15 -5
- package/src/index.ts +2 -0
- package/src/internal/advertise-tools.ts +37 -12
- package/src/internal/as-of.ts +163 -0
- package/src/internal/cli-deploy.ts +88 -25
- package/src/internal/continuation-identity.ts +3 -1
- package/src/internal/conversation-mirror.ts +3 -8
- package/src/internal/cursor/hosted-deployment-secrets.ts +72 -0
- package/src/internal/cursor/hosted-store-secrets.ts +72 -0
- package/src/internal/cursor-deployment-relay.ts +65 -8
- package/src/internal/deploy-client.ts +83 -28
- package/src/internal/discovery.ts +479 -114
- package/src/internal/distribution.ts +5 -0
- package/src/internal/framework-file-storage.ts +80 -10
- package/src/internal/framework-storage-selection.ts +31 -44
- package/src/internal/hosted-delivery.ts +38 -63
- package/src/internal/hosted-execution-diag.ts +6 -0
- package/src/internal/hosted-execution-flush.ts +142 -0
- package/src/internal/mcp-endpoint.ts +1 -0
- package/src/internal/mcp-host.ts +40 -14
- package/src/internal/review-comments.ts +5 -2
- package/src/internal/server.ts +81 -100
- package/src/internal/session-engine.ts +56 -28
- package/src/internal/session-run-log.ts +8 -12
- package/src/internal/start-log-store.ts +177 -0
- package/src/internal/storage-coordinator.ts +1 -11
- package/src/internal/tool-policy.ts +39 -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 +37 -0
- package/src/storage.ts +1 -0
- package/src/types.ts +177 -14
- package/dist/docs/assets/chunks/@localSearchIndexroot.DpuI4i7Z.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/internal/null-kv-storage.d.ts +0 -48
- package/dist/internal/null-kv-storage.d.ts.map +0 -1
- package/dist/internal/null-kv-storage.js +0 -58
- package/dist/playground/assets/index-D7rGZNjy.css +0 -1
- package/src/internal/null-kv-storage.ts +0 -74
- /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_http-api.md.BEJx9XVj.lean.js → reference_http-api.md.oySXBO8o.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,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable hosted `start.log` on the framework file store. **v2 only.**
|
|
3
|
+
*
|
|
4
|
+
* The engine tees stdout/stderr to a local file. That file is the v2
|
|
5
|
+
* customer log (errors, traces, debug). It is NOT written to S3 per line:
|
|
6
|
+
* callers snapshot the local buffer and PUT once. The Temporal host does
|
|
7
|
+
* a last catch-up at the end of the delivery so the object is complete
|
|
8
|
+
* after park/discard.
|
|
9
|
+
*
|
|
10
|
+
* Same flush moments as `hosted-execution.json` and session-runs —
|
|
11
|
+
* see `hosted-execution-flush.ts`. Keys: {@link storageKeys.log}.
|
|
12
|
+
* Values are raw UTF-8, not JSON.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { readFile } from "node:fs/promises";
|
|
16
|
+
import type { FileSink } from "../files.js";
|
|
17
|
+
import {
|
|
18
|
+
cursorFrameworkStoreSourceId,
|
|
19
|
+
cursorHostedFiles,
|
|
20
|
+
} from "../files-backends/cursor-hosted.js";
|
|
21
|
+
import { storageKeys } from "../storage-protocol.js";
|
|
22
|
+
import type { AgentProject } from "../types.js";
|
|
23
|
+
import { resolveApiKeySync } from "./cursor/credentials.js";
|
|
24
|
+
import { AGENT_SERVE_GENERATION_ENV_VAR } from "./cursor-relay-core.js";
|
|
25
|
+
import { describeError } from "./describe-error.js";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Last N bytes flushed to the store. Matches the Temporal catch-up cap
|
|
29
|
+
* so guest snapshots and host catch-up stay interchangeable. The store
|
|
30
|
+
* allows 64 MiB; this keeps the dashboard snapshot bounded.
|
|
31
|
+
*/
|
|
32
|
+
export const START_LOG_STORE_MAX_BYTES: number = 2 * 1024 * 1024;
|
|
33
|
+
|
|
34
|
+
/** Same path the hosted start command tees. Overridable in tests. */
|
|
35
|
+
export const DEFAULT_ENGINE_START_LOG_PATH =
|
|
36
|
+
"/workspace/.agent-serve/start.log";
|
|
37
|
+
|
|
38
|
+
export interface StartLogStore {
|
|
39
|
+
persist(startLogId: string, contents: string): Promise<void>;
|
|
40
|
+
read(startLogId: string): Promise<string | undefined>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function decodeSinkBody(body: Uint8Array | { body: Uint8Array }): Uint8Array {
|
|
44
|
+
return body instanceof Uint8Array ? body : body.body;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function tailStartLogText(raw: string, maxBytes: number): string {
|
|
48
|
+
const encoded = new TextEncoder().encode(raw);
|
|
49
|
+
if (encoded.byteLength <= maxBytes) {
|
|
50
|
+
return raw;
|
|
51
|
+
}
|
|
52
|
+
return new TextDecoder().decode(
|
|
53
|
+
encoded.subarray(encoded.byteLength - maxBytes)
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function resolveEngineStartLogPath(
|
|
58
|
+
env: NodeJS.ProcessEnv = process.env
|
|
59
|
+
): string {
|
|
60
|
+
const configured = env.AGENT_SERVE_ENGINE_START_LOG_PATH?.trim();
|
|
61
|
+
return configured !== undefined && configured.length > 0
|
|
62
|
+
? configured
|
|
63
|
+
: DEFAULT_ENGINE_START_LOG_PATH;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Read the local engine tee. Missing/empty is `undefined` (no store write).
|
|
68
|
+
* Soft-fail: a local read error must not change hosted-execution HTTP.
|
|
69
|
+
*/
|
|
70
|
+
export async function readLocalStartLogText(args?: {
|
|
71
|
+
path?: string;
|
|
72
|
+
maxBytes?: number;
|
|
73
|
+
}): Promise<string | undefined> {
|
|
74
|
+
const path = args?.path ?? resolveEngineStartLogPath();
|
|
75
|
+
const maxBytes = args?.maxBytes ?? START_LOG_STORE_MAX_BYTES;
|
|
76
|
+
try {
|
|
77
|
+
const raw = await readFile(path, "utf8");
|
|
78
|
+
if (raw.length === 0) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return tailStartLogText(raw, maxBytes);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (
|
|
84
|
+
error !== null &&
|
|
85
|
+
typeof error === "object" &&
|
|
86
|
+
"code" in error &&
|
|
87
|
+
(error as { code?: string }).code === "ENOENT"
|
|
88
|
+
) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function createStartLogStore(input: {
|
|
96
|
+
sink: FileSink;
|
|
97
|
+
agentName: string;
|
|
98
|
+
logger?: (line: string) => void;
|
|
99
|
+
}): StartLogStore {
|
|
100
|
+
const { sink, agentName } = input;
|
|
101
|
+
const logger = input.logger ?? (() => {});
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
async persist(startLogId, contents) {
|
|
105
|
+
const key = storageKeys.log(agentName, startLogId);
|
|
106
|
+
const body = tailStartLogText(contents, START_LOG_STORE_MAX_BYTES);
|
|
107
|
+
try {
|
|
108
|
+
await sink.put(key, new TextEncoder().encode(body));
|
|
109
|
+
} catch (error) {
|
|
110
|
+
logger(
|
|
111
|
+
`[agent-sdk] start-log: persist failed for ${startLogId} (${describeError(error)})`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
async read(startLogId) {
|
|
117
|
+
const key = storageKeys.log(agentName, startLogId);
|
|
118
|
+
try {
|
|
119
|
+
const body = await sink.get(key);
|
|
120
|
+
if (body === undefined) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
const text = new TextDecoder().decode(decodeSinkBody(body));
|
|
124
|
+
return text.length === 0 ? undefined : text;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
logger(
|
|
127
|
+
`[agent-sdk] start-log: read failed for ${startLogId} (${describeError(error)})`
|
|
128
|
+
);
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Same selection as the session-run log: architecture-v2 hosted engines.
|
|
137
|
+
*/
|
|
138
|
+
export function selectStartLogStore(input: {
|
|
139
|
+
project: AgentProject;
|
|
140
|
+
logger?: (line: string) => void;
|
|
141
|
+
env?: Record<string, string | undefined>;
|
|
142
|
+
}): StartLogStore | undefined {
|
|
143
|
+
if (input.project.agent.architecture !== "v2") {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
const env = input.env ?? process.env;
|
|
147
|
+
if (env[AGENT_SERVE_GENERATION_ENV_VAR] === undefined) {
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
const envSnapshot = env as NodeJS.ProcessEnv;
|
|
151
|
+
return createStartLogStore({
|
|
152
|
+
sink: cursorHostedFiles({
|
|
153
|
+
resolveStoreSourceId: () => cursorFrameworkStoreSourceId(envSnapshot),
|
|
154
|
+
resolveApiKey: () => resolveApiKeySync()?.apiKey,
|
|
155
|
+
}),
|
|
156
|
+
agentName: input.project.name,
|
|
157
|
+
logger: input.logger,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Snapshot the local tee into the store. No-op when the file is missing
|
|
163
|
+
* or empty. Soft-fail inside {@link StartLogStore.persist}.
|
|
164
|
+
*/
|
|
165
|
+
export async function flushLocalStartLog(args: {
|
|
166
|
+
store: StartLogStore;
|
|
167
|
+
startLogId: string;
|
|
168
|
+
path?: string;
|
|
169
|
+
}): Promise<void> {
|
|
170
|
+
const contents = await readLocalStartLogText(
|
|
171
|
+
args.path === undefined ? undefined : { path: args.path }
|
|
172
|
+
);
|
|
173
|
+
if (contents === undefined) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
await args.store.persist(args.startLogId, contents);
|
|
177
|
+
}
|
|
@@ -38,7 +38,6 @@ import type { JsonValue, SessionEvent, SessionRecord } from "../types.js";
|
|
|
38
38
|
import type { ABSnapshot } from "./ab-snapshot.js";
|
|
39
39
|
import { describeError } from "./describe-error.js";
|
|
40
40
|
import type { EvalRunStorage } from "./eval-run-store.js";
|
|
41
|
-
import { isAuthorKvUnsupported } from "./null-kv-storage.js";
|
|
42
41
|
import type {
|
|
43
42
|
AuthorKvStore,
|
|
44
43
|
EvalAbStore,
|
|
@@ -469,18 +468,9 @@ export class StorageCoordinator
|
|
|
469
468
|
/**
|
|
470
469
|
* Whether the sink can serve awaited author reads/writes (`get` is
|
|
471
470
|
* required — `put` is always present on {@link StorageConfig}).
|
|
472
|
-
*
|
|
473
|
-
* A sink may keep `get` for framework session state while refusing author
|
|
474
|
-
* KV: hosted v2 reads sessions from the framework file store but has no
|
|
475
|
-
* working KV backend, and author handlers that cannot read their own
|
|
476
|
-
* writes back are better served by the local-disk fallback than by a sink
|
|
477
|
-
* that accepts every write and forgets it.
|
|
478
471
|
*/
|
|
479
472
|
get supportsAuthorKv(): boolean {
|
|
480
|
-
return
|
|
481
|
-
this.definition.get !== undefined &&
|
|
482
|
-
!isAuthorKvUnsupported(this.definition)
|
|
483
|
-
);
|
|
473
|
+
return this.definition.get !== undefined;
|
|
484
474
|
}
|
|
485
475
|
|
|
486
476
|
/**
|
|
@@ -16,7 +16,11 @@ import type {
|
|
|
16
16
|
ToolEffectDeclaration,
|
|
17
17
|
ToolExecuteResult,
|
|
18
18
|
} from "../types.js";
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
forwardTimeArgument,
|
|
21
|
+
missingTimeWindow,
|
|
22
|
+
timeArgViolation,
|
|
23
|
+
} from "./as-of.js";
|
|
20
24
|
|
|
21
25
|
/** What the host does with one tool call. */
|
|
22
26
|
export type ToolDecision =
|
|
@@ -64,6 +68,14 @@ export interface ToolCallFacts {
|
|
|
64
68
|
asOf?: string;
|
|
65
69
|
/** The tool's declared time-bound argument names, if it made them. */
|
|
66
70
|
timeArgs?: readonly string[];
|
|
71
|
+
/**
|
|
72
|
+
* String-typed time-window property names a vendor tool's own input schema
|
|
73
|
+
* declares (`from`/`to`/`since`/...). In a frozen session a call that omits
|
|
74
|
+
* one is refused: the vendor fills an omitted window with a live default
|
|
75
|
+
* the argument walker can never see. Advertised/bridged MCP tools only —
|
|
76
|
+
* authored tools declare {@link timeArgs} instead.
|
|
77
|
+
*/
|
|
78
|
+
timeWindow?: readonly string[];
|
|
67
79
|
}
|
|
68
80
|
|
|
69
81
|
/**
|
|
@@ -159,14 +171,32 @@ function unclassifiedRefusal(toolName: string): string {
|
|
|
159
171
|
export function decideToolCall(facts: ToolCallFacts): ToolDecision {
|
|
160
172
|
// Before the dry-run split: a frozen session bounds its reads whether or
|
|
161
173
|
// not its writes are stubbed.
|
|
162
|
-
if (
|
|
163
|
-
facts.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
174
|
+
if (facts.asOf !== undefined) {
|
|
175
|
+
if (facts.timeArgs !== undefined && facts.timeArgs.length > 0) {
|
|
176
|
+
const violation = timeArgViolation(
|
|
177
|
+
facts.input,
|
|
178
|
+
facts.timeArgs,
|
|
179
|
+
facts.asOf
|
|
180
|
+
);
|
|
181
|
+
if (violation !== undefined) {
|
|
182
|
+
return { kind: "unbounded", message: violation };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const forward = forwardTimeArgument(facts.input, facts.asOf);
|
|
186
|
+
if (forward !== undefined) {
|
|
187
|
+
return { kind: "unbounded", message: forward };
|
|
188
|
+
}
|
|
189
|
+
// Present values are checked above; absent ones are the vendor's live
|
|
190
|
+
// default window, which no walker can see. Require them explicitly.
|
|
191
|
+
if (facts.timeWindow !== undefined) {
|
|
192
|
+
const omitted = missingTimeWindow(
|
|
193
|
+
facts.input,
|
|
194
|
+
facts.timeWindow,
|
|
195
|
+
facts.asOf
|
|
196
|
+
);
|
|
197
|
+
if (omitted !== undefined) {
|
|
198
|
+
return { kind: "unbounded", message: omitted };
|
|
199
|
+
}
|
|
170
200
|
}
|
|
171
201
|
}
|
|
172
202
|
if (!facts.dryRun) {
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor-managed durable KV for hosted **architecture v2** agents.
|
|
3
|
+
*
|
|
4
|
+
* Talks to the AgentSDK v2 KV proxy
|
|
5
|
+
* (`POST /internal/agentsdk/kv/*`) using the engine's pod
|
|
6
|
+
* `CURSOR_API_KEY`. The server resolves the v2 deployment from that service
|
|
7
|
+
* account (factorydb `agentsdk_deployment`) and persists rows in factorydb
|
|
8
|
+
* `agentsdk_kv` — v1's Bugbot-backed `/internal/agent-serve/storage/*`
|
|
9
|
+
* routes cannot resolve a v2 pod credential at all.
|
|
10
|
+
*
|
|
11
|
+
* The v2 wire protocol is four routes, not v1's eight:
|
|
12
|
+
*
|
|
13
|
+
* - `POST /internal/agentsdk/kv/get`
|
|
14
|
+
* `{ key }` → `{ found, value, version }` — reads always carry the CAS
|
|
15
|
+
* version token ({@link KvV2GetResponse}).
|
|
16
|
+
* - `POST /internal/agentsdk/kv/put`
|
|
17
|
+
* `{ key, value, ifAbsent? | ifVersion? }` → `{ ok, version, current }`
|
|
18
|
+
* ({@link KvV2PutResponse}) — one write primitive: last-write-wins when
|
|
19
|
+
* unconditional (still bumps the token), atomic create-if-absent with
|
|
20
|
+
* `ifAbsent: true`, atomic compare-and-swap with `ifVersion`.
|
|
21
|
+
* - `POST /internal/agentsdk/kv/delete` `{ key }` → `{ ok }`.
|
|
22
|
+
* - `POST /internal/agentsdk/kv/list`
|
|
23
|
+
* `{ prefix, limit?, cursor?, keysOnly? }` → `{ entries, nextCursor }`
|
|
24
|
+
* ({@link KvV2ListResponse}) — ascending key order with keyset
|
|
25
|
+
* pagination. `list` / `listKeys` below drain every page, so the v1
|
|
26
|
+
* truncated-scan failure mode does not exist here.
|
|
27
|
+
*
|
|
28
|
+
* Eval runs and A/B samples still ride the v1 storage proxy's dedicated
|
|
29
|
+
* tables (`evals` / `abs` below); moving them to factorydb is a separate
|
|
30
|
+
* follow-up from the KV cutover.
|
|
31
|
+
*
|
|
32
|
+
* This backend is platform-selected for architecture v2
|
|
33
|
+
* (framework-storage-selection.ts) — authors never import it; `agent/storage.ts`
|
|
34
|
+
* is rejected on v2.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import type {
|
|
38
|
+
StorageABTable,
|
|
39
|
+
StorageCasTable,
|
|
40
|
+
StorageConfig,
|
|
41
|
+
StorageEntry,
|
|
42
|
+
StorageEvalsTable,
|
|
43
|
+
} from "../storage.js";
|
|
44
|
+
import type { JsonValue, KvCasResult, KvVersionedEntry } from "../types.js";
|
|
45
|
+
import {
|
|
46
|
+
CURSOR_HOSTED_STORAGE,
|
|
47
|
+
type CursorHostedStorageOptions,
|
|
48
|
+
cursorHostedStorage,
|
|
49
|
+
storageRpc,
|
|
50
|
+
} from "./cursor-hosted.js";
|
|
51
|
+
|
|
52
|
+
const KV_V2_PREFIX = "/internal/agentsdk/kv";
|
|
53
|
+
|
|
54
|
+
/** Wire shape of the v2 `get` route. `null` ⇒ JSON `undefined`. */
|
|
55
|
+
export interface KvV2GetResponse {
|
|
56
|
+
found: boolean;
|
|
57
|
+
value: JsonValue | null;
|
|
58
|
+
version: string | null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Wire shape of the v2 `put` route (all three write modes). */
|
|
62
|
+
export interface KvV2PutResponse {
|
|
63
|
+
ok: boolean;
|
|
64
|
+
/** New version token on an accepted write, else `null`. */
|
|
65
|
+
version: string | null;
|
|
66
|
+
/** Entry observed when a conditional write lost; `null` when absent. */
|
|
67
|
+
current: { value: JsonValue | null; version: string } | null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Wire shape of the v2 `list` route. */
|
|
71
|
+
export interface KvV2ListResponse {
|
|
72
|
+
entries: Array<{
|
|
73
|
+
key: string;
|
|
74
|
+
/** Omitted when the request asked for keys only. */
|
|
75
|
+
value?: JsonValue | null;
|
|
76
|
+
version: string;
|
|
77
|
+
}>;
|
|
78
|
+
/** Last key of this page when more rows remain, else `null`. */
|
|
79
|
+
nextCursor: string | null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type CursorHostedStorageV2Methods = Required<
|
|
83
|
+
Pick<StorageConfig, "put" | "get" | "delete" | "list">
|
|
84
|
+
> & {
|
|
85
|
+
readonly [CURSOR_HOSTED_STORAGE]: true;
|
|
86
|
+
cas: StorageCasTable;
|
|
87
|
+
evals: StorageEvalsTable;
|
|
88
|
+
abs: StorageABTable;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
function toCasResult(response: KvV2PutResponse): KvCasResult {
|
|
92
|
+
if (response.ok) {
|
|
93
|
+
if (response.version === null) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
"cursorHostedStorageV2: conditional write succeeded without a version token"
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
return { ok: true, version: response.version };
|
|
99
|
+
}
|
|
100
|
+
const current: KvVersionedEntry | undefined =
|
|
101
|
+
response.current === null
|
|
102
|
+
? undefined
|
|
103
|
+
: {
|
|
104
|
+
value: response.current.value ?? null,
|
|
105
|
+
version: response.current.version,
|
|
106
|
+
};
|
|
107
|
+
return { ok: false, current };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Drain every page of a v2 `list` scan. The server pages by keyset (each
|
|
112
|
+
* `nextCursor` is the strictly-greatest key returned so far), so a cursor
|
|
113
|
+
* that fails to advance means a broken server — fail loudly rather than
|
|
114
|
+
* loop forever.
|
|
115
|
+
*/
|
|
116
|
+
async function listAllPages(
|
|
117
|
+
options: CursorHostedStorageOptions,
|
|
118
|
+
body: { prefix: string; keysOnly?: boolean }
|
|
119
|
+
): Promise<KvV2ListResponse["entries"]> {
|
|
120
|
+
const entries: KvV2ListResponse["entries"] = [];
|
|
121
|
+
let cursor: string | undefined;
|
|
122
|
+
for (;;) {
|
|
123
|
+
const page = await storageRpc<KvV2ListResponse>(
|
|
124
|
+
options,
|
|
125
|
+
`${KV_V2_PREFIX}/list`,
|
|
126
|
+
cursor === undefined ? body : { ...body, cursor }
|
|
127
|
+
);
|
|
128
|
+
entries.push(...page.entries);
|
|
129
|
+
if (page.nextCursor === null) {
|
|
130
|
+
return entries;
|
|
131
|
+
}
|
|
132
|
+
if (cursor !== undefined && page.nextCursor <= cursor) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`cursorHostedStorageV2: list("${body.prefix}") cursor did not advance`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
cursor = page.nextCursor;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Architecture-v2 `defineStorage` methods (AgentSDK v2 KV proxy → factorydb
|
|
143
|
+
* `agentsdk_kv`). Platform-selected; spread into `defineStorage({...})` by
|
|
144
|
+
* framework-storage-selection.ts. No `listNewest`: v2 session records live
|
|
145
|
+
* on the framework file store, so the only consumer of write-time ordering
|
|
146
|
+
* never reaches this backend and the engine's `list` fallback covers the
|
|
147
|
+
* rest.
|
|
148
|
+
*/
|
|
149
|
+
export function cursorHostedStorageV2(
|
|
150
|
+
options: CursorHostedStorageOptions = {}
|
|
151
|
+
): CursorHostedStorageV2Methods {
|
|
152
|
+
// Eval runs and A/B samples stay on the v1 proxy's dedicated tables.
|
|
153
|
+
const v1 = cursorHostedStorage(options);
|
|
154
|
+
return {
|
|
155
|
+
[CURSOR_HOSTED_STORAGE]: true,
|
|
156
|
+
async put(key, value): Promise<void> {
|
|
157
|
+
await storageRpc(options, `${KV_V2_PREFIX}/put`, { key, value });
|
|
158
|
+
},
|
|
159
|
+
async get(key): Promise<JsonValue | undefined> {
|
|
160
|
+
const result = await storageRpc<KvV2GetResponse>(
|
|
161
|
+
options,
|
|
162
|
+
`${KV_V2_PREFIX}/get`,
|
|
163
|
+
{ key }
|
|
164
|
+
);
|
|
165
|
+
if (!result.found) {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
return result.value ?? undefined;
|
|
169
|
+
},
|
|
170
|
+
async delete(key): Promise<void> {
|
|
171
|
+
await storageRpc(options, `${KV_V2_PREFIX}/delete`, { key });
|
|
172
|
+
},
|
|
173
|
+
async list(prefix): Promise<StorageEntry[]> {
|
|
174
|
+
const entries = await listAllPages(options, { prefix });
|
|
175
|
+
return entries.map((entry) => ({
|
|
176
|
+
key: entry.key,
|
|
177
|
+
value: entry.value ?? null,
|
|
178
|
+
}));
|
|
179
|
+
},
|
|
180
|
+
cas: {
|
|
181
|
+
async getWithVersion(key): Promise<KvVersionedEntry | undefined> {
|
|
182
|
+
const result = await storageRpc<KvV2GetResponse>(
|
|
183
|
+
options,
|
|
184
|
+
`${KV_V2_PREFIX}/get`,
|
|
185
|
+
{ key }
|
|
186
|
+
);
|
|
187
|
+
if (!result.found || result.version === null) {
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
return { value: result.value ?? null, version: result.version };
|
|
191
|
+
},
|
|
192
|
+
async putIfAbsent(key, value): Promise<KvCasResult> {
|
|
193
|
+
const result = await storageRpc<KvV2PutResponse>(
|
|
194
|
+
options,
|
|
195
|
+
`${KV_V2_PREFIX}/put`,
|
|
196
|
+
{ key, value, ifAbsent: true }
|
|
197
|
+
);
|
|
198
|
+
return toCasResult(result);
|
|
199
|
+
},
|
|
200
|
+
async putIfVersion(key, value, expectedVersion): Promise<KvCasResult> {
|
|
201
|
+
const result = await storageRpc<KvV2PutResponse>(
|
|
202
|
+
options,
|
|
203
|
+
`${KV_V2_PREFIX}/put`,
|
|
204
|
+
{ key, value, ifVersion: expectedVersion }
|
|
205
|
+
);
|
|
206
|
+
return toCasResult(result);
|
|
207
|
+
},
|
|
208
|
+
async listKeys(prefix): Promise<string[]> {
|
|
209
|
+
const entries = await listAllPages(options, {
|
|
210
|
+
prefix,
|
|
211
|
+
keysOnly: true,
|
|
212
|
+
});
|
|
213
|
+
return entries.map((entry) => entry.key);
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
evals: v1.evals,
|
|
217
|
+
abs: v1.abs,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
@@ -207,7 +207,12 @@ function resolveBaseUrl(options: CursorHostedStorageOptions): string {
|
|
|
207
207
|
return raw.endsWith("/") ? raw.slice(0, -1) : raw;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
|
|
210
|
+
/**
|
|
211
|
+
* One authenticated POST to the control-plane proxy. Shared with the
|
|
212
|
+
* architecture-v2 backend (`cursor-hosted-v2.ts`), which speaks a different
|
|
213
|
+
* route family over the same transport and credential chain.
|
|
214
|
+
*/
|
|
215
|
+
export async function storageRpc<T>(
|
|
211
216
|
options: CursorHostedStorageOptions,
|
|
212
217
|
path: string,
|
|
213
218
|
body: Record<string, unknown>
|
package/src/storage-protocol.ts
CHANGED
|
@@ -39,6 +39,7 @@ const DURABLE_SESSION_RECORD_KEY_RE =
|
|
|
39
39
|
* | `agentkit/v1/{agent}/session/{sessionId}` | `SessionRecord` |
|
|
40
40
|
* | `agentkit/v1/{agent}/session-events/{sessionId}/{index}` | `SessionEvent[]` chunk (index = first event's index, zero-padded) |
|
|
41
41
|
* | `agentkit/v1/{agent}/session-runs/{sessionPublicId}` | One session-level hosted-execution log (executions[] + lastFailure) |
|
|
42
|
+
* | `agentkit/v1/{agent}/logs/{logId}` | Hosted engine stdout/stderr tee (on-disk `start.log`; `ses_…` after send, `wf:{workflowId}` on admission failure) |
|
|
42
43
|
* | `agentkit/v1/{agent}/continuation/{channelId}/{token}` | `{ sessionId }` |
|
|
43
44
|
* | `agentkit/v1/{agent}/kv/{key}` | Author JSON via `HostContext.kv` |
|
|
44
45
|
*
|
|
@@ -69,6 +70,17 @@ export const storageKeys = {
|
|
|
69
70
|
`${STORAGE_KEY_ROOT}/${agent}/session-runs/${keySegment(sessionPublicId)}`,
|
|
70
71
|
sessionRunsPrefix: (agent: string): string =>
|
|
71
72
|
`${STORAGE_KEY_ROOT}/${agent}/session-runs/`,
|
|
73
|
+
/**
|
|
74
|
+
* The v2 customer log: the engine stdout/stderr tee (on-disk `start.log`).
|
|
75
|
+
* `logId` is the factory `ses_…` after a `send`, or
|
|
76
|
+
* `wf:{workflowId}` / `wf:{workflowId}/{runId}` when admission fails
|
|
77
|
+
* before a session exists. Skip/task admissions do not write this key.
|
|
78
|
+
* Stored as raw UTF-8, not JSON — the file store accepts 64 MiB
|
|
79
|
+
* objects, and this key is flushed in snapshots, not per line.
|
|
80
|
+
*/
|
|
81
|
+
log: (agent: string, logId: string): string =>
|
|
82
|
+
`${STORAGE_KEY_ROOT}/${agent}/logs/${keySegment(logId)}`,
|
|
83
|
+
logsPrefix: (agent: string): string => `${STORAGE_KEY_ROOT}/${agent}/logs/`,
|
|
72
84
|
continuation: (
|
|
73
85
|
agent: string,
|
|
74
86
|
channelId: string,
|
|
@@ -111,6 +123,31 @@ export const storageKeys = {
|
|
|
111
123
|
*/
|
|
112
124
|
export const MAX_KEY_SEGMENT_BYTES = 256;
|
|
113
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Stable start-log object id. A `send` attaches to the factory session
|
|
128
|
+
* so the factory/dashboard session-runs read can see it. Admission that
|
|
129
|
+
* fails before a session exists is keyed on the Temporal workflow run
|
|
130
|
+
* (`wf:{workflowId}` or `wf:{workflowId}/{runId}`) so the object joins
|
|
131
|
+
* the Temporal UI. A successful skip/task writes nothing — there is no
|
|
132
|
+
* customer log.
|
|
133
|
+
*/
|
|
134
|
+
export function frameworkStartLogId(args: {
|
|
135
|
+
sessionPublicId?: string | null;
|
|
136
|
+
workflowId?: string | null;
|
|
137
|
+
runId?: string | null;
|
|
138
|
+
}): string | undefined {
|
|
139
|
+
const sessionPublicId = args.sessionPublicId?.trim() ?? "";
|
|
140
|
+
if (sessionPublicId.length > 0) {
|
|
141
|
+
return sessionPublicId;
|
|
142
|
+
}
|
|
143
|
+
const workflowId = args.workflowId?.trim() ?? "";
|
|
144
|
+
if (workflowId.length === 0) {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
const runId = args.runId?.trim() ?? "";
|
|
148
|
+
return runId.length > 0 ? `wf:${workflowId}/${runId}` : `wf:${workflowId}`;
|
|
149
|
+
}
|
|
150
|
+
|
|
114
151
|
/**
|
|
115
152
|
* URI-encode one caller-controlled key segment, substituting a `sha256:…`
|
|
116
153
|
* digest of the raw value when the encoding exceeds
|