@cursor/bdk 0.2.11 → 0.2.12
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/dist/bin/agent-serve.js +28 -26
- package/dist/channels/bitbucket/api.js +8 -8
- package/dist/channels/bitbucket/binding.js +4 -4
- package/dist/channels/bitbucket/bitbucket-channel.js +1 -1
- package/dist/channels/bitbucket/bitbucket-webhook.js +1 -1
- package/dist/channels/bitbucket/checks.js +1 -1
- package/dist/channels/bitbucket/cursor-account.js +1 -1
- package/dist/channels/bitbucket/events.js +1 -1
- package/dist/channels/change-monitors/change-monitors-channel.js +1 -1
- package/dist/channels/checks.js +2 -2
- package/dist/channels/deployments/deployments-channel.js +1 -1
- package/dist/channels/github/cursor-account.js +3 -3
- package/dist/channels/github/defaults.js +3 -3
- package/dist/channels/github/events.js +1 -1
- package/dist/channels/github/forward.js +8 -8
- package/dist/channels/github/github-channel.js +2 -2
- package/dist/channels/gitlab/binding.js +4 -4
- package/dist/channels/gitlab/checks.js +1 -1
- package/dist/channels/gitlab/cursor-account.js +1 -1
- package/dist/channels/gitlab/events.js +1 -1
- package/dist/channels/gitlab/gitlab-channel.js +1 -1
- package/dist/channels/gitlab/gitlab-webhook.js +1 -1
- package/dist/channels/gitlab/replay.js +2 -2
- package/dist/channels/origin/binding.js +3 -3
- package/dist/channels/origin/checks.js +1 -1
- package/dist/channels/origin/cursor-account.js +1 -1
- package/dist/channels/origin/events.js +1 -1
- package/dist/channels/origin/origin-channel.js +1 -1
- package/dist/channels/origin/origin-webhook.js +2 -2
- package/dist/channels/slack/agentic-delivery.js +3 -3
- package/dist/channels/slack/agentic-signals.js +1 -1
- package/dist/channels/slack/api.js +5 -5
- package/dist/channels/slack/approvals.js +1 -1
- package/dist/channels/slack/attachments.js +3 -3
- package/dist/channels/slack/blocks.js +3 -3
- package/dist/channels/slack/bot-mentions.js +4 -4
- package/dist/channels/slack/channel-watch.js +4 -4
- package/dist/channels/slack/cli-project.js +3 -3
- package/dist/channels/slack/dispatch.js +1 -1
- package/dist/channels/slack/doctor.js +1 -1
- package/dist/channels/slack/eval-directive.js +1 -1
- package/dist/channels/slack/footer.js +1 -1
- package/dist/channels/slack/interactive.js +2 -2
- package/dist/channels/slack/log.d.ts.map +1 -1
- package/dist/channels/slack/log.js +1 -1
- package/dist/channels/slack/manifest.js +1 -1
- package/dist/channels/slack/nudge-carrier.js +1 -1
- package/dist/channels/slack/nudge-store.js +2 -2
- package/dist/channels/slack/recording-sink.js +6 -6
- package/dist/channels/slack/reply-options.js +6 -6
- package/dist/channels/slack/self-identity.d.ts +7 -4
- package/dist/channels/slack/self-identity.d.ts.map +1 -1
- package/dist/channels/slack/self-identity.js +17 -8
- package/dist/channels/slack/sender-name.d.ts.map +1 -1
- package/dist/channels/slack/sender-name.js +2 -6
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +1 -1
- package/dist/channels/slack/slack-channel.js +2 -2
- package/dist/channels/slack/socket-mode.js +2 -2
- package/dist/channels/slack/thread-context.js +8 -8
- package/dist/channels/slack/tool-cards.js +1 -1
- package/dist/channels/slack/user-info.d.ts +2 -1
- package/dist/channels/slack/user-info.d.ts.map +1 -1
- package/dist/channels/slack/user-info.js +16 -1
- package/dist/channels.js +1 -1
- package/dist/docs/404.html +3 -3
- package/dist/docs/assets/{app.DXI7bwox.js → app.CKta5zX1.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot.DtlCe4t6.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BrbO5mEe.js → VPLocalSearchBox.4vRM3EDG.js} +2 -2
- package/dist/docs/assets/chunks/{arc.BOG1yms8.js → arc.CofbA8tA.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.C0hsMZnZ.js → architectureDiagram-Q4EWVU46.Mt2UV5M-.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.H044KjKs.js → baseUniq.C_W0Aqp4.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.BsRW6GoB.js → blockDiagram-DXYQGD6D.dAc4goE-.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.B9HV5PFR.js → c4Diagram-AHTNJAMY.dnbRC3Dm.js} +1 -1
- package/dist/docs/assets/chunks/channel.DpljPUVU.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.CPoT_ajl.js → chunk-4BX2VUAB.B42ltSTd.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.DZBwWuCL.js → chunk-4TB4RGXK.2GbAul_E.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.CZ3yTiyq.js → chunk-55IACEB6.pjzY-v-B.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.6DfvHSd8.js → chunk-EDXVE4YY.BB1GXLj2.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.CpBj8HfK.js → chunk-FMBD7UC4.B2WxZkoA.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.BdKo8YqS.js → chunk-OYMX7WX6.BMvb2w73.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BnXNyxJx.js → chunk-QZHKN3VN.Bmu_2lNr.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.Cg1OcF8G.js → chunk-YZCP3GAM.Cth65EaC.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.DFNHq2OM.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.DFNHq2OM.js +1 -0
- package/dist/docs/assets/chunks/clone.DssygCzX.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.1SP8al9c.js → cose-bilkent-S5V4N54A.CrfA7Iw_.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.DS1L6hJt.js → dagre-KV5264BT.PCD6KQDb.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.ChsausbG.js → diagram-5BDNPKRD.CGNlYlP1.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.3XsptNWj.js → diagram-G4DWMVQ6.C0cvryPD.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.DPA9Dk_P.js → diagram-MMDJMWI5.DHlkZHNV.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.BVswXWrB.js → diagram-TYMM5635.DDGqH_4B.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.BSak5OSP.js → erDiagram-SMLLAGMA.4gOY_C3v.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.CQgN4TTz.js → flowDiagram-DWJPFMVM.8i7zsxuh.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.GrT0kA4a.js → ganttDiagram-T4ZO3ILL.BEKHYdM-.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.CdS7Ucll.js → gitGraphDiagram-UUTBAWPF.ACzeLGiB.js} +1 -1
- package/dist/docs/assets/chunks/{graph.BVqKRmRo.js → graph.08C3hS6m.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.C3C9FRto.js → infoDiagram-42DDH7IO.D8R9obOH.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.2FuAh_Zj.js → ishikawaDiagram-UXIWVN3A.CmgYpCWL.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CaHMfK4b.js → journeyDiagram-VCZTEJTY.DUzjGfoZ.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.CjhIUwcA.js → kanban-definition-6JOO6SKY.DbcW2iZ0.js} +1 -1
- package/dist/docs/assets/chunks/{layout.CGU3gfSf.js → layout.BaDEpJzu.js} +1 -1
- package/dist/docs/assets/chunks/{linear.DaihpW_n.js → linear.B_zRQgCU.js} +1 -1
- package/dist/docs/assets/chunks/{min.BS-j8kHQ.js → min.BYscCdSu.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.BVJ1Bbnk.js → mindmap-definition-QFDTVHPH.Ggu0jg86.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.Cz1WIv9r.js → pieDiagram-DEJITSTG.D_q4SVDT.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.DKLFxcjy.js → quadrantDiagram-34T5L4WZ.D3zGj5ok.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.BHegiK7x.js → requirementDiagram-MS252O5E.DVTg7zr2.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.DYkY6yPc.js → sankeyDiagram-XADWPNL6.D3X8jm57.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.DYQ1QUrI.js → sequenceDiagram-FGHM5R23.Dpjai9YP.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.Iru8BsFo.js → stateDiagram-FHFEXIEX.D_AbQBuP.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CWKWRxRx.js +1 -0
- package/dist/docs/assets/chunks/{theme.DaplWQhQ.js → theme.BcgOnbZ6.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BwFA8hiX.js → timeline-definition-GMOUNBTQ.Cp3DKBe2.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CZ60W1C_.js → vennDiagram-DHZGUBPP.Bcvg-Aqu.js} +1 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.CCpdcUSq.js +162 -0
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.B69D2r8-.js → wardleyDiagram-NUSXRM2D.L0yehCc5.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.CLPZEIU9.js → xychartDiagram-5P7HB3ND.Cw8-tJmw.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.Bljpve-y.js → reference_connections.md.DLrgAd5f.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.C5LCJ1R3.js → reference_hooks.md.B-eGa2km.js} +3 -3
- package/dist/docs/assets/{reference_hooks.md.C5LCJ1R3.lean.js → reference_hooks.md.B-eGa2km.lean.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.CM5zo3w4.js → reference_sessions.md.CyM7ARz1.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.v3SXVSs_.js → reference_tools.md.DzIY9JzY.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.v3SXVSs_.lean.js → reference_tools.md.DzIY9JzY.lean.js} +1 -1
- package/dist/docs/assets/{style.C130MVnH.css → style.Dwls12uf.css} +1 -1
- package/dist/docs/building-with-agents.html +37 -37
- package/dist/docs/deployment.html +37 -37
- package/dist/docs/evals.html +37 -37
- package/dist/docs/guides/agent-to-agent.html +37 -37
- package/dist/docs/guides/bitbucket.html +37 -37
- package/dist/docs/guides/cloud-agents.html +37 -37
- package/dist/docs/guides/convert-automation.html +37 -37
- package/dist/docs/guides/github.html +37 -37
- package/dist/docs/guides/gitlab.html +37 -37
- package/dist/docs/guides/grokbot-agents.html +37 -37
- package/dist/docs/guides/hooks.html +37 -37
- package/dist/docs/guides/improve.html +37 -37
- package/dist/docs/guides/jev.html +37 -37
- package/dist/docs/guides/mcp-oauth.html +37 -37
- package/dist/docs/guides/migrate.html +37 -37
- package/dist/docs/guides/opentelemetry.html +37 -37
- package/dist/docs/guides/slack.html +37 -37
- package/dist/docs/guides/webhooks.html +37 -37
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +37 -37
- package/dist/docs/index.html +37 -37
- package/dist/docs/llms-full.txt +15 -2
- package/dist/docs/quickstart.html +37 -37
- package/dist/docs/reference/agent-config.html +37 -37
- package/dist/docs/reference/artifacts.html +37 -37
- package/dist/docs/reference/channels.html +37 -37
- package/dist/docs/reference/cli.html +37 -37
- package/dist/docs/reference/connections.html +39 -39
- package/dist/docs/reference/connections.md +2 -1
- package/dist/docs/reference/evals.html +37 -37
- package/dist/docs/reference/extensions.html +37 -37
- package/dist/docs/reference/hooks.html +39 -39
- package/dist/docs/reference/hooks.md +1 -0
- package/dist/docs/reference/http-api.html +37 -37
- package/dist/docs/reference/instructions.html +37 -37
- package/dist/docs/reference/playground.html +36 -36
- package/dist/docs/reference/project-layout.html +37 -37
- package/dist/docs/reference/prompt.html +37 -37
- package/dist/docs/reference/schedules.html +37 -37
- package/dist/docs/reference/sessions.html +37 -37
- package/dist/docs/reference/sessions.md +1 -1
- package/dist/docs/reference/skills.html +37 -37
- package/dist/docs/reference/subagents.html +37 -37
- package/dist/docs/reference/tools.html +39 -39
- package/dist/docs/reference/tools.md +11 -0
- package/dist/docs/templates/agentic-owners.html +37 -37
- package/dist/docs/templates/grokbot-agents.html +37 -37
- package/dist/docs/templates/security-reviewer.html +37 -37
- package/dist/docs/templates/thermo-quality-review.html +37 -37
- package/dist/docs/templates/thermo-review.html +37 -37
- package/dist/docs/templates/triage.html +37 -37
- package/dist/docs/troubleshooting.html +36 -36
- package/dist/evals/assertions.d.ts.map +1 -1
- package/dist/evals/assertions.js +21 -19
- package/dist/evals/expect.js +1 -1
- package/dist/evals/judge.js +1 -1
- package/dist/evals/reporters.js +8 -8
- package/dist/evals/run-facts.js +2 -2
- package/dist/evals.js +6 -6
- package/dist/extensions/cursor-cloud-agents/extension.d.ts +2 -0
- package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/extension.js +2 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts +16 -0
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +44 -3
- package/dist/extensions/cursor-cloud-agents/lib/fleet.js +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts +23 -0
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.js +32 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.js +2 -2
- package/dist/extensions/cursor-cloud-agents/lib/transcript.js +2 -2
- package/dist/extensions/cursor-cloud-agents/lib/watch.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/watch.js +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/launch.js +3 -8
- package/dist/extensions/cursor-cloud-agents/tools/list.js +1 -1
- package/dist/extensions/cursor-grokbot-agents/extension.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/agents.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.js +4 -4
- package/dist/extensions/cursor-grokbot-agents/tools/list.js +1 -1
- package/dist/extensions/improve/skills/yourself.js +1 -1
- package/dist/extensions/jev/extension.js +2 -2
- package/dist/extensions/jev/tools/evaluate.js +1 -1
- package/dist/extensions/slack-communication/tools/react.js +1 -1
- package/dist/files-backends/cursor-hosted.js +8 -8
- package/dist/files-backends/local-fs.js +1 -1
- package/dist/filesystem.d.ts.map +1 -1
- package/dist/filesystem.js +15 -15
- package/dist/internal/advertise-tools.d.ts +3 -2
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +11 -9
- package/dist/internal/approval-gate.js +1 -1
- package/dist/internal/artifacts-store.js +13 -13
- package/dist/internal/as-of.js +2 -2
- package/dist/internal/authored-alias-hooks.js +1 -1
- package/dist/internal/builtin-tools/reminders.js +2 -2
- package/dist/internal/chat-client.js +5 -5
- package/dist/internal/cli-ax.js +14 -14
- package/dist/internal/cli-bitbucket.js +10 -10
- package/dist/internal/cli-convert-automation.js +2 -2
- package/dist/internal/cli-cursor.js +2 -2
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +40 -40
- package/dist/internal/cli-docs.js +5 -5
- package/dist/internal/cli-github.js +15 -15
- package/dist/internal/cli-gitlab.js +10 -10
- package/dist/internal/cli-images.js +16 -16
- package/dist/internal/cli-manifest.js +1 -1
- package/dist/internal/cli-mcp-oauth.js +5 -5
- package/dist/internal/cli-mcp.js +3 -3
- package/dist/internal/cli-migrate.js +1 -1
- package/dist/internal/cli-skills.js +2 -2
- package/dist/internal/cli-slack.js +5 -5
- package/dist/internal/cloud-turn-cost.js +1 -1
- package/dist/internal/continuation-identity.js +6 -6
- package/dist/internal/conversation-mirror.js +5 -5
- package/dist/internal/convert-automation/convert-workflow.js +24 -24
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +20 -20
- package/dist/internal/cursor/backend-client.js +6 -6
- package/dist/internal/cursor/credentials.js +1 -1
- package/dist/internal/cursor/store-api-client.js +1 -1
- package/dist/internal/cursor-account-mcp-auth.js +9 -9
- package/dist/internal/cursor-deployment-relay.d.ts.map +1 -1
- package/dist/internal/cursor-deployment-relay.js +9 -9
- package/dist/internal/cursor-event-relay.js +10 -10
- package/dist/internal/cursor-relay-core.js +2 -2
- package/dist/internal/deploy-manifest.js +10 -10
- package/dist/internal/discovery/agent-config.js +2 -2
- package/dist/internal/discovery/agent.js +6 -6
- package/dist/internal/discovery/connections.js +5 -5
- package/dist/internal/discovery/cursor-plugin.js +12 -12
- package/dist/internal/discovery/extension-overlay.js +3 -3
- package/dist/internal/discovery/extensions.js +6 -6
- package/dist/internal/discovery/info.js +9 -9
- package/dist/internal/discovery/instructions.js +1 -1
- package/dist/internal/discovery/project.js +3 -3
- package/dist/internal/discovery/services.js +1 -1
- package/dist/internal/discovery/tools.js +1 -1
- package/dist/internal/docs-site.js +2 -2
- package/dist/internal/env-file.js +1 -1
- package/dist/internal/eval-run-store.js +7 -7
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +14 -14
- package/dist/internal/eval-transport.js +1 -1
- package/dist/internal/evals-client.js +4 -4
- package/dist/internal/event-log.js +8 -8
- package/dist/internal/event-mapper.js +13 -13
- package/dist/internal/expected-delivery-failure.js +2 -2
- package/dist/internal/filesystem/format.js +2 -2
- package/dist/internal/filesystem/nearest.js +3 -3
- package/dist/internal/filesystem/scratch.js +3 -3
- package/dist/internal/filesystem/tools.js +6 -6
- package/dist/internal/filesystem/walk.d.ts.map +1 -1
- package/dist/internal/filesystem/walk.js +2 -2
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +6 -5
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +4 -2
- package/dist/internal/github-fanout.d.ts.map +1 -1
- package/dist/internal/github-fanout.js +3 -3
- package/dist/internal/guest-network.js +4 -4
- package/dist/internal/host-files.js +1 -1
- package/dist/internal/host-kv.js +2 -2
- package/dist/internal/hosted-catch-protocol.js +1 -1
- package/dist/internal/hosted-catch.js +1 -1
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +14 -14
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +23 -9
- package/dist/internal/hosted-eval-cases.js +4 -4
- package/dist/internal/hosted-execution-diag.js +3 -3
- package/dist/internal/hosting.js +1 -1
- package/dist/internal/http-channel.js +1 -1
- package/dist/internal/http-control-plane-session.js +2 -2
- package/dist/internal/init-interview.js +7 -7
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +12 -12
- package/dist/internal/inline-stdio-mcp.js +2 -2
- package/dist/internal/install-cursor-skills.js +11 -11
- package/dist/internal/json-schema.js +1 -1
- package/dist/internal/local-control-plane.js +3 -3
- package/dist/internal/local-env.js +3 -3
- package/dist/internal/log-ring.js +1 -1
- package/dist/internal/logs-client.js +1 -1
- package/dist/internal/mcp-endpoint.js +8 -8
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +5 -5
- package/dist/internal/mcp-oauth-on-demand.js +3 -3
- package/dist/internal/mcp-oauth.js +5 -5
- package/dist/internal/net.js +2 -2
- package/dist/internal/otel/config.js +3 -3
- package/dist/internal/otel/runtime.js +13 -13
- package/dist/internal/peer-connections.js +2 -2
- package/dist/internal/persistent-stage-log-mirror.d.ts +57 -0
- package/dist/internal/persistent-stage-log-mirror.d.ts.map +1 -0
- package/dist/internal/persistent-stage-log-mirror.js +231 -0
- package/dist/internal/platform-schedule-sync.js +1 -1
- package/dist/internal/platform-timers.js +1 -1
- package/dist/internal/playground/static.js +2 -2
- package/dist/internal/playground/toolchain.js +2 -2
- package/dist/internal/playground-proxy.js +3 -3
- package/dist/internal/process-memory-telemetry.js +1 -1
- package/dist/internal/reminder-runner.d.ts +1 -1
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +14 -16
- package/dist/internal/reminder-store.js +1 -1
- package/dist/internal/resolved-connections.js +8 -8
- package/dist/internal/router.js +4 -4
- package/dist/internal/run-client.js +2 -2
- package/dist/internal/schedule-runner.js +6 -6
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +6 -6
- package/dist/internal/serve-restart.js +1 -1
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +93 -72
- package/dist/internal/session-cost.js +3 -3
- package/dist/internal/session-engine.d.ts +8 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +183 -118
- package/dist/internal/session-live-publisher.d.ts +46 -0
- package/dist/internal/session-live-publisher.d.ts.map +1 -0
- package/dist/internal/session-live-publisher.js +352 -0
- package/dist/internal/session-run-log.js +6 -6
- package/dist/internal/sessions-client.js +3 -3
- package/dist/internal/skill-catalog.js +2 -2
- package/dist/internal/sleep.js +1 -1
- package/dist/internal/start-log-store.d.ts +5 -1
- package/dist/internal/start-log-store.d.ts.map +1 -1
- package/dist/internal/start-log-store.js +5 -3
- package/dist/internal/storage-coordinator.js +12 -12
- package/dist/internal/store-api-protocol.d.ts +51 -0
- package/dist/internal/store-api-protocol.d.ts.map +1 -1
- package/dist/internal/store-api-protocol.js +39 -2
- package/dist/internal/store-mirror.js +4 -4
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +4 -0
- package/dist/internal/terminal-style.js +2 -2
- package/dist/internal/tool-call-retry.d.ts +87 -0
- package/dist/internal/tool-call-retry.d.ts.map +1 -0
- package/dist/internal/tool-call-retry.js +387 -0
- package/dist/internal/tool-result.js +3 -3
- package/dist/internal/trajectory.js +7 -7
- package/dist/internal/turn-governor.js +2 -2
- package/dist/internal/turn-outbox.js +1 -1
- package/dist/internal/update-check.d.ts.map +1 -1
- package/dist/internal/update-check.js +4 -2
- package/dist/internal/v2-hosting.d.ts +6 -0
- package/dist/internal/v2-hosting.d.ts.map +1 -1
- package/dist/internal/v2-hosting.js +7 -1
- package/dist/internal/workspace.js +4 -4
- package/dist/kv/memory-kv.js +3 -3
- package/dist/playground/assets/{index-Be0-1hw2.js → index-HN5lOuAX.js} +42 -42
- package/dist/playground/assets/index-JY1wKCMg.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/prompt.js +1 -1
- package/dist/storage-backends/cursor-hosted-v2.js +2 -2
- package/dist/storage-backends/file-kv.js +7 -7
- package/dist/storage-protocol.d.ts +7 -0
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +7 -0
- package/dist/storage.js +3 -3
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -4
- package/docs/reference/connections.md +2 -1
- package/docs/reference/hooks.md +1 -0
- package/docs/reference/sessions.md +1 -1
- package/docs/reference/tools.md +11 -0
- package/package.json +6 -6
- package/templates/agentic-owners/bot/channels/github.ts +2 -2
- package/templates/agentic-owners/bot/lib/github.ts +7 -5
- package/templates/agentic-owners/bot/lib/owners/decision.ts +9 -9
- package/templates/agentic-owners/bot/lib/owners/handles.ts +2 -2
- package/templates/agentic-owners/bot/lib/owners/match.ts +5 -3
- package/templates/agentic-owners/bot/lib/owners/matching.ts +1 -1
- package/templates/agentic-owners/bot/lib/owners/parse.ts +4 -4
- package/templates/agentic-owners/bot/lib/owners/prompt.ts +1 -1
- package/templates/agentic-owners/bot/lib/review.ts +18 -17
- package/templates/agentic-owners/evals/owners.eval.ts +2 -2
- package/templates/agents-md/bot/lib/collect.ts +6 -6
- package/templates/agents-md/bot/lib/config.ts +1 -1
- package/templates/agents-md/bot/tools/apply_agents.ts +4 -4
- package/templates/code-wiki/bot/channels/github.ts +3 -3
- package/templates/code-wiki/bot/lib/repos.ts +1 -1
- package/templates/code-wiki/bot/tools/apply_wiki.ts +2 -2
- package/templates/demo/bot/lib/collect.ts +1 -1
- package/templates/demo/bot/lib/repos.ts +1 -1
- package/templates/demo/bot/tools/record_demo.ts +1 -1
- package/templates/pr-autofixer/bot/channels/github.ts +2 -2
- package/templates/pr-autofixer/bot/lib/merge-watch.ts +2 -2
- package/templates/pr-autofixer/bot/lib/repos.ts +2 -2
- package/templates/pr-autofixer/bot/lib/webhook-routing.ts +1 -1
- package/templates/security-help/bot/lib/repos.ts +1 -1
- package/templates/security-reviewer/bot/lib/repos.ts +1 -1
- package/templates/triage/bot/lib/actuate.ts +15 -15
- package/dist/docs/assets/chunks/@localSearchIndexroot.CtLtpWcx.js +0 -1
- package/dist/docs/assets/chunks/channel.CBwrU9rP.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CbC_mrvB.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CbC_mrvB.js +0 -1
- package/dist/docs/assets/chunks/clone.BTvFyY1a.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.BYXl4LW6.js +0 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.iXazD3Z7.js +0 -162
- package/dist/playground/assets/index-Clz6uHj9.css +0 -1
- /package/dist/docs/assets/{reference_connections.md.Bljpve-y.lean.js → reference_connections.md.DLrgAd5f.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.CM5zo3w4.lean.js → reference_sessions.md.CyM7ARz1.lean.js} +0 -0
|
@@ -110,4 +110,55 @@ export type MemoryReadResponse = {
|
|
|
110
110
|
* (`{ code, error }`) with a matching HTTP status.
|
|
111
111
|
*/
|
|
112
112
|
export declare const memoryReadResponseSchema: z.ZodType<MemoryReadResponse>;
|
|
113
|
+
/**
|
|
114
|
+
* Live session relay: the engine posts batches of session events, and the
|
|
115
|
+
* service keeps them only while a viewer is watching that session. The
|
|
116
|
+
* stored transcript stays the durable copy.
|
|
117
|
+
*/
|
|
118
|
+
export declare const STORE_API_SESSION_LIVE_CALL = "session.live";
|
|
119
|
+
/**
|
|
120
|
+
* Cap on one serialized live event. A larger event crosses as a stub with
|
|
121
|
+
* `liveTruncated: true`; viewers reread the stored transcript after the turn.
|
|
122
|
+
*/
|
|
123
|
+
export declare const SESSION_LIVE_MAX_EVENT_BYTES: number;
|
|
124
|
+
/** Cap on one batch's serialized `events`, enforced on both sides. */
|
|
125
|
+
export declare const SESSION_LIVE_MAX_BATCH_BYTES: number;
|
|
126
|
+
export declare const SESSION_LIVE_MAX_BATCH_EVENTS = 500;
|
|
127
|
+
/**
|
|
128
|
+
* One session event as it crosses the live wire. `index` orders and
|
|
129
|
+
* deduplicates events; everything else passes through.
|
|
130
|
+
*/
|
|
131
|
+
export type SessionLiveEventWire = {
|
|
132
|
+
index: number;
|
|
133
|
+
type: string;
|
|
134
|
+
} & Record<string, unknown>;
|
|
135
|
+
export declare const sessionLiveEventWireSchema: z.ZodType<SessionLiveEventWire>;
|
|
136
|
+
/** `session.live` validated payload. An empty batch is a subscription probe. */
|
|
137
|
+
export type SessionLiveWirePayload = {
|
|
138
|
+
sessionId: string;
|
|
139
|
+
events: SessionLiveEventWire[];
|
|
140
|
+
};
|
|
141
|
+
export declare const sessionLivePayloadSchema: z.ZodType<SessionLiveWirePayload>;
|
|
142
|
+
/** The versioned request body for the `session.live` call. */
|
|
143
|
+
export type SessionLiveEnvelope = {
|
|
144
|
+
v: typeof STORE_API_PROTOCOL_VERSION;
|
|
145
|
+
call: typeof STORE_API_SESSION_LIVE_CALL;
|
|
146
|
+
payload: SessionLiveWirePayload;
|
|
147
|
+
};
|
|
148
|
+
/** The whole request body. Unknown envelope fields are stripped (= ignored). */
|
|
149
|
+
export declare const sessionLiveEnvelopeSchema: z.ZodType<SessionLiveEnvelope>;
|
|
150
|
+
/**
|
|
151
|
+
* `session.live` success body. `subscribed` says whether a viewer is
|
|
152
|
+
* watching (the service kept nothing when false), `recheckAfterMs` is the
|
|
153
|
+
* earliest next probe while unsubscribed, and `replayFromIndex` asks the
|
|
154
|
+
* engine to resend its local log from that index.
|
|
155
|
+
*/
|
|
156
|
+
export type SessionLiveResponse = {
|
|
157
|
+
v: typeof STORE_API_PROTOCOL_VERSION;
|
|
158
|
+
ok: true;
|
|
159
|
+
subscribed: boolean;
|
|
160
|
+
recheckAfterMs: number;
|
|
161
|
+
replayFromIndex: number | null;
|
|
162
|
+
};
|
|
163
|
+
export declare const sessionLiveResponseSchema: z.ZodType<SessionLiveResponse>;
|
|
113
164
|
//# sourceMappingURL=store-api-protocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-api-protocol.d.ts","sourceRoot":"","sources":["../../src/internal/store-api-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C,oEAAoE;AACpE,eAAO,MAAM,cAAc,iCAAiC,CAAC;AAE7D,eAAO,MAAM,4BAA4B,kBAAkB,CAAC;AAE5D;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,EAAE,MAAkB,CAAC;AAEhE,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,EAAE,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAYvD,CAAC;AAEjB,yCAAyC;AACzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,oBAAoB,CAAC;CAC9B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"store-api-protocol.d.ts","sourceRoot":"","sources":["../../src/internal/store-api-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -53,7 +53,7 @@ export const memoryAppendPayloadSchema = z.object({
|
|
|
53
53
|
.string()
|
|
54
54
|
.min(1)
|
|
55
55
|
.max(256)
|
|
56
|
-
.refine(name => !name.includes("/") && !name.includes("\\") && name !== "." && name !== "..", {
|
|
56
|
+
.refine((name) => !name.includes("/") && !name.includes("\\") && name !== "." && name !== "..", {
|
|
57
57
|
message: "agent must be a single store key segment",
|
|
58
58
|
}),
|
|
59
59
|
record: turnMemoryRecordWireSchema,
|
|
@@ -82,7 +82,7 @@ export const memoryReadPayloadSchema = z.object({
|
|
|
82
82
|
.string()
|
|
83
83
|
.min(1)
|
|
84
84
|
.max(256)
|
|
85
|
-
.refine(name => !name.includes("/") && !name.includes("\\") && name !== "." && name !== "..", {
|
|
85
|
+
.refine((name) => !name.includes("/") && !name.includes("\\") && name !== "." && name !== "..", {
|
|
86
86
|
message: "agent must be a single store key segment",
|
|
87
87
|
}),
|
|
88
88
|
});
|
|
@@ -106,3 +106,40 @@ export const memoryReadResponseSchema = z.object({
|
|
|
106
106
|
})
|
|
107
107
|
.nullable(),
|
|
108
108
|
});
|
|
109
|
+
/**
|
|
110
|
+
* Live session relay: the engine posts batches of session events, and the
|
|
111
|
+
* service keeps them only while a viewer is watching that session. The
|
|
112
|
+
* stored transcript stays the durable copy.
|
|
113
|
+
*/
|
|
114
|
+
export const STORE_API_SESSION_LIVE_CALL = "session.live";
|
|
115
|
+
/**
|
|
116
|
+
* Cap on one serialized live event. A larger event crosses as a stub with
|
|
117
|
+
* `liveTruncated: true`; viewers reread the stored transcript after the turn.
|
|
118
|
+
*/
|
|
119
|
+
export const SESSION_LIVE_MAX_EVENT_BYTES = 16 * 1024;
|
|
120
|
+
/** Cap on one batch's serialized `events`, enforced on both sides. */
|
|
121
|
+
export const SESSION_LIVE_MAX_BATCH_BYTES = 256 * 1024;
|
|
122
|
+
export const SESSION_LIVE_MAX_BATCH_EVENTS = 500;
|
|
123
|
+
export const sessionLiveEventWireSchema = z
|
|
124
|
+
.object({
|
|
125
|
+
index: z.number().int().min(0),
|
|
126
|
+
type: z.string().min(1),
|
|
127
|
+
})
|
|
128
|
+
.passthrough();
|
|
129
|
+
export const sessionLivePayloadSchema = z.object({
|
|
130
|
+
sessionId: z.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
|
|
131
|
+
events: z.array(sessionLiveEventWireSchema).max(SESSION_LIVE_MAX_BATCH_EVENTS),
|
|
132
|
+
});
|
|
133
|
+
/** The whole request body. Unknown envelope fields are stripped (= ignored). */
|
|
134
|
+
export const sessionLiveEnvelopeSchema = z.object({
|
|
135
|
+
v: z.literal(STORE_API_PROTOCOL_VERSION),
|
|
136
|
+
call: z.literal(STORE_API_SESSION_LIVE_CALL),
|
|
137
|
+
payload: sessionLivePayloadSchema,
|
|
138
|
+
});
|
|
139
|
+
export const sessionLiveResponseSchema = z.object({
|
|
140
|
+
v: z.literal(STORE_API_PROTOCOL_VERSION),
|
|
141
|
+
ok: z.literal(true),
|
|
142
|
+
subscribed: z.boolean(),
|
|
143
|
+
recheckAfterMs: z.number().int().min(0),
|
|
144
|
+
replayFromIndex: z.number().int().min(0).nullable(),
|
|
145
|
+
});
|
|
@@ -13,11 +13,11 @@ import { FileConflictError } from "../files.js";
|
|
|
13
13
|
*/
|
|
14
14
|
export async function mirrorToStore(args) {
|
|
15
15
|
await Promise.all([...args.desired].map(([key, body]) => putLastWriterWins(args.sink, key, body)));
|
|
16
|
-
const listed = await Promise.all([args.prefix, ...(args.legacyPrefixes ?? [])].map(prefix => args.sink.list(prefix)));
|
|
16
|
+
const listed = await Promise.all([args.prefix, ...(args.legacyPrefixes ?? [])].map((prefix) => args.sink.list(prefix)));
|
|
17
17
|
await Promise.all(listed
|
|
18
18
|
.flat()
|
|
19
|
-
.filter(entry => !args.desired.has(entry.key))
|
|
20
|
-
.map(entry => args.sink.delete(entry.key)));
|
|
19
|
+
.filter((entry) => !args.desired.has(entry.key))
|
|
20
|
+
.map((entry) => args.sink.delete(entry.key)));
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* Same refusals as local materialization's `resolveInside`: a rel that
|
|
@@ -31,7 +31,7 @@ export function storeRelPath(relPath, what) {
|
|
|
31
31
|
relPath.includes("\\") ||
|
|
32
32
|
posix.isAbsolute(relPath) ||
|
|
33
33
|
relPath.endsWith("/") ||
|
|
34
|
-
relPath.split("/").some(seg => seg === ".." || seg === ".") ||
|
|
34
|
+
relPath.split("/").some((seg) => seg === ".." || seg === ".") ||
|
|
35
35
|
posix.normalize(relPath) !== relPath) {
|
|
36
36
|
throw new Error(`Refusing ${what} path "${relPath}" (must be a normalized relative path)`);
|
|
37
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-progress.d.ts","sourceRoot":"","sources":["../../src/internal/stream-progress.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAC7C,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"stream-progress.d.ts","sourceRoot":"","sources":["../../src/internal/stream-progress.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAC7C,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,cAAc,CAmOjB"}
|
|
@@ -124,6 +124,10 @@ export function createStreamProgress(options) {
|
|
|
124
124
|
write(` ${mark} ${c.bold(event.data.connection)} ${c.dim(event.data.decision === "approve" ? "connected" : "denied")}\n`);
|
|
125
125
|
break;
|
|
126
126
|
}
|
|
127
|
+
case "action.tool_retry": {
|
|
128
|
+
write(` ${c.yellow("↻")} ${c.bold(event.data.toolName)} ${c.dim(`again as try ${event.data.attempt} (${event.data.reason})`)}\n`);
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
127
131
|
case "action.result": {
|
|
128
132
|
if (event.data.toolName === "task" && event.data.parentCallId === undefined) {
|
|
129
133
|
break;
|
|
@@ -69,7 +69,7 @@ export function terminalHyperlink(url, label, enabled = colorEnabledFor()) {
|
|
|
69
69
|
export function formatTerminalBox(lines, options) {
|
|
70
70
|
const color = options?.color ?? IDENTITY;
|
|
71
71
|
const padding = options?.padding ?? 1;
|
|
72
|
-
const contentWidth = Math.max(options?.minWidth ?? 0, ...lines.map(line => visibleWidth(line)), 1);
|
|
72
|
+
const contentWidth = Math.max(options?.minWidth ?? 0, ...lines.map((line) => visibleWidth(line)), 1);
|
|
73
73
|
const inner = contentWidth + padding * 2;
|
|
74
74
|
const padLine = (line) => {
|
|
75
75
|
const extra = contentWidth - visibleWidth(line);
|
|
@@ -78,7 +78,7 @@ export function formatTerminalBox(lines, options) {
|
|
|
78
78
|
const paint = (line) => color(line);
|
|
79
79
|
const box = [
|
|
80
80
|
paint(`╭${"─".repeat(inner)}╮`),
|
|
81
|
-
...lines.map(line => paint(padLine(line))),
|
|
81
|
+
...lines.map((line) => paint(padLine(line))),
|
|
82
82
|
paint(`╰${"─".repeat(inner)}╯`),
|
|
83
83
|
].join("\n");
|
|
84
84
|
return box;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transient retry for a read-effect tool call that already executed.
|
|
3
|
+
*
|
|
4
|
+
* Writes, unclassified tools, dry-run stubs, approval denials, and
|
|
5
|
+
* validation failures never reach this helper. Auth, elicitation, and a
|
|
6
|
+
* timeout that already ran long enough to repeat are not transient.
|
|
7
|
+
*
|
|
8
|
+
* Backoff is full jitter (base 500ms, cap 4s) and at most 10s asleep per
|
|
9
|
+
* call. An attempt that already ran longer than 15s is not retried, so
|
|
10
|
+
* one slow call plus the backoff budget stays under 30s. Sleep yields the
|
|
11
|
+
* event loop, so a timer can still fire during the wait.
|
|
12
|
+
*/
|
|
13
|
+
import { type Meter } from "@opentelemetry/api";
|
|
14
|
+
import type { ToolEffect } from "../types.js";
|
|
15
|
+
/** Total tries, including the first, for a read-effect call. */
|
|
16
|
+
export declare const TOOL_RETRY_DEFAULT_MAX_ATTEMPTS = 3;
|
|
17
|
+
export declare const TOOL_RETRY_BACKOFF_BASE_MS = 500;
|
|
18
|
+
export declare const TOOL_RETRY_BACKOFF_CAP_MS = 4000;
|
|
19
|
+
/** Cumulative sleep per call. */
|
|
20
|
+
export declare const TOOL_RETRY_BACKOFF_BUDGET_MS = 10000;
|
|
21
|
+
/**
|
|
22
|
+
* An attempt slower than this is not retried. Paired with the backoff
|
|
23
|
+
* budget, the extra wait stays under 30s.
|
|
24
|
+
*/
|
|
25
|
+
export declare const TOOL_RETRY_MAX_ATTEMPT_MS = 15000;
|
|
26
|
+
/** Quiet-stream limit the extra wait must stay under. */
|
|
27
|
+
export declare const TOOL_RETRY_STALL_FAIL_MS = 30000;
|
|
28
|
+
export type ToolRetryReason = "transport" | "http_429" | "http_502" | "http_503" | "http_504" | "mcp_transient";
|
|
29
|
+
export type ToolRetryOutcome = "recovered" | "exhausted" | "not_eligible";
|
|
30
|
+
export interface ToolRetryNotice {
|
|
31
|
+
/** The try that is about to run (2 = first retry). */
|
|
32
|
+
readonly attempt: number;
|
|
33
|
+
readonly reason: ToolRetryReason;
|
|
34
|
+
readonly backoffMs: number;
|
|
35
|
+
readonly connection?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Vendor-reported MCP `isError` result. Distinct from a thrown transport
|
|
39
|
+
* failure so the classifier can require an explicit transient phrase.
|
|
40
|
+
*/
|
|
41
|
+
export declare class McpToolError extends Error {
|
|
42
|
+
readonly connection: string;
|
|
43
|
+
readonly toolName: string;
|
|
44
|
+
readonly vendorMessage: string;
|
|
45
|
+
constructor(args: {
|
|
46
|
+
connection: string;
|
|
47
|
+
toolName: string;
|
|
48
|
+
vendorMessage: string;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export type ToolFailureVerdict = {
|
|
52
|
+
readonly transient: false;
|
|
53
|
+
} | {
|
|
54
|
+
readonly transient: true;
|
|
55
|
+
readonly reason: ToolRetryReason;
|
|
56
|
+
readonly retryAfterMs?: number;
|
|
57
|
+
};
|
|
58
|
+
type SleepFn = (ms: number, signal: AbortSignal | undefined) => Promise<void>;
|
|
59
|
+
/** @internal Test seam. `undefined` restores the real timer. */
|
|
60
|
+
export declare function setToolRetrySleepForTests(sleep: SleepFn | undefined): void;
|
|
61
|
+
/** @internal Test seam. `undefined` restores `Math.random`. */
|
|
62
|
+
export declare function setToolRetryRandomForTests(random: (() => number) | undefined): void;
|
|
63
|
+
/** @internal Test seam. `undefined` restores the global meter. */
|
|
64
|
+
export declare function setToolRetryMeterForTests(meter: Meter | undefined): void;
|
|
65
|
+
export declare function classifyToolFailure(error: unknown): ToolFailureVerdict;
|
|
66
|
+
/**
|
|
67
|
+
* Full-jitter delay for the backoff after `failedAttempt` (1 = first try
|
|
68
|
+
* failed). `Retry-After` replaces the jittered delay and is still capped.
|
|
69
|
+
* Returns `undefined` when the cumulative budget is already spent.
|
|
70
|
+
*/
|
|
71
|
+
export declare function toolRetryBackoffMs(args: {
|
|
72
|
+
failedAttempt: number;
|
|
73
|
+
random: number;
|
|
74
|
+
retryAfterMs?: number;
|
|
75
|
+
spentMs: number;
|
|
76
|
+
}): number | undefined;
|
|
77
|
+
export declare function retryReadOnlyToolCall<T>(args: {
|
|
78
|
+
toolName: string;
|
|
79
|
+
connection?: string;
|
|
80
|
+
effect: ToolEffect | undefined;
|
|
81
|
+
signal?: AbortSignal;
|
|
82
|
+
now?: () => number;
|
|
83
|
+
onRetry?: (notice: ToolRetryNotice) => void;
|
|
84
|
+
execute: () => T | Promise<T>;
|
|
85
|
+
}): Promise<T>;
|
|
86
|
+
export {};
|
|
87
|
+
//# sourceMappingURL=tool-call-retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call-retry.d.ts","sourceRoot":"","sources":["../../src/internal/tool-call-retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transient retry for a read-effect tool call that already executed.
|
|
3
|
+
*
|
|
4
|
+
* Writes, unclassified tools, dry-run stubs, approval denials, and
|
|
5
|
+
* validation failures never reach this helper. Auth, elicitation, and a
|
|
6
|
+
* timeout that already ran long enough to repeat are not transient.
|
|
7
|
+
*
|
|
8
|
+
* Backoff is full jitter (base 500ms, cap 4s) and at most 10s asleep per
|
|
9
|
+
* call. An attempt that already ran longer than 15s is not retried, so
|
|
10
|
+
* one slow call plus the backoff budget stays under 30s. Sleep yields the
|
|
11
|
+
* event loop, so a timer can still fire during the wait.
|
|
12
|
+
*/
|
|
13
|
+
import { metrics } from "@opentelemetry/api";
|
|
14
|
+
/** Total tries, including the first, for a read-effect call. */
|
|
15
|
+
export const TOOL_RETRY_DEFAULT_MAX_ATTEMPTS = 3;
|
|
16
|
+
export const TOOL_RETRY_BACKOFF_BASE_MS = 500;
|
|
17
|
+
export const TOOL_RETRY_BACKOFF_CAP_MS = 4_000;
|
|
18
|
+
/** Cumulative sleep per call. */
|
|
19
|
+
export const TOOL_RETRY_BACKOFF_BUDGET_MS = 10_000;
|
|
20
|
+
/**
|
|
21
|
+
* An attempt slower than this is not retried. Paired with the backoff
|
|
22
|
+
* budget, the extra wait stays under 30s.
|
|
23
|
+
*/
|
|
24
|
+
export const TOOL_RETRY_MAX_ATTEMPT_MS = 15_000;
|
|
25
|
+
/** Quiet-stream limit the extra wait must stay under. */
|
|
26
|
+
export const TOOL_RETRY_STALL_FAIL_MS = 30_000;
|
|
27
|
+
const METRIC_NAME = "agent_sdk.tool.retry";
|
|
28
|
+
const TRANSIENT_CODES = new Set([
|
|
29
|
+
"ECONNRESET",
|
|
30
|
+
"ECONNREFUSED",
|
|
31
|
+
"EAI_AGAIN",
|
|
32
|
+
"EPIPE",
|
|
33
|
+
"ETIMEDOUT",
|
|
34
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
35
|
+
"UND_ERR_SOCKET",
|
|
36
|
+
"UND_ERR_CLOSED",
|
|
37
|
+
]);
|
|
38
|
+
const TRANSIENT_HTTP_STATUS = new Set([429, 502, 503, 504]);
|
|
39
|
+
const MAX_CAUSE_DEPTH = 8;
|
|
40
|
+
const ENDPOINT_DEADLINE = /tool call timed out after \d+\s*ms/i;
|
|
41
|
+
const TIMEOUT_WORD = /timed?\s*out|\btimeout\b/i;
|
|
42
|
+
const OVERSIZE = /too large|\boversize\b|payload exceeds|result exceeds/i;
|
|
43
|
+
const AUTH_TEXT = /needsauth|needs authorization|\belicitation\b|\bunauthorized\b/i;
|
|
44
|
+
const TRANSPORT_TEXT = /econnreset|econnrefused|socket hang up|fetch failed|eai_again|und_err_connect|und_err_socket|connection closed/i;
|
|
45
|
+
const HTTP_STATUS_TEXT = /\b(?:HTTP\s*)?(429|502|503|504)\b/i;
|
|
46
|
+
const MCP_TRANSIENT_TEXT = /rate limit|temporarily unavailable|(?<!do not )try again/i;
|
|
47
|
+
const RETRY_AFTER_TEXT = /retry-after[^\d]{0,16}(\d+(?:\.\d+)?)/i;
|
|
48
|
+
/**
|
|
49
|
+
* Vendor-reported MCP `isError` result. Distinct from a thrown transport
|
|
50
|
+
* failure so the classifier can require an explicit transient phrase.
|
|
51
|
+
*/
|
|
52
|
+
export class McpToolError extends Error {
|
|
53
|
+
constructor(args) {
|
|
54
|
+
super(args.vendorMessage === ""
|
|
55
|
+
? `${args.connection} tool ${args.toolName} failed`
|
|
56
|
+
: args.vendorMessage);
|
|
57
|
+
this.name = "McpToolError";
|
|
58
|
+
this.connection = args.connection;
|
|
59
|
+
this.toolName = args.toolName;
|
|
60
|
+
this.vendorMessage = args.vendorMessage;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
let sleepImpl = defaultSleep;
|
|
64
|
+
let randomImpl = Math.random;
|
|
65
|
+
let meterOverride;
|
|
66
|
+
let counterCache;
|
|
67
|
+
/** @internal Test seam. `undefined` restores the real timer. */
|
|
68
|
+
export function setToolRetrySleepForTests(sleep) {
|
|
69
|
+
sleepImpl = sleep ?? defaultSleep;
|
|
70
|
+
}
|
|
71
|
+
/** @internal Test seam. `undefined` restores `Math.random`. */
|
|
72
|
+
export function setToolRetryRandomForTests(random) {
|
|
73
|
+
randomImpl = random ?? Math.random;
|
|
74
|
+
}
|
|
75
|
+
/** @internal Test seam. `undefined` restores the global meter. */
|
|
76
|
+
export function setToolRetryMeterForTests(meter) {
|
|
77
|
+
meterOverride = meter;
|
|
78
|
+
counterCache = undefined;
|
|
79
|
+
}
|
|
80
|
+
export function classifyToolFailure(error) {
|
|
81
|
+
return classifyAtDepth(error, 0);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Full-jitter delay for the backoff after `failedAttempt` (1 = first try
|
|
85
|
+
* failed). `Retry-After` replaces the jittered delay and is still capped.
|
|
86
|
+
* Returns `undefined` when the cumulative budget is already spent.
|
|
87
|
+
*/
|
|
88
|
+
export function toolRetryBackoffMs(args) {
|
|
89
|
+
const remaining = TOOL_RETRY_BACKOFF_BUDGET_MS - args.spentMs;
|
|
90
|
+
if (remaining <= 0) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const unit = Math.min(Math.max(args.random, 0), 1);
|
|
94
|
+
const exp = TOOL_RETRY_BACKOFF_BASE_MS * 2 ** Math.max(0, args.failedAttempt - 1);
|
|
95
|
+
const jittered = unit * Math.min(TOOL_RETRY_BACKOFF_CAP_MS, exp);
|
|
96
|
+
const chosen = args.retryAfterMs !== undefined && Number.isFinite(args.retryAfterMs) && args.retryAfterMs >= 0
|
|
97
|
+
? args.retryAfterMs
|
|
98
|
+
: jittered;
|
|
99
|
+
return Math.min(chosen, TOOL_RETRY_BACKOFF_CAP_MS, remaining);
|
|
100
|
+
}
|
|
101
|
+
export async function retryReadOnlyToolCall(args) {
|
|
102
|
+
const maxAttempts = TOOL_RETRY_DEFAULT_MAX_ATTEMPTS;
|
|
103
|
+
const eligible = args.effect === "read";
|
|
104
|
+
if (!eligible) {
|
|
105
|
+
try {
|
|
106
|
+
return await args.execute();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (classifyToolFailure(error).transient) {
|
|
110
|
+
recordOutcome("not_eligible");
|
|
111
|
+
}
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const now = args.now ?? Date.now;
|
|
116
|
+
let spentMs = 0;
|
|
117
|
+
let lastError;
|
|
118
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
119
|
+
throwIfAborted(args.signal);
|
|
120
|
+
const started = now();
|
|
121
|
+
try {
|
|
122
|
+
const result = await args.execute();
|
|
123
|
+
if (attempt > 1) {
|
|
124
|
+
recordOutcome("recovered");
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
lastError = error;
|
|
130
|
+
if (args.signal?.aborted === true) {
|
|
131
|
+
throw abortError(args.signal);
|
|
132
|
+
}
|
|
133
|
+
const elapsed = now() - started;
|
|
134
|
+
const verdict = classifyToolFailure(error);
|
|
135
|
+
const slow = elapsed > TOOL_RETRY_MAX_ATTEMPT_MS;
|
|
136
|
+
const canRetry = verdict.transient && !slow && attempt < maxAttempts;
|
|
137
|
+
if (!canRetry) {
|
|
138
|
+
if (verdict.transient && (slow || attempt >= maxAttempts)) {
|
|
139
|
+
recordOutcome(attempt > 1 ? "exhausted" : "not_eligible");
|
|
140
|
+
}
|
|
141
|
+
else if (attempt > 1) {
|
|
142
|
+
recordOutcome("exhausted");
|
|
143
|
+
}
|
|
144
|
+
if (attempt > 1) {
|
|
145
|
+
throw exhaustedError(attempt, error);
|
|
146
|
+
}
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
const delay = toolRetryBackoffMs({
|
|
150
|
+
failedAttempt: attempt,
|
|
151
|
+
random: randomImpl(),
|
|
152
|
+
retryAfterMs: verdict.retryAfterMs,
|
|
153
|
+
spentMs,
|
|
154
|
+
});
|
|
155
|
+
if (delay === undefined) {
|
|
156
|
+
recordOutcome("exhausted");
|
|
157
|
+
throw exhaustedError(attempt, error);
|
|
158
|
+
}
|
|
159
|
+
const notice = {
|
|
160
|
+
attempt: attempt + 1,
|
|
161
|
+
reason: verdict.reason,
|
|
162
|
+
backoffMs: delay,
|
|
163
|
+
...(args.connection === undefined ? {} : { connection: args.connection }),
|
|
164
|
+
};
|
|
165
|
+
args.onRetry?.(notice);
|
|
166
|
+
await sleepImpl(delay, args.signal);
|
|
167
|
+
spentMs += delay;
|
|
168
|
+
throwIfAborted(args.signal);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
recordOutcome("exhausted");
|
|
172
|
+
throw exhaustedError(maxAttempts, lastError);
|
|
173
|
+
}
|
|
174
|
+
function recordOutcome(outcome) {
|
|
175
|
+
const counter = retryCounter();
|
|
176
|
+
counter?.add(1, { outcome });
|
|
177
|
+
}
|
|
178
|
+
function retryCounter() {
|
|
179
|
+
if (counterCache !== undefined) {
|
|
180
|
+
return counterCache;
|
|
181
|
+
}
|
|
182
|
+
const meter = meterOverride ?? metrics.getMeter("@cursor/bdk");
|
|
183
|
+
counterCache = meter.createCounter(METRIC_NAME, {
|
|
184
|
+
description: "Read-only tool retries by outcome",
|
|
185
|
+
});
|
|
186
|
+
return counterCache;
|
|
187
|
+
}
|
|
188
|
+
function exhaustedError(attempts, error) {
|
|
189
|
+
const detail = error instanceof Error && error.message !== "" ? error.message : "unknown error";
|
|
190
|
+
const wrapped = new Error(`failed after ${attempts} attempts: ${detail}`);
|
|
191
|
+
wrapped.cause = error;
|
|
192
|
+
return wrapped;
|
|
193
|
+
}
|
|
194
|
+
function throwIfAborted(signal) {
|
|
195
|
+
if (signal?.aborted === true) {
|
|
196
|
+
throw abortError(signal);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function abortError(signal) {
|
|
200
|
+
const reason = signal?.reason;
|
|
201
|
+
if (reason instanceof Error) {
|
|
202
|
+
return reason;
|
|
203
|
+
}
|
|
204
|
+
const error = new Error("The turn was aborted.");
|
|
205
|
+
error.name = "AbortError";
|
|
206
|
+
return error;
|
|
207
|
+
}
|
|
208
|
+
function defaultSleep(ms, signal) {
|
|
209
|
+
if (ms <= 0) {
|
|
210
|
+
return Promise.resolve();
|
|
211
|
+
}
|
|
212
|
+
return new Promise((resolve, reject) => {
|
|
213
|
+
const timer = setTimeout(() => {
|
|
214
|
+
signal?.removeEventListener("abort", onAbort);
|
|
215
|
+
resolve();
|
|
216
|
+
}, ms);
|
|
217
|
+
const onAbort = () => {
|
|
218
|
+
clearTimeout(timer);
|
|
219
|
+
reject(abortError(signal));
|
|
220
|
+
};
|
|
221
|
+
if (signal?.aborted === true) {
|
|
222
|
+
clearTimeout(timer);
|
|
223
|
+
reject(abortError(signal));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function classifyAtDepth(error, depth) {
|
|
230
|
+
if (depth >= MAX_CAUSE_DEPTH || !(error instanceof Error)) {
|
|
231
|
+
return { transient: false };
|
|
232
|
+
}
|
|
233
|
+
if (isVeto(error)) {
|
|
234
|
+
return { transient: false };
|
|
235
|
+
}
|
|
236
|
+
const status = httpStatus(error);
|
|
237
|
+
if (status !== undefined && status >= 400 && status <= 499 && status !== 429) {
|
|
238
|
+
return { transient: false };
|
|
239
|
+
}
|
|
240
|
+
const retryAfterMs = readRetryAfterMs(error);
|
|
241
|
+
if (status !== undefined && TRANSIENT_HTTP_STATUS.has(status)) {
|
|
242
|
+
return { transient: true, reason: httpReason(status), retryAfterMs };
|
|
243
|
+
}
|
|
244
|
+
const code = errorCode(error);
|
|
245
|
+
if (code !== undefined && TRANSIENT_CODES.has(code)) {
|
|
246
|
+
return { transient: true, reason: "transport", retryAfterMs };
|
|
247
|
+
}
|
|
248
|
+
if (code !== undefined && code.startsWith("UND_ERR_") && /CONNECT|SOCKET/.test(code)) {
|
|
249
|
+
return { transient: true, reason: "transport", retryAfterMs };
|
|
250
|
+
}
|
|
251
|
+
// A vendor isError string is not a transport failure. Only the MCP
|
|
252
|
+
// allowlist retries it.
|
|
253
|
+
if (error instanceof McpToolError) {
|
|
254
|
+
const vendor = classifyMcpVendorMessage(error.vendorMessage, retryAfterMs);
|
|
255
|
+
if (vendor !== undefined) {
|
|
256
|
+
return vendor;
|
|
257
|
+
}
|
|
258
|
+
return classifyAtDepth(error.cause, depth + 1);
|
|
259
|
+
}
|
|
260
|
+
if (TRANSPORT_TEXT.test(error.message)) {
|
|
261
|
+
return { transient: true, reason: "transport", retryAfterMs };
|
|
262
|
+
}
|
|
263
|
+
const fromText = error.message.match(HTTP_STATUS_TEXT);
|
|
264
|
+
if (fromText !== null) {
|
|
265
|
+
const parsed = Number(fromText[1]);
|
|
266
|
+
if (TRANSIENT_HTTP_STATUS.has(parsed)) {
|
|
267
|
+
return { transient: true, reason: httpReason(parsed), retryAfterMs };
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (error instanceof AggregateError) {
|
|
271
|
+
for (const inner of error.errors) {
|
|
272
|
+
const verdict = classifyAtDepth(inner, depth + 1);
|
|
273
|
+
if (verdict.transient) {
|
|
274
|
+
return verdict;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return classifyAtDepth(error.cause, depth + 1);
|
|
279
|
+
}
|
|
280
|
+
function classifyMcpVendorMessage(vendorMessage, retryAfterMs) {
|
|
281
|
+
if (MCP_TRANSIENT_TEXT.test(vendorMessage)) {
|
|
282
|
+
return { transient: true, reason: "mcp_transient", retryAfterMs };
|
|
283
|
+
}
|
|
284
|
+
const fromText = vendorMessage.match(HTTP_STATUS_TEXT);
|
|
285
|
+
if (fromText !== null) {
|
|
286
|
+
const parsed = Number(fromText[1]);
|
|
287
|
+
if (TRANSIENT_HTTP_STATUS.has(parsed)) {
|
|
288
|
+
return { transient: true, reason: httpReason(parsed), retryAfterMs };
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
function isVeto(error) {
|
|
294
|
+
if (error.name === "McpNeedsAuthError" || error.name === "UnauthorizedError") {
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
const text = `${error.name}\n${error.message}`;
|
|
298
|
+
if (AUTH_TEXT.test(text) || OVERSIZE.test(text) || ENDPOINT_DEADLINE.test(text)) {
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
const status = httpStatus(error);
|
|
302
|
+
if (status === 401 || status === 403 || status === 413) {
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
return timeoutLongerThanAttemptCap(text);
|
|
306
|
+
}
|
|
307
|
+
function timeoutLongerThanAttemptCap(text) {
|
|
308
|
+
if (!TIMEOUT_WORD.test(text)) {
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
for (const match of text.matchAll(/(\d+)\s*ms\b/gi)) {
|
|
312
|
+
if (Number(match[1]) > TOOL_RETRY_MAX_ATTEMPT_MS) {
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
for (const match of text.matchAll(/(\d+(?:\.\d+)?)\s*(?:seconds|\bsec\b|\bs\b)/gi)) {
|
|
317
|
+
if (Number(match[1]) * 1000 > TOOL_RETRY_MAX_ATTEMPT_MS) {
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
function httpReason(status) {
|
|
324
|
+
switch (status) {
|
|
325
|
+
case 429:
|
|
326
|
+
return "http_429";
|
|
327
|
+
case 502:
|
|
328
|
+
return "http_502";
|
|
329
|
+
case 504:
|
|
330
|
+
return "http_504";
|
|
331
|
+
default:
|
|
332
|
+
return "http_503";
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function httpStatus(error) {
|
|
336
|
+
const record = error;
|
|
337
|
+
for (const value of [record.status, record.statusCode]) {
|
|
338
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
339
|
+
return value;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return undefined;
|
|
343
|
+
}
|
|
344
|
+
function errorCode(error) {
|
|
345
|
+
const code = error.code;
|
|
346
|
+
return typeof code === "string" && code.length > 0 ? code : undefined;
|
|
347
|
+
}
|
|
348
|
+
function readRetryAfterMs(error) {
|
|
349
|
+
const record = error;
|
|
350
|
+
const header = record.headers?.get?.("retry-after") ?? record.headers?.get?.("Retry-After");
|
|
351
|
+
const fromHeader = parseRetryAfter(header);
|
|
352
|
+
if (fromHeader !== undefined) {
|
|
353
|
+
return fromHeader;
|
|
354
|
+
}
|
|
355
|
+
if (typeof record.retryAfter === "number" && Number.isFinite(record.retryAfter)) {
|
|
356
|
+
return record.retryAfter * 1000;
|
|
357
|
+
}
|
|
358
|
+
if (typeof record.retryAfter === "string") {
|
|
359
|
+
const parsed = parseRetryAfter(record.retryAfter);
|
|
360
|
+
if (parsed !== undefined) {
|
|
361
|
+
return parsed;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const match = error.message.match(RETRY_AFTER_TEXT);
|
|
365
|
+
if (match !== null) {
|
|
366
|
+
return Number(match[1]) * 1000;
|
|
367
|
+
}
|
|
368
|
+
return undefined;
|
|
369
|
+
}
|
|
370
|
+
function parseRetryAfter(value) {
|
|
371
|
+
if (value === undefined || value === null) {
|
|
372
|
+
return undefined;
|
|
373
|
+
}
|
|
374
|
+
const trimmed = value.trim();
|
|
375
|
+
if (trimmed === "") {
|
|
376
|
+
return undefined;
|
|
377
|
+
}
|
|
378
|
+
const seconds = Number(trimmed);
|
|
379
|
+
if (Number.isFinite(seconds)) {
|
|
380
|
+
return Math.max(0, seconds * 1000);
|
|
381
|
+
}
|
|
382
|
+
const date = Date.parse(trimmed);
|
|
383
|
+
if (Number.isNaN(date)) {
|
|
384
|
+
return undefined;
|
|
385
|
+
}
|
|
386
|
+
return Math.max(0, date - Date.now());
|
|
387
|
+
}
|