@cursor/july 0.1.96 → 0.1.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/README.md +3 -2
- package/dist/bin/agent-serve.js +13 -3
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +16 -0
- package/dist/channels/origin/api.d.ts +15 -4
- package/dist/channels/origin/api.d.ts.map +1 -1
- package/dist/channels/origin/api.js +19 -3
- package/dist/channels/origin/binding.d.ts +11 -0
- package/dist/channels/origin/binding.d.ts.map +1 -1
- package/dist/channels/origin/binding.js +41 -25
- package/dist/channels/origin/index.d.ts +1 -0
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +1 -0
- 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 +40 -4
- package/dist/channels/origin/reactions.d.ts +56 -0
- package/dist/channels/origin/reactions.d.ts.map +1 -0
- package/dist/channels/origin/reactions.js +67 -0
- package/dist/channels/origin/types.d.ts +11 -0
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/approvals.d.ts +16 -0
- package/dist/channels/slack/approvals.d.ts.map +1 -1
- package/dist/channels/slack/approvals.js +86 -0
- package/dist/channels/slack/cli-project.d.ts +19 -0
- package/dist/channels/slack/cli-project.d.ts.map +1 -0
- package/dist/channels/slack/cli-project.js +234 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +142 -63
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +1 -1
- package/dist/channels/slack/init.d.ts +3 -2
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +5 -5
- package/dist/channels/slack/interactive.d.ts +2 -1
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +15 -4
- package/dist/channels/slack/live-delivery.d.ts +1 -1
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +4 -2
- package/dist/channels/slack/manifest.d.ts +1 -1
- package/dist/channels/slack/manifest.js +1 -1
- 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/setup.d.ts +1 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +10 -6
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +1 -0
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
- package/dist/channels/slack/tool-approval-events.js +91 -1
- package/dist/channels/slack/types.d.ts +9 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.jXleCmOc.js → app.BplEAZ3S.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DpuI4i7Z.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.8LhyglIT.js → VPLocalSearchBox.CHXyv4wP.js} +1 -1
- package/dist/docs/assets/chunks/{theme.9ged-pr2.js → theme.BTcsZmjQ.js} +2 -2
- package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
- package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
- package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.CCnG-nJx.js → reference_cli.md.DfoeyvL0.js} +9 -6
- package/dist/docs/assets/{reference_cli.md.CCnG-nJx.lean.js → reference_cli.md.DfoeyvL0.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
- package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.BEJx9XVj.js} +2 -2
- package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.CvAHsdSp.js} +10 -2
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.CvAHsdSp.lean.js} +1 -1
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/deployment.md +5 -4
- package/dist/docs/design/runtime-abstraction.md +1757 -0
- package/dist/docs/evals.html +4 -4
- 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 +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +8 -8
- package/dist/docs/guides/mcp-oauth.md +26 -8
- package/dist/docs/guides/opentelemetry.html +4 -4
- package/dist/docs/guides/slack.html +17 -33
- package/dist/docs/guides/slack.md +92 -201
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +5 -3
- package/dist/docs/llms-full.txt +2065 -637
- package/dist/docs/llms.txt +3 -2
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +6 -6
- package/dist/docs/reference/agent-config.md +2 -2
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +13 -10
- package/dist/docs/reference/cli.md +32 -16
- package/dist/docs/reference/connections.html +9 -8
- package/dist/docs/reference/connections.md +6 -3
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +7 -7
- package/dist/docs/reference/http-api.md +3 -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 +5 -5
- package/dist/docs/reference/sessions.md +4 -2
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +15 -7
- package/dist/docs/reference/tools.md +34 -2
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +28 -0
- package/dist/docs/templates/agents-md.md +105 -0
- package/dist/docs/templates/code-wiki.html +5 -5
- 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 +5 -5
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +2 -2
- package/dist/evals/run-facts.d.ts.map +1 -1
- package/dist/evals/run-facts.js +27 -0
- package/dist/files-backends/cursor-hosted.d.ts +3 -2
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +15 -9
- package/dist/internal/approval-gate.d.ts +12 -13
- package/dist/internal/approval-gate.d.ts.map +1 -1
- package/dist/internal/approval-gate.js +16 -21
- 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/chat-client.js +10 -0
- package/dist/internal/cli-deploy.d.ts +6 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +149 -21
- package/dist/internal/cli-mcp-oauth.js +8 -18
- package/dist/internal/cli-slack-manual.d.ts +24 -2
- package/dist/internal/cli-slack-manual.d.ts.map +1 -1
- package/dist/internal/cli-slack-manual.js +251 -20
- package/dist/internal/cli-slack.d.ts +9 -2
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +29 -82
- package/dist/internal/cursor/account-mcp.d.ts +1 -0
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +17 -0
- package/dist/internal/cursor-agent-template.d.ts +1 -1
- package/dist/internal/cursor-agent-template.d.ts.map +1 -1
- package/dist/internal/cursor-agent-template.js +1 -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 +17 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +31 -10
- package/dist/internal/env-file.d.ts +19 -0
- package/dist/internal/env-file.d.ts.map +1 -0
- package/dist/internal/env-file.js +90 -0
- package/dist/internal/framework-file-storage.d.ts +11 -17
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +17 -40
- 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 +37 -26
- 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 +13 -1
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +8 -1
- package/dist/internal/hosted-delivery.d.ts +21 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +101 -34
- package/dist/internal/hosted-execution-diag.d.ts +59 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
- package/dist/internal/hosted-execution-diag.js +187 -0
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +85 -2
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +2 -0
- package/dist/internal/logs-client.d.ts +5 -0
- package/dist/internal/logs-client.d.ts.map +1 -1
- package/dist/internal/logs-client.js +5 -0
- package/dist/internal/mcp-endpoint.js +2 -3
- package/dist/internal/mcp-host.d.ts +10 -0
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +57 -8
- package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
- package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-on-demand.js +287 -0
- package/dist/internal/mcp-oauth-persist.d.ts +42 -0
- package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-persist.js +92 -0
- package/dist/internal/mcp-oauth.d.ts +1 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -1
- package/dist/internal/mcp-oauth.js +10 -2
- package/dist/internal/null-kv-storage.d.ts +48 -0
- package/dist/internal/null-kv-storage.d.ts.map +1 -0
- package/dist/internal/null-kv-storage.js +58 -0
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +22 -9
- package/dist/internal/server.d.ts +6 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +123 -33
- package/dist/internal/session-engine.d.ts +88 -3
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +538 -46
- 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 +359 -0
- package/dist/internal/sessions-client.d.ts +9 -7
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +3 -1
- package/dist/internal/storage-coordinator.d.ts +13 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +37 -6
- package/dist/internal/storage-roles.d.ts +5 -0
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +10 -0
- package/dist/internal/tool-policy.d.ts +29 -9
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +24 -0
- package/dist/internal/trajectory.d.ts.map +1 -1
- package/dist/internal/trajectory.js +10 -0
- package/dist/internal/turn-outbox.d.ts +24 -0
- package/dist/internal/turn-outbox.d.ts.map +1 -0
- package/dist/internal/turn-outbox.js +80 -0
- package/dist/playground/assets/index-D7rGZNjy.css +1 -0
- package/dist/playground/assets/index-jzNbJENa.js +69 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +1 -1
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +12 -0
- 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/storage.d.ts +8 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/tools.d.ts +12 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/types.d.ts +88 -7
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +5 -3
- package/docs/deployment.md +5 -4
- package/docs/design/runtime-abstraction.md +1757 -0
- package/docs/guides/mcp-oauth.md +26 -8
- package/docs/guides/slack.md +93 -202
- package/docs/reference/agent-config.md +2 -2
- package/docs/reference/cli.md +32 -16
- package/docs/reference/connections.md +6 -3
- package/docs/reference/http-api.md +3 -1
- package/docs/reference/sessions.md +4 -2
- package/docs/reference/tools.md +34 -2
- package/docs/templates/agents-md.md +110 -0
- package/docs/troubleshooting.md +2 -2
- package/package.json +1 -1
- package/skills/create-agent/SKILL.md +2 -1
- package/skills/mcp-auth/SKILL.md +6 -3
- package/skills/setup-slack/SKILL.md +23 -13
- package/src/bin/agent-serve.ts +12 -1
- package/src/channels/github/github-channel.ts +17 -0
- package/src/channels/origin/api.ts +24 -5
- package/src/channels/origin/binding.ts +55 -26
- package/src/channels/origin/index.ts +1 -0
- package/src/channels/origin/origin-channel.ts +78 -10
- package/src/channels/origin/reactions.ts +82 -0
- package/src/channels/origin/types.ts +11 -0
- package/src/channels/slack/approvals.ts +105 -0
- package/src/channels/slack/cli-project.ts +267 -0
- package/src/channels/slack/defaults.ts +165 -74
- package/src/channels/slack/dispatch.ts +2 -0
- package/src/channels/slack/init.ts +10 -5
- package/src/channels/slack/interactive.ts +35 -9
- package/src/channels/slack/live-delivery.ts +5 -3
- package/src/channels/slack/manifest.ts +1 -1
- package/src/channels/slack/progress-delivery.ts +133 -0
- package/src/channels/slack/setup.ts +10 -6
- package/src/channels/slack/slack-channel.ts +1 -0
- package/src/channels/slack/tool-approval-events.ts +93 -0
- package/src/channels/slack/types.ts +9 -1
- package/src/evals/run-facts.ts +32 -0
- package/src/files-backends/cursor-hosted.ts +3 -2
- package/src/index.ts +4 -0
- package/src/internal/advertise-tools.ts +31 -10
- package/src/internal/approval-gate.ts +20 -29
- package/src/internal/as-of.ts +107 -0
- package/src/internal/chat-client.ts +19 -0
- package/src/internal/cli-deploy.ts +203 -13
- package/src/internal/cli-mcp-oauth.ts +7 -21
- package/src/internal/cli-slack-manual.ts +350 -18
- package/src/internal/cli-slack.ts +40 -84
- package/src/internal/cursor/account-mcp.ts +21 -0
- package/src/internal/cursor-agent-template.ts +1 -0
- package/src/internal/cursor-event-relay.ts +5 -6
- package/src/internal/deploy-client.ts +43 -0
- package/src/internal/env-file.ts +84 -0
- package/src/internal/framework-file-storage.ts +18 -46
- package/src/internal/framework-storage-selection.ts +41 -25
- package/src/internal/hosted-admission-adapter.ts +42 -0
- package/src/internal/hosted-delivery-protocol.ts +14 -2
- package/src/internal/hosted-delivery.ts +169 -44
- package/src/internal/hosted-execution-diag.ts +252 -0
- package/src/internal/http-channel.ts +107 -0
- package/src/internal/init-project.ts +2 -0
- package/src/internal/logs-client.ts +5 -0
- package/src/internal/mcp-endpoint.ts +13 -4
- package/src/internal/mcp-host.ts +77 -11
- package/src/internal/mcp-oauth-on-demand.ts +352 -0
- package/src/internal/mcp-oauth-persist.ts +127 -0
- package/src/internal/mcp-oauth.ts +17 -1
- package/src/internal/null-kv-storage.ts +74 -0
- package/src/internal/otel/collector.ts +30 -0
- package/src/internal/server.ts +159 -11
- package/src/internal/session-engine.ts +691 -57
- package/src/internal/session-run-log.ts +584 -0
- package/src/internal/sessions-client.ts +17 -8
- package/src/internal/storage-coordinator.ts +49 -9
- package/src/internal/storage-roles.ts +7 -0
- package/src/internal/stream-progress.ts +19 -0
- package/src/internal/tool-policy.ts +49 -9
- package/src/internal/trajectory.ts +10 -0
- package/src/internal/turn-outbox.ts +85 -0
- package/src/storage-backends/cursor-hosted.ts +13 -1
- package/src/storage-protocol.ts +10 -0
- package/src/storage.ts +12 -0
- package/src/tools.ts +12 -2
- package/src/types.ts +93 -8
- package/templates/agents-md/README.md +39 -0
- package/templates/agents-md/agent/agent.ts +8 -0
- package/templates/agents-md/agent/channels/github.ts +10 -0
- package/templates/agents-md/agent/channels/queue.ts +28 -0
- package/templates/agents-md/agent/channels/slack.ts +9 -0
- package/templates/agents-md/agent/instructions.md +39 -0
- package/templates/agents-md/agent/lib/collect.ts +439 -0
- package/templates/agents-md/agent/lib/config.ts +8 -0
- package/templates/agents-md/agent/lib/paths.ts +51 -0
- package/templates/agents-md/agent/schedules/weekly.ts +17 -0
- package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
- package/templates/agents-md/evals/agents.eval.ts +135 -0
- package/templates/agents-md/evals/evals.config.ts +5 -0
- package/templates/agents-md/init.json +38 -0
- package/templates/agents-md/package.json +18 -0
- package/templates/agents-md/tsconfig.json +12 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.DFoGuETX.js +0 -1
- package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
- package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
- package/dist/docs/assets/index.md.CI93Ltlb.js +0 -5
- package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
- package/dist/docs/design/agsh.md +0 -406
- package/dist/playground/assets/index-B1DDvBeC.css +0 -1
- package/dist/playground/assets/index-Cx9CclK_.js +0 -88
- package/docs/design/agsh.md +0 -406
- /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
- /package/dist/docs/assets/{index.md.CI93Ltlb.lean.js → index.md.CVeRUOeZ.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.BEJx9XVj.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable hosted-execution run log on the framework file store. **v2 only.**
|
|
3
|
+
*
|
|
4
|
+
* One JSON document per factory session (`ses_…`), with per-execution
|
|
5
|
+
* entries inside. The later customer UI is session-scoped ("why did this
|
|
6
|
+
* session fail?") so a single GET is the read path; continuations are FIFO
|
|
7
|
+
* so last-write-wins merge is safe. Guest-local `hosted-execution.json` and
|
|
8
|
+
* factorydb `last_error` are lossy: the on-disk diag dies with the pod, and
|
|
9
|
+
* the session row only keeps the first 1024 characters of a generic HTTP
|
|
10
|
+
* 500.
|
|
11
|
+
*
|
|
12
|
+
* Process death: persist `running` at turn start so SIGKILL / OOM still
|
|
13
|
+
* leaves a durable leftover. `uncaughtException` / SIGTERM flush the same
|
|
14
|
+
* session key with `processDeath: true` and the real throw. Soft-fail on
|
|
15
|
+
* persist so a store outage never changes the hosted-execution HTTP reply.
|
|
16
|
+
*
|
|
17
|
+
* Keys: {@link storageKeys.sessionRun}.
|
|
18
|
+
*/
|
|
19
|
+
import type { FileSink } from "../files.js";
|
|
20
|
+
import type { AgentProject } from "../types.js";
|
|
21
|
+
import type { HostedExecutionDiagAbortReason } from "./hosted-execution-diag.js";
|
|
22
|
+
import type { LogRingEntry } from "./log-ring.js";
|
|
23
|
+
export declare const SESSION_RUN_LOG_VERSION = 1;
|
|
24
|
+
/** Last N log-ring lines kept on each execution. */
|
|
25
|
+
export declare const SESSION_RUN_LOG_MAX_ENTRIES = 200;
|
|
26
|
+
/** Per-line cap so a runaway logger cannot blow the document. */
|
|
27
|
+
export declare const SESSION_RUN_LOG_MAX_LINE_CHARS = 4096;
|
|
28
|
+
/** Continuations are FIFO; keep a bounded history for the session UI. */
|
|
29
|
+
export declare const SESSION_RUN_LOG_MAX_EXECUTIONS = 20;
|
|
30
|
+
/** Crash-handler flush must not block `process.exit`. */
|
|
31
|
+
export declare const SESSION_RUN_FATAL_FLUSH_TIMEOUT_MS = 2000;
|
|
32
|
+
export type SessionRunAbortReason = HostedExecutionDiagAbortReason | "process_exit" | "uncaught_exception" | "unhandled_rejection";
|
|
33
|
+
export type SessionRunLogError = {
|
|
34
|
+
name: string;
|
|
35
|
+
message: string;
|
|
36
|
+
stack?: string;
|
|
37
|
+
};
|
|
38
|
+
export type SessionRunExecution = {
|
|
39
|
+
executionId: string;
|
|
40
|
+
writtenAt: string;
|
|
41
|
+
sessionId: string;
|
|
42
|
+
turnStatus: string;
|
|
43
|
+
durationMs: number;
|
|
44
|
+
abortReason?: SessionRunAbortReason;
|
|
45
|
+
message?: string;
|
|
46
|
+
error?: SessionRunLogError;
|
|
47
|
+
/** True when this entry was flushed from a process-death handler. */
|
|
48
|
+
processDeath?: boolean;
|
|
49
|
+
logs: LogRingEntry[];
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Latest non-success execution, including leftover `running` after the
|
|
53
|
+
* process died without a terminal persist (SIGKILL / OOM). Undefined when
|
|
54
|
+
* the latest execution `turnStatus` is `finished`.
|
|
55
|
+
*/
|
|
56
|
+
export type SessionRunLastFailure = {
|
|
57
|
+
executionId: string;
|
|
58
|
+
writtenAt: string;
|
|
59
|
+
turnStatus: string;
|
|
60
|
+
abortReason?: SessionRunAbortReason;
|
|
61
|
+
message?: string;
|
|
62
|
+
error?: SessionRunLogError;
|
|
63
|
+
processDeath?: boolean;
|
|
64
|
+
};
|
|
65
|
+
/** One document per factory session. The customer UI reads this object. */
|
|
66
|
+
export type SessionRunLogDocument = {
|
|
67
|
+
v: typeof SESSION_RUN_LOG_VERSION;
|
|
68
|
+
sessionPublicId: string;
|
|
69
|
+
updatedAt: string;
|
|
70
|
+
lastFailure?: SessionRunLastFailure;
|
|
71
|
+
executions: SessionRunExecution[];
|
|
72
|
+
};
|
|
73
|
+
/** Persist input: one execution upserted into the session document. */
|
|
74
|
+
export type SessionRunExecutionWrite = SessionRunExecution & {
|
|
75
|
+
sessionPublicId: string;
|
|
76
|
+
};
|
|
77
|
+
export interface SessionRunLogStore {
|
|
78
|
+
persist(write: SessionRunExecutionWrite): Promise<void>;
|
|
79
|
+
read(sessionPublicId: string): Promise<SessionRunLogDocument | undefined>;
|
|
80
|
+
/**
|
|
81
|
+
* Upgrade the in-flight `running` claim to a terminal process-death
|
|
82
|
+
* entry. No-op when no execution is active (already terminal, or never
|
|
83
|
+
* started). Soft-fail.
|
|
84
|
+
*/
|
|
85
|
+
flushProcessDeath(reason: Extract<SessionRunAbortReason, "process_exit" | "uncaught_exception" | "unhandled_rejection">, error?: unknown): Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Install the crash-handler flush used by `bin/agent-serve` on
|
|
89
|
+
* `uncaughtException`. One process, one active hosted serve.
|
|
90
|
+
*/
|
|
91
|
+
export declare function registerSessionRunFatalFlush(flush: (error: unknown) => Promise<void>): void;
|
|
92
|
+
export declare function unregisterSessionRunFatalFlush(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Await the registered crash flush, bounded so a hung store cannot prevent
|
|
95
|
+
* `process.exit`. Soft-fail.
|
|
96
|
+
*/
|
|
97
|
+
export declare function flushSessionRunFatal(error: unknown): Promise<void>;
|
|
98
|
+
export declare function serializeSessionRunError(error: unknown): SessionRunLogError;
|
|
99
|
+
export declare function snapshotSessionRunLogs(entries: readonly LogRingEntry[]): LogRingEntry[];
|
|
100
|
+
export declare function lastFailureFromExecutions(executions: readonly SessionRunExecution[]): SessionRunLastFailure | undefined;
|
|
101
|
+
export declare function parseSessionRunLogDocument(value: unknown): SessionRunLogDocument | undefined;
|
|
102
|
+
export declare function createSessionRunLogStore(input: {
|
|
103
|
+
sink: FileSink;
|
|
104
|
+
agentName: string;
|
|
105
|
+
logger?: (line: string) => void;
|
|
106
|
+
snapshotLogs?: () => readonly LogRingEntry[];
|
|
107
|
+
}): SessionRunLogStore;
|
|
108
|
+
/**
|
|
109
|
+
* Same selection as the conversation mirror: architecture-v2 hosted
|
|
110
|
+
* engines with a provisioned framework file store. Self-hosted and v1
|
|
111
|
+
* stay on local disk / today's behavior. This is the only path that
|
|
112
|
+
* installs the session-run log — v1 never writes these documents.
|
|
113
|
+
*/
|
|
114
|
+
export declare function selectSessionRunLogStore(input: {
|
|
115
|
+
project: AgentProject;
|
|
116
|
+
logger?: (line: string) => void;
|
|
117
|
+
env?: Record<string, string | undefined>;
|
|
118
|
+
snapshotLogs?: () => readonly LogRingEntry[];
|
|
119
|
+
}): SessionRunLogStore | undefined;
|
|
120
|
+
//# sourceMappingURL=session-run-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-run-log.d.ts","sourceRoot":"","sources":["../../src/internal/session-run-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAM5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,oDAAoD;AACpD,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,iEAAiE;AACjE,eAAO,MAAM,8BAA8B,OAAO,CAAC;AACnD,yEAAyE;AACzE,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAIjD,yDAAyD;AACzD,eAAO,MAAM,kCAAkC,OAAQ,CAAC;AAExD,MAAM,MAAM,qBAAqB,GAC7B,8BAA8B,GAC9B,cAAc,GACd,oBAAoB,GACpB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,qEAAqE;IACrE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,YAAY,EAAE,CAAC;CACtB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,qBAAqB,GAAG;IAClC,CAAC,EAAE,OAAO,uBAAuB,CAAC;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC,CAAC;AAEF,uEAAuE;AACvE,MAAM,MAAM,wBAAwB,GAAG,mBAAmB,GAAG;IAC3D,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAAC;IAC1E;;;;OAIG;IACH,iBAAiB,CACf,MAAM,EAAE,OAAO,CACb,qBAAqB,EACrB,cAAc,GAAG,oBAAoB,GAAG,qBAAqB,CAC9D,EACD,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAWD;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GACvC,IAAI,CAEN;AAED,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAUxE;AAgBD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAa3E;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,SAAS,YAAY,EAAE,GAC/B,YAAY,EAAE,CAOhB;AA6FD,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,SAAS,mBAAmB,EAAE,GACzC,qBAAqB,GAAG,SAAS,CAgBnC;AAuFD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,qBAAqB,GAAG,SAAS,CAkCnC;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,SAAS,YAAY,EAAE,CAAC;CAC9C,GAAG,kBAAkB,CA8GrB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,SAAS,YAAY,EAAE,CAAC;CAC9C,GAAG,kBAAkB,GAAG,SAAS,CAyBjC"}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable hosted-execution run log on the framework file store. **v2 only.**
|
|
3
|
+
*
|
|
4
|
+
* One JSON document per factory session (`ses_…`), with per-execution
|
|
5
|
+
* entries inside. The later customer UI is session-scoped ("why did this
|
|
6
|
+
* session fail?") so a single GET is the read path; continuations are FIFO
|
|
7
|
+
* so last-write-wins merge is safe. Guest-local `hosted-execution.json` and
|
|
8
|
+
* factorydb `last_error` are lossy: the on-disk diag dies with the pod, and
|
|
9
|
+
* the session row only keeps the first 1024 characters of a generic HTTP
|
|
10
|
+
* 500.
|
|
11
|
+
*
|
|
12
|
+
* Process death: persist `running` at turn start so SIGKILL / OOM still
|
|
13
|
+
* leaves a durable leftover. `uncaughtException` / SIGTERM flush the same
|
|
14
|
+
* session key with `processDeath: true` and the real throw. Soft-fail on
|
|
15
|
+
* persist so a store outage never changes the hosted-execution HTTP reply.
|
|
16
|
+
*
|
|
17
|
+
* Keys: {@link storageKeys.sessionRun}.
|
|
18
|
+
*/
|
|
19
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
20
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
21
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
22
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
23
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
24
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
25
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
import { cursorFrameworkStoreSourceId, cursorHostedFiles, } from "../files-backends/cursor-hosted.js";
|
|
29
|
+
import { storageKeys } from "../storage-protocol.js";
|
|
30
|
+
import { resolveApiKeySync } from "./cursor/credentials.js";
|
|
31
|
+
import { AGENT_SERVE_GENERATION_ENV_VAR } from "./cursor-relay-core.js";
|
|
32
|
+
import { describeError } from "./describe-error.js";
|
|
33
|
+
export const SESSION_RUN_LOG_VERSION = 1;
|
|
34
|
+
/** Last N log-ring lines kept on each execution. */
|
|
35
|
+
export const SESSION_RUN_LOG_MAX_ENTRIES = 200;
|
|
36
|
+
/** Per-line cap so a runaway logger cannot blow the document. */
|
|
37
|
+
export const SESSION_RUN_LOG_MAX_LINE_CHARS = 4096;
|
|
38
|
+
/** Continuations are FIFO; keep a bounded history for the session UI. */
|
|
39
|
+
export const SESSION_RUN_LOG_MAX_EXECUTIONS = 20;
|
|
40
|
+
const MAX_ERROR_MESSAGE_CHARS = 4096;
|
|
41
|
+
const MAX_ERROR_STACK_CHARS = 16384;
|
|
42
|
+
const MAX_DOCUMENT_CHARS = 512 * 1024;
|
|
43
|
+
/** Crash-handler flush must not block `process.exit`. */
|
|
44
|
+
export const SESSION_RUN_FATAL_FLUSH_TIMEOUT_MS = 2000;
|
|
45
|
+
let fatalFlush;
|
|
46
|
+
/**
|
|
47
|
+
* Install the crash-handler flush used by `bin/agent-serve` on
|
|
48
|
+
* `uncaughtException`. One process, one active hosted serve.
|
|
49
|
+
*/
|
|
50
|
+
export function registerSessionRunFatalFlush(flush) {
|
|
51
|
+
fatalFlush = flush;
|
|
52
|
+
}
|
|
53
|
+
export function unregisterSessionRunFatalFlush() {
|
|
54
|
+
fatalFlush = undefined;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Await the registered crash flush, bounded so a hung store cannot prevent
|
|
58
|
+
* `process.exit`. Soft-fail.
|
|
59
|
+
*/
|
|
60
|
+
export function flushSessionRunFatal(error) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
if (fatalFlush === undefined) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
yield Promise.race([
|
|
66
|
+
fatalFlush(error).catch(() => undefined),
|
|
67
|
+
new Promise((resolve) => {
|
|
68
|
+
setTimeout(resolve, SESSION_RUN_FATAL_FLUSH_TIMEOUT_MS);
|
|
69
|
+
}),
|
|
70
|
+
]);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function boundedText(value, max) {
|
|
74
|
+
return value.length > max ? `${value.slice(0, max)}…` : value;
|
|
75
|
+
}
|
|
76
|
+
function boundedOptionalText(value, max) {
|
|
77
|
+
if (value === undefined || value.length === 0) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
return boundedText(value, max);
|
|
81
|
+
}
|
|
82
|
+
export function serializeSessionRunError(error) {
|
|
83
|
+
if (error instanceof Error) {
|
|
84
|
+
const stack = boundedOptionalText(error.stack, MAX_ERROR_STACK_CHARS);
|
|
85
|
+
return Object.assign({ name: boundedText(error.name.length > 0 ? error.name : "Error", 128), message: boundedText(error.message, MAX_ERROR_MESSAGE_CHARS) }, (stack === undefined ? {} : { stack }));
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
name: "Error",
|
|
89
|
+
message: boundedText(String(error), MAX_ERROR_MESSAGE_CHARS),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export function snapshotSessionRunLogs(entries) {
|
|
93
|
+
const tail = entries.slice(-SESSION_RUN_LOG_MAX_ENTRIES);
|
|
94
|
+
return tail.map((entry) => ({
|
|
95
|
+
index: entry.index,
|
|
96
|
+
at: entry.at,
|
|
97
|
+
line: boundedText(entry.line, SESSION_RUN_LOG_MAX_LINE_CHARS),
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
function isRecord(value) {
|
|
101
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
102
|
+
}
|
|
103
|
+
function decodeSinkBody(body) {
|
|
104
|
+
return body instanceof Uint8Array ? body : body.body;
|
|
105
|
+
}
|
|
106
|
+
function parseError(value) {
|
|
107
|
+
if (!isRecord(value)) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const name = typeof value.name === "string" ? value.name : "";
|
|
111
|
+
const message = typeof value.message === "string" ? value.message : "";
|
|
112
|
+
const stack = typeof value.stack === "string" ? value.stack : undefined;
|
|
113
|
+
return Object.assign({ name,
|
|
114
|
+
message }, (stack === undefined ? {} : { stack }));
|
|
115
|
+
}
|
|
116
|
+
function parseLogs(value) {
|
|
117
|
+
if (!Array.isArray(value)) {
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
const logs = [];
|
|
121
|
+
for (const entry of value) {
|
|
122
|
+
if (!isRecord(entry)) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (typeof entry.index !== "number" ||
|
|
126
|
+
typeof entry.at !== "string" ||
|
|
127
|
+
typeof entry.line !== "string") {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
logs.push({ index: entry.index, at: entry.at, line: entry.line });
|
|
131
|
+
}
|
|
132
|
+
return logs;
|
|
133
|
+
}
|
|
134
|
+
function parseExecution(value) {
|
|
135
|
+
if (!isRecord(value)) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
const executionId = typeof value.executionId === "string" ? value.executionId : undefined;
|
|
139
|
+
const writtenAt = typeof value.writtenAt === "string" ? value.writtenAt : undefined;
|
|
140
|
+
const sessionId = typeof value.sessionId === "string" ? value.sessionId : undefined;
|
|
141
|
+
const turnStatus = typeof value.turnStatus === "string" ? value.turnStatus : undefined;
|
|
142
|
+
const durationMs = typeof value.durationMs === "number" && Number.isFinite(value.durationMs)
|
|
143
|
+
? value.durationMs
|
|
144
|
+
: undefined;
|
|
145
|
+
if (executionId === undefined ||
|
|
146
|
+
executionId.length === 0 ||
|
|
147
|
+
writtenAt === undefined ||
|
|
148
|
+
sessionId === undefined ||
|
|
149
|
+
turnStatus === undefined ||
|
|
150
|
+
turnStatus.length === 0 ||
|
|
151
|
+
durationMs === undefined ||
|
|
152
|
+
durationMs < 0) {
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
const abortReason = typeof value.abortReason === "string" ? value.abortReason : undefined;
|
|
156
|
+
const message = typeof value.message === "string" ? value.message : undefined;
|
|
157
|
+
const error = parseError(value.error);
|
|
158
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ executionId,
|
|
159
|
+
writtenAt,
|
|
160
|
+
sessionId,
|
|
161
|
+
turnStatus,
|
|
162
|
+
durationMs }, (abortReason === undefined
|
|
163
|
+
? {}
|
|
164
|
+
: { abortReason: abortReason })), (message === undefined ? {} : { message })), (error === undefined ? {} : { error })), (value.processDeath === true ? { processDeath: true } : {})), { logs: parseLogs(value.logs) });
|
|
165
|
+
}
|
|
166
|
+
export function lastFailureFromExecutions(executions) {
|
|
167
|
+
const latest = executions.at(-1);
|
|
168
|
+
if (latest === undefined || latest.turnStatus === "finished") {
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
return Object.assign(Object.assign(Object.assign(Object.assign({ executionId: latest.executionId, writtenAt: latest.writtenAt, turnStatus: latest.turnStatus }, (latest.abortReason === undefined
|
|
172
|
+
? {}
|
|
173
|
+
: { abortReason: latest.abortReason })), (latest.message === undefined ? {} : { message: latest.message })), (latest.error === undefined ? {} : { error: latest.error })), (latest.processDeath === true ? { processDeath: true } : {}));
|
|
174
|
+
}
|
|
175
|
+
function boundExecution(write) {
|
|
176
|
+
const error = write.error === undefined
|
|
177
|
+
? undefined
|
|
178
|
+
: Object.assign({ name: boundedText(write.error.name, 128), message: boundedText(write.error.message, MAX_ERROR_MESSAGE_CHARS) }, (write.error.stack === undefined
|
|
179
|
+
? {}
|
|
180
|
+
: {
|
|
181
|
+
stack: boundedText(write.error.stack, MAX_ERROR_STACK_CHARS),
|
|
182
|
+
}));
|
|
183
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ executionId: write.executionId, writtenAt: write.writtenAt, sessionId: write.sessionId, turnStatus: write.turnStatus, durationMs: write.durationMs }, (write.abortReason === undefined
|
|
184
|
+
? {}
|
|
185
|
+
: { abortReason: write.abortReason })), (boundedOptionalText(write.message, MAX_ERROR_MESSAGE_CHARS) ===
|
|
186
|
+
undefined
|
|
187
|
+
? {}
|
|
188
|
+
: {
|
|
189
|
+
message: boundedOptionalText(write.message, MAX_ERROR_MESSAGE_CHARS),
|
|
190
|
+
})), (error === undefined ? {} : { error })), (write.processDeath === true ? { processDeath: true } : {})), { logs: snapshotSessionRunLogs(write.logs) });
|
|
191
|
+
}
|
|
192
|
+
function upsertExecution(existing, next) {
|
|
193
|
+
const executions = existing.filter((entry) => entry.executionId !== next.executionId);
|
|
194
|
+
executions.push(next);
|
|
195
|
+
executions.sort((a, b) => a.writtenAt.localeCompare(b.writtenAt));
|
|
196
|
+
return executions.slice(-SESSION_RUN_LOG_MAX_EXECUTIONS);
|
|
197
|
+
}
|
|
198
|
+
function shrinkSessionDocument(document) {
|
|
199
|
+
let executions = document.executions;
|
|
200
|
+
let next = Object.assign(Object.assign({}, document), { executions, lastFailure: lastFailureFromExecutions(executions) });
|
|
201
|
+
let serialized = JSON.stringify(next);
|
|
202
|
+
while (serialized.length > MAX_DOCUMENT_CHARS) {
|
|
203
|
+
const oldestWithLogs = executions.findIndex((entry) => entry.logs.length > 0);
|
|
204
|
+
if (oldestWithLogs >= 0) {
|
|
205
|
+
const entry = executions[oldestWithLogs];
|
|
206
|
+
executions = executions.map((item, index) => index === oldestWithLogs
|
|
207
|
+
? Object.assign(Object.assign({}, entry), { logs: entry.logs.slice(Math.ceil(entry.logs.length / 2)) }) : item);
|
|
208
|
+
}
|
|
209
|
+
else if (executions.length > 1) {
|
|
210
|
+
executions = executions.slice(1);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
next = Object.assign(Object.assign({}, document), { executions, lastFailure: lastFailureFromExecutions(executions) });
|
|
216
|
+
serialized = JSON.stringify(next);
|
|
217
|
+
}
|
|
218
|
+
return next;
|
|
219
|
+
}
|
|
220
|
+
export function parseSessionRunLogDocument(value) {
|
|
221
|
+
if (!isRecord(value) || value.v !== SESSION_RUN_LOG_VERSION) {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
const sessionPublicId = typeof value.sessionPublicId === "string"
|
|
225
|
+
? value.sessionPublicId
|
|
226
|
+
: undefined;
|
|
227
|
+
const updatedAt = typeof value.updatedAt === "string" ? value.updatedAt : undefined;
|
|
228
|
+
if (sessionPublicId === undefined ||
|
|
229
|
+
sessionPublicId.length === 0 ||
|
|
230
|
+
updatedAt === undefined ||
|
|
231
|
+
!Array.isArray(value.executions)) {
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
234
|
+
const executions = [];
|
|
235
|
+
for (const entry of value.executions) {
|
|
236
|
+
const parsed = parseExecution(entry);
|
|
237
|
+
if (parsed !== undefined) {
|
|
238
|
+
executions.push(parsed);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
executions.sort((a, b) => a.writtenAt.localeCompare(b.writtenAt));
|
|
242
|
+
const lastFailure = lastFailureFromExecutions(executions);
|
|
243
|
+
return Object.assign(Object.assign({ v: SESSION_RUN_LOG_VERSION, sessionPublicId,
|
|
244
|
+
updatedAt }, (lastFailure === undefined ? {} : { lastFailure })), { executions });
|
|
245
|
+
}
|
|
246
|
+
export function createSessionRunLogStore(input) {
|
|
247
|
+
var _a;
|
|
248
|
+
const { sink, agentName } = input;
|
|
249
|
+
const logger = (_a = input.logger) !== null && _a !== void 0 ? _a : (() => { });
|
|
250
|
+
let active;
|
|
251
|
+
const readDocument = (sessionPublicId) => __awaiter(this, void 0, void 0, function* () {
|
|
252
|
+
const key = storageKeys.sessionRun(agentName, sessionPublicId);
|
|
253
|
+
const body = yield sink.get(key);
|
|
254
|
+
if (body === undefined) {
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
return parseSessionRunLogDocument(JSON.parse(new TextDecoder().decode(decodeSinkBody(body))));
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
logger(`[agent-sdk] session-run log: skip unreadable ${key} (${describeError(error)})`);
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
const persistWrite = (write) => __awaiter(this, void 0, void 0, function* () {
|
|
266
|
+
var _a;
|
|
267
|
+
const fitted = boundExecution(write);
|
|
268
|
+
let existing;
|
|
269
|
+
try {
|
|
270
|
+
existing = yield readDocument(write.sessionPublicId);
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
logger(`[agent-sdk] session-run log: persist failed for ${fitted.executionId} (${describeError(error)})`);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const executions = upsertExecution((_a = existing === null || existing === void 0 ? void 0 : existing.executions) !== null && _a !== void 0 ? _a : [], fitted);
|
|
277
|
+
const document = shrinkSessionDocument({
|
|
278
|
+
v: SESSION_RUN_LOG_VERSION,
|
|
279
|
+
sessionPublicId: write.sessionPublicId,
|
|
280
|
+
updatedAt: fitted.writtenAt,
|
|
281
|
+
executions,
|
|
282
|
+
});
|
|
283
|
+
const key = storageKeys.sessionRun(agentName, document.sessionPublicId);
|
|
284
|
+
try {
|
|
285
|
+
yield sink.put(key, new TextEncoder().encode(JSON.stringify(document)));
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
logger(`[agent-sdk] session-run log: persist failed for ${fitted.executionId} (${describeError(error)})`);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (fitted.turnStatus === "running") {
|
|
292
|
+
active = {
|
|
293
|
+
sessionPublicId: write.sessionPublicId,
|
|
294
|
+
executionId: fitted.executionId,
|
|
295
|
+
sessionId: fitted.sessionId,
|
|
296
|
+
startedAt: Date.now(),
|
|
297
|
+
};
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if ((active === null || active === void 0 ? void 0 : active.executionId) === fitted.executionId) {
|
|
301
|
+
active = undefined;
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
return {
|
|
305
|
+
persist: persistWrite,
|
|
306
|
+
read(sessionPublicId) {
|
|
307
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
308
|
+
try {
|
|
309
|
+
return yield readDocument(sessionPublicId);
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
logger(`[agent-sdk] session-run log: read failed for ${sessionPublicId} (${describeError(error)})`);
|
|
313
|
+
return undefined;
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
},
|
|
317
|
+
flushProcessDeath(reason, error) {
|
|
318
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
319
|
+
var _a;
|
|
320
|
+
var _b;
|
|
321
|
+
if (active === undefined) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
const current = active;
|
|
325
|
+
const serialized = error === undefined ? undefined : serializeSessionRunError(error);
|
|
326
|
+
const message = error instanceof Error
|
|
327
|
+
? error.message
|
|
328
|
+
: error !== undefined
|
|
329
|
+
? String(error)
|
|
330
|
+
: "process died during hosted execution";
|
|
331
|
+
yield persistWrite(Object.assign(Object.assign({ sessionPublicId: current.sessionPublicId, executionId: current.executionId, writtenAt: new Date().toISOString(), sessionId: current.sessionId, turnStatus: "error", durationMs: Math.max(0, Date.now() - current.startedAt), abortReason: reason, processDeath: true, message }, (serialized === undefined ? {} : { error: serialized })), { logs: snapshotSessionRunLogs((_b = (_a = input.snapshotLogs) === null || _a === void 0 ? void 0 : _a.call(input)) !== null && _b !== void 0 ? _b : []) }));
|
|
332
|
+
});
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Same selection as the conversation mirror: architecture-v2 hosted
|
|
338
|
+
* engines with a provisioned framework file store. Self-hosted and v1
|
|
339
|
+
* stay on local disk / today's behavior. This is the only path that
|
|
340
|
+
* installs the session-run log — v1 never writes these documents.
|
|
341
|
+
*/
|
|
342
|
+
export function selectSessionRunLogStore(input) {
|
|
343
|
+
var _a;
|
|
344
|
+
if (input.project.agent.architecture !== "v2") {
|
|
345
|
+
return undefined;
|
|
346
|
+
}
|
|
347
|
+
const env = (_a = input.env) !== null && _a !== void 0 ? _a : process.env;
|
|
348
|
+
const frameworkStoreId = cursorFrameworkStoreSourceId(env);
|
|
349
|
+
if (env[AGENT_SERVE_GENERATION_ENV_VAR] === undefined ||
|
|
350
|
+
frameworkStoreId === undefined) {
|
|
351
|
+
return undefined;
|
|
352
|
+
}
|
|
353
|
+
return createSessionRunLogStore(Object.assign({ sink: cursorHostedFiles({
|
|
354
|
+
storeSourceId: frameworkStoreId,
|
|
355
|
+
resolveApiKey: () => { var _a; return (_a = resolveApiKeySync()) === null || _a === void 0 ? void 0 : _a.apiKey; },
|
|
356
|
+
}), agentName: input.project.name, logger: input.logger }, (input.snapshotLogs === undefined
|
|
357
|
+
? {}
|
|
358
|
+
: { snapshotLogs: input.snapshotLogs })));
|
|
359
|
+
}
|
|
@@ -10,16 +10,18 @@ export interface ListedSessions {
|
|
|
10
10
|
/** Present when the server reports which store answered. */
|
|
11
11
|
source?: SessionListSource;
|
|
12
12
|
}
|
|
13
|
-
export
|
|
13
|
+
export interface ListSessionsArgs {
|
|
14
14
|
baseUrl: string;
|
|
15
15
|
auth?: RequestAuth;
|
|
16
16
|
fetchImpl?: typeof fetch;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
17
|
+
/**
|
|
18
|
+
* Ask for only the newest visible session (`?latest=1`). The server
|
|
19
|
+
* answers from memory where it can instead of scanning durable storage.
|
|
20
|
+
*/
|
|
21
|
+
latest?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function listSessions(args: ListSessionsArgs): Promise<SessionSummary[]>;
|
|
24
|
+
export declare function listSessionsWithSource(args: ListSessionsArgs): Promise<ListedSessions>;
|
|
23
25
|
export declare function fetchSessionEvents(args: {
|
|
24
26
|
baseUrl: string;
|
|
25
27
|
sessionId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions-client.d.ts","sourceRoot":"","sources":["../../src/internal/sessions-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE7E,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,
|
|
1
|
+
{"version":3,"file":"sessions-client.d.ts","sourceRoot":"","sources":["../../src/internal/sessions-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE7E,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,cAAc,EAAE,CAAC,CAE3B;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,cAAc,CAAC,CAkCzB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAuE1B;AAmCD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAClC,cAAc,GAAG,SAAS,CAU5B;AAED,+DAA+D;AAC/D,wBAAsB,wBAAwB,CAAC,IAAI,EAAE;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO9B;AAED,+DAA+D;AAC/D,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAIzE;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAAE,GACvC,MAAM,CAkBR"}
|
|
@@ -24,9 +24,10 @@ export function listSessionsWithSource(args) {
|
|
|
24
24
|
var _a;
|
|
25
25
|
const baseUrl = args.baseUrl.replace(/\/$/, "");
|
|
26
26
|
const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
|
|
27
|
+
const query = args.latest === true ? "?latest=1" : "";
|
|
27
28
|
let resp;
|
|
28
29
|
try {
|
|
29
|
-
resp = yield fetchImpl(`${baseUrl}/v1/sessions`, {
|
|
30
|
+
resp = yield fetchImpl(`${baseUrl}/v1/sessions${query}`, {
|
|
30
31
|
headers: mergeRequestHeaders(args.auth),
|
|
31
32
|
});
|
|
32
33
|
}
|
|
@@ -146,6 +147,7 @@ function parseSessionSummary(value) {
|
|
|
146
147
|
queued: typeof row.queued === "boolean" ? row.queued : undefined,
|
|
147
148
|
createdAt: typeof row.createdAt === "string" ? row.createdAt : "",
|
|
148
149
|
updatedAt: typeof row.updatedAt === "string" ? row.updatedAt : "",
|
|
150
|
+
dryRun: row.dryRun === true ? true : undefined,
|
|
149
151
|
continuationToken,
|
|
150
152
|
externalUrl: typeof row.externalUrl === "string" ? row.externalUrl : undefined,
|
|
151
153
|
prUrl: typeof row.prUrl === "string" ? row.prUrl : undefined,
|
|
@@ -98,6 +98,13 @@ export declare class StorageCoordinator implements FrameworkSessionStore, Author
|
|
|
98
98
|
* so the caller can fall back to the local session store.
|
|
99
99
|
*/
|
|
100
100
|
listSessionsFromSink(): Promise<SessionRecord[]>;
|
|
101
|
+
/**
|
|
102
|
+
* Newest-written session records from the sink (`GET /v1/sessions?latest=1`
|
|
103
|
+
* on a host whose local store has nothing for the caller). Same error
|
|
104
|
+
* posture as {@link listSessionsFromSink}; `undefined` when the sink
|
|
105
|
+
* cannot order by write time, so the caller falls back to the full list.
|
|
106
|
+
*/
|
|
107
|
+
listNewestSessionsFromSink(limit: number): Promise<SessionRecord[] | undefined>;
|
|
101
108
|
/**
|
|
102
109
|
* Saved event stream for one session: chunk values concatenated in key
|
|
103
110
|
* order (chunks are keyed by their first event's index, zero-padded, so
|
|
@@ -124,6 +131,12 @@ export declare class StorageCoordinator implements FrameworkSessionStore, Author
|
|
|
124
131
|
/**
|
|
125
132
|
* Whether the sink can serve awaited author reads/writes (`get` is
|
|
126
133
|
* required — `put` is always present on {@link StorageConfig}).
|
|
134
|
+
*
|
|
135
|
+
* A sink may keep `get` for framework session state while refusing author
|
|
136
|
+
* KV: hosted v2 reads sessions from the framework file store but has no
|
|
137
|
+
* working KV backend, and author handlers that cannot read their own
|
|
138
|
+
* writes back are better served by the local-disk fallback than by a sink
|
|
139
|
+
* that accepts every write and forgets it.
|
|
127
140
|
*/
|
|
128
141
|
get supportsAuthorKv(): boolean;
|
|
129
142
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-coordinator.d.ts","sourceRoot":"","sources":["../../src/internal/storage-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,OAAO,EACL,KAAK,qBAAqB,EAE1B,KAAK,cAAc,EACnB,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"storage-coordinator.d.ts","sourceRoot":"","sources":["../../src/internal/storage-coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,6 +34,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
34
34
|
import { resolveStoragePolicy, storageKeys, } from "../storage.js";
|
|
35
35
|
import { isCursorHostedStorage } from "../storage-backends/cursor-hosted.js";
|
|
36
36
|
import { describeError } from "./describe-error.js";
|
|
37
|
+
import { isAuthorKvUnsupported } from "./null-kv-storage.js";
|
|
37
38
|
/** Event types that close a unit of work — flush point for turn-end batching. */
|
|
38
39
|
const TURN_BOUNDARY_EVENTS = new Set([
|
|
39
40
|
"turn.completed",
|
|
@@ -62,6 +63,14 @@ const DEBOUNCE_MAX_BATCH = 200;
|
|
|
62
63
|
* convenience backfill, not a source of truth.
|
|
63
64
|
*/
|
|
64
65
|
const AB_SNAPSHOT_MIN_INTERVAL_MS = 60000;
|
|
66
|
+
/** Session records out of raw sink entries; rows without a usable id are dropped. */
|
|
67
|
+
function sessionRecordsOf(entries) {
|
|
68
|
+
return entries
|
|
69
|
+
.map((entry) => entry.value)
|
|
70
|
+
.filter((record) => record != null &&
|
|
71
|
+
typeof record.sessionId === "string" &&
|
|
72
|
+
record.sessionId !== "");
|
|
73
|
+
}
|
|
65
74
|
export class StorageCoordinator {
|
|
66
75
|
constructor(options) {
|
|
67
76
|
/** Per-session pending state (events + coalesced record). */
|
|
@@ -233,11 +242,26 @@ export class StorageCoordinator {
|
|
|
233
242
|
if (!Array.isArray(entries)) {
|
|
234
243
|
throw new Error("storage list returned a non-array");
|
|
235
244
|
}
|
|
236
|
-
return entries
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
245
|
+
return sessionRecordsOf(entries);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Newest-written session records from the sink (`GET /v1/sessions?latest=1`
|
|
250
|
+
* on a host whose local store has nothing for the caller). Same error
|
|
251
|
+
* posture as {@link listSessionsFromSink}; `undefined` when the sink
|
|
252
|
+
* cannot order by write time, so the caller falls back to the full list.
|
|
253
|
+
*/
|
|
254
|
+
listNewestSessionsFromSink(limit) {
|
|
255
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
256
|
+
const listNewest = this.definition.listNewest;
|
|
257
|
+
if (listNewest === undefined) {
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
const entries = yield listNewest(storageKeys.sessionPrefix(this.agentName), limit, this.context("restore"));
|
|
261
|
+
if (!Array.isArray(entries)) {
|
|
262
|
+
throw new Error("storage listNewest returned a non-array");
|
|
263
|
+
}
|
|
264
|
+
return sessionRecordsOf(entries);
|
|
241
265
|
});
|
|
242
266
|
}
|
|
243
267
|
/**
|
|
@@ -333,9 +357,16 @@ export class StorageCoordinator {
|
|
|
333
357
|
/**
|
|
334
358
|
* Whether the sink can serve awaited author reads/writes (`get` is
|
|
335
359
|
* required — `put` is always present on {@link StorageConfig}).
|
|
360
|
+
*
|
|
361
|
+
* A sink may keep `get` for framework session state while refusing author
|
|
362
|
+
* KV: hosted v2 reads sessions from the framework file store but has no
|
|
363
|
+
* working KV backend, and author handlers that cannot read their own
|
|
364
|
+
* writes back are better served by the local-disk fallback than by a sink
|
|
365
|
+
* that accepts every write and forgets it.
|
|
336
366
|
*/
|
|
337
367
|
get supportsAuthorKv() {
|
|
338
|
-
return this.definition.get !== undefined
|
|
368
|
+
return (this.definition.get !== undefined &&
|
|
369
|
+
!isAuthorKvUnsupported(this.definition));
|
|
339
370
|
}
|
|
340
371
|
/**
|
|
341
372
|
* Awaited author KV read. Unlike framework session mirrors, this awaits
|