@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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Slack setup guide printed by `agent-serve slack setup`.
|
|
3
3
|
*
|
|
4
4
|
* Dedicated Socket Mode app via `slack create` (dashboard wizard).
|
|
5
|
-
* `slack init --manual` is the unmanaged paste
|
|
5
|
+
* `slack init --manual` is the unmanaged Slack CLI / paste path.
|
|
6
6
|
* {@link SLACK_SETUP_PHASES} is that checklist; its ids key
|
|
7
7
|
* `.agent-serve/slack/setup-status.json`.
|
|
8
8
|
*/
|
|
@@ -21,6 +21,7 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
|
|
|
21
21
|
title: "Generate channel + manifests",
|
|
22
22
|
steps: [
|
|
23
23
|
"agent-serve slack init --manual --dir . --name My Agent",
|
|
24
|
+
"Installs the Slack app when Slack CLI is logged in. Otherwise next asks the user to install it.",
|
|
24
25
|
"Manifests default to Socket Mode (no public Request URL).",
|
|
25
26
|
],
|
|
26
27
|
},
|
|
@@ -29,9 +30,11 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
|
|
|
29
30
|
actor: "human",
|
|
30
31
|
title: "Create two Slack apps from manifests",
|
|
31
32
|
steps: [
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
33
|
+
"Preferred: Slack CLI at ~/.slack/bin/slack. slack login --no-prompt, then slack app install --environment local --team <T> --force",
|
|
34
|
+
"Prod: SLACK_ENV=deployed slack app install --environment deployed --team <T> --force",
|
|
35
|
+
"Do not slack deploy; Agent SDK serve owns Socket Mode",
|
|
36
|
+
"Fallback: https://api.slack.com/apps -> Create New App from a manifest",
|
|
37
|
+
"Paste .slack/manifest.dev.json, then manifest.prod.json",
|
|
35
38
|
],
|
|
36
39
|
},
|
|
37
40
|
{
|
|
@@ -39,8 +42,9 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
|
|
|
39
42
|
actor: "human",
|
|
40
43
|
title: "Install + mint App-Level Token",
|
|
41
44
|
steps: [
|
|
42
|
-
"
|
|
45
|
+
"Slack CLI install leaves tokens in that process only. Copy xoxb from OAuth & Permissions at https://api.slack.com/apps/<appId>",
|
|
43
46
|
"App-Level Tokens: create token with connections:write; copy xapp-...",
|
|
47
|
+
"If Slack CLI wrote SLACK_* to .env, copy them into .env.local using env.example names",
|
|
44
48
|
],
|
|
45
49
|
},
|
|
46
50
|
{
|
|
@@ -106,7 +110,7 @@ export function formatSlackSetupGuide(): string {
|
|
|
106
110
|
" Finish Slack consent and the bot name there. The CLI writes",
|
|
107
111
|
" tokens into .env.local.",
|
|
108
112
|
"",
|
|
109
|
-
"Manual Slack app: `slack init --manual
|
|
113
|
+
"Manual Slack app: `slack init --manual` (Slack CLI, or paste at api.slack.com).",
|
|
110
114
|
"Goal: importable dev + prod Slack apps over Socket Mode (no public URL).",
|
|
111
115
|
"App-Level Token (xapp-...) + Bot Token (xoxb-...) required.",
|
|
112
116
|
"",
|
|
@@ -21,8 +21,11 @@
|
|
|
21
21
|
import type { ChannelEventHandlers } from "../../types.js";
|
|
22
22
|
import { postMessage, setThreadStatus, updateMessage } from "./api.js";
|
|
23
23
|
import {
|
|
24
|
+
authThreadStatus,
|
|
24
25
|
buildApprovalBlocks,
|
|
26
|
+
buildAuthBlocks,
|
|
25
27
|
buildResolvedApprovalBlocks,
|
|
28
|
+
buildResolvedAuthBlocks,
|
|
26
29
|
} from "./approvals.js";
|
|
27
30
|
import { SLACK_DEFAULT_LOADING_MESSAGES } from "./constants.js";
|
|
28
31
|
import { defaultSlackLog, type SlackLog } from "./log.js";
|
|
@@ -132,5 +135,95 @@ export function buildToolApprovalEvents(
|
|
|
132
135
|
decision: event.data.decision,
|
|
133
136
|
});
|
|
134
137
|
},
|
|
138
|
+
|
|
139
|
+
async "action.auth_requested"(event, channel, ctx) {
|
|
140
|
+
const log = getLog();
|
|
141
|
+
const state = channel.state;
|
|
142
|
+
if (state.channelId === null || state.threadTs === null) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const blocks = buildAuthBlocks({
|
|
146
|
+
sessionId: ctx.session.id,
|
|
147
|
+
callId: event.data.callId,
|
|
148
|
+
toolName: event.data.toolName,
|
|
149
|
+
connection: event.data.connection,
|
|
150
|
+
authUrl: event.data.authUrl,
|
|
151
|
+
});
|
|
152
|
+
try {
|
|
153
|
+
const posted = await postMessage({
|
|
154
|
+
botToken,
|
|
155
|
+
channel: state.channelId,
|
|
156
|
+
threadTs: state.threadTs,
|
|
157
|
+
text: `Authorization required for \`${event.data.connection}\``,
|
|
158
|
+
blocks,
|
|
159
|
+
});
|
|
160
|
+
channel.state.approvalMessageByCallId = {
|
|
161
|
+
...(state.approvalMessageByCallId ?? {}),
|
|
162
|
+
[event.data.callId]: posted.ts,
|
|
163
|
+
};
|
|
164
|
+
await setThreadStatus({
|
|
165
|
+
botToken,
|
|
166
|
+
channelId: state.channelId,
|
|
167
|
+
threadTs: state.threadTs,
|
|
168
|
+
status: authThreadStatus(event.data.connection),
|
|
169
|
+
loadingMessages: [
|
|
170
|
+
authThreadStatus(event.data.connection),
|
|
171
|
+
...SLACK_DEFAULT_LOADING_MESSAGES,
|
|
172
|
+
],
|
|
173
|
+
});
|
|
174
|
+
log.info("auth card posted", {
|
|
175
|
+
call_id: event.data.callId,
|
|
176
|
+
connection: event.data.connection,
|
|
177
|
+
message_ts: posted.ts,
|
|
178
|
+
});
|
|
179
|
+
} catch (error) {
|
|
180
|
+
log.warn("auth card post failed", {
|
|
181
|
+
call_id: event.data.callId,
|
|
182
|
+
error: error instanceof Error ? error.message : String(error),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
async "action.auth_resolved"(event, channel) {
|
|
188
|
+
const log = getLog();
|
|
189
|
+
const state = channel.state;
|
|
190
|
+
const messageTs = state.approvalMessageByCallId?.[event.data.callId];
|
|
191
|
+
if (
|
|
192
|
+
state.channelId !== null &&
|
|
193
|
+
messageTs !== undefined &&
|
|
194
|
+
messageTs !== ""
|
|
195
|
+
) {
|
|
196
|
+
const blocks = buildResolvedAuthBlocks({
|
|
197
|
+
connection: event.data.connection,
|
|
198
|
+
decision: event.data.decision,
|
|
199
|
+
byUserId: event.data.by,
|
|
200
|
+
});
|
|
201
|
+
const verb =
|
|
202
|
+
event.data.decision === "approve" ? "Connected" : "Cancelled";
|
|
203
|
+
await updateMessage({
|
|
204
|
+
botToken,
|
|
205
|
+
channel: state.channelId,
|
|
206
|
+
ts: messageTs,
|
|
207
|
+
text: `${verb} — ${event.data.connection}`,
|
|
208
|
+
blocks,
|
|
209
|
+
});
|
|
210
|
+
const next = { ...(state.approvalMessageByCallId ?? {}) };
|
|
211
|
+
delete next[event.data.callId];
|
|
212
|
+
channel.state.approvalMessageByCallId = next;
|
|
213
|
+
}
|
|
214
|
+
if (state.channelId !== null && state.threadTs !== null) {
|
|
215
|
+
await setThreadStatus({
|
|
216
|
+
botToken,
|
|
217
|
+
channelId: state.channelId,
|
|
218
|
+
threadTs: state.threadTs,
|
|
219
|
+
status: "Working…",
|
|
220
|
+
loadingMessages: [...SLACK_DEFAULT_LOADING_MESSAGES],
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
log.info("auth resolved in slack", {
|
|
224
|
+
call_id: event.data.callId,
|
|
225
|
+
decision: event.data.decision,
|
|
226
|
+
});
|
|
227
|
+
},
|
|
135
228
|
};
|
|
136
229
|
}
|
|
@@ -61,8 +61,14 @@ export interface SlackChannelState {
|
|
|
61
61
|
streamTs: string | null;
|
|
62
62
|
/** Channel id used when the stream was started. */
|
|
63
63
|
streamChannelId?: string | null;
|
|
64
|
-
/** Last
|
|
64
|
+
/** Last assistant text delivered to the thread (stream or postMessage). */
|
|
65
65
|
lastPostedText?: string | null;
|
|
66
|
+
/**
|
|
67
|
+
* Text of the current assistant block already written into the open stream.
|
|
68
|
+
* The harness restarts its cumulative text at every tool boundary, so the
|
|
69
|
+
* append delta cannot be measured against {@link lastPostedText}.
|
|
70
|
+
*/
|
|
71
|
+
streamBlockText?: string | null;
|
|
66
72
|
/**
|
|
67
73
|
* Slack message ts of the agent's last delivered reply in this thread.
|
|
68
74
|
* Warm turns use this as the `<slack_thread_delta>` watermark.
|
|
@@ -73,6 +79,8 @@ export interface SlackChannelState {
|
|
|
73
79
|
* for the rest of the turn.
|
|
74
80
|
*/
|
|
75
81
|
streamingUnavailable?: boolean;
|
|
82
|
+
/** Editable progress message ts when `chat.startStream` is unavailable. */
|
|
83
|
+
progressTs: string | null;
|
|
76
84
|
/**
|
|
77
85
|
* Message ts of approval cards keyed by tool call id (for
|
|
78
86
|
* replacing Approve/Deny buttons after a decision).
|
package/src/evals/run-facts.ts
CHANGED
|
@@ -182,6 +182,38 @@ export function deriveRunFacts(events: readonly SessionEvent[]): EvalRunFacts {
|
|
|
182
182
|
}
|
|
183
183
|
break;
|
|
184
184
|
}
|
|
185
|
+
case "action.auth_requested": {
|
|
186
|
+
const request: EvalInputRequestFact = {
|
|
187
|
+
callId: event.data.callId,
|
|
188
|
+
toolName: event.data.toolName,
|
|
189
|
+
args: {
|
|
190
|
+
connection: event.data.connection,
|
|
191
|
+
authUrl: event.data.authUrl,
|
|
192
|
+
},
|
|
193
|
+
resolved: false,
|
|
194
|
+
};
|
|
195
|
+
inputRequests.push(request);
|
|
196
|
+
inputRequestsByCallId.set(event.data.callId, request);
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case "action.auth_resolved": {
|
|
200
|
+
const request = inputRequestsByCallId.get(event.data.callId);
|
|
201
|
+
if (request !== undefined) {
|
|
202
|
+
request.resolved = true;
|
|
203
|
+
request.decision = event.data.decision;
|
|
204
|
+
}
|
|
205
|
+
const fact = ensureCall(
|
|
206
|
+
event.data.callId,
|
|
207
|
+
event.data.toolName,
|
|
208
|
+
event.turnId,
|
|
209
|
+
event.data.parentCallId
|
|
210
|
+
);
|
|
211
|
+
fact.approvalDecision = event.data.decision;
|
|
212
|
+
if (event.data.decision === "deny") {
|
|
213
|
+
fact.status = "rejected";
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
185
217
|
case "subagent.called": {
|
|
186
218
|
const existing = subagentsByCallId.get(event.data.callId);
|
|
187
219
|
if (existing === undefined) {
|
|
@@ -76,8 +76,9 @@ export const AGENT_SERVE_STORE_SOURCE_ID_ENV_VAR =
|
|
|
76
76
|
* user-level store above. The user store carries author-facing bytes
|
|
77
77
|
* (`ctx.host.files`, skills, memory, artifacts) and is browsable and
|
|
78
78
|
* mountable; the framework store carries engine-owned session state —
|
|
79
|
-
* session records, event transcripts,
|
|
80
|
-
* conversation mirror — and is never
|
|
79
|
+
* session records, event transcripts, hosted-execution run logs,
|
|
80
|
+
* continuation index, and the SDK conversation mirror — and is never
|
|
81
|
+
* exposed to authors or models.
|
|
81
82
|
* Provisioned by the v2 deploy pipeline alongside the user store; v1
|
|
82
83
|
* deployments have only the user store.
|
|
83
84
|
*/
|
package/src/index.ts
CHANGED
|
@@ -79,6 +79,10 @@ export {
|
|
|
79
79
|
V2EngineError,
|
|
80
80
|
} from "./continuation.js";
|
|
81
81
|
export { defineHook } from "./hooks.js";
|
|
82
|
+
export {
|
|
83
|
+
InvalidAsOfError,
|
|
84
|
+
VacuousTimeArgsError,
|
|
85
|
+
} from "./internal/as-of.js";
|
|
82
86
|
export type { LoadAgentProjectOptions } from "./internal/discovery.js";
|
|
83
87
|
export {
|
|
84
88
|
formatDiagnostics,
|
|
@@ -118,24 +118,45 @@ export async function resolveAdvertisedTools(args: {
|
|
|
118
118
|
return [];
|
|
119
119
|
}
|
|
120
120
|
const sourceFor = args.sourceFor ?? sourceForConnection;
|
|
121
|
+
// Each connection's listing is a network round trip against a distinct
|
|
122
|
+
// server (auth callback, MCP initialize, tools/list), so they run
|
|
123
|
+
// concurrently; the fan-out is bounded by the agent's declared
|
|
124
|
+
// connections. Name assignment below stays in declaration order so
|
|
125
|
+
// collision suffixes do not depend on which server answered first.
|
|
126
|
+
type Listing =
|
|
127
|
+
| {
|
|
128
|
+
connection: DiscoveredConnection;
|
|
129
|
+
ok: true;
|
|
130
|
+
source: AdvertisedToolSource;
|
|
131
|
+
listed: HostMcpToolInfo[];
|
|
132
|
+
}
|
|
133
|
+
| { connection: DiscoveredConnection; ok: false; error: unknown };
|
|
134
|
+
const listings = await Promise.all(
|
|
135
|
+
advertising.map(async (connection): Promise<Listing> => {
|
|
136
|
+
try {
|
|
137
|
+
const source = await sourceFor(connection, args.session, args.hostMcp);
|
|
138
|
+
const listed = await source.listTools();
|
|
139
|
+
return { connection, ok: true, source, listed };
|
|
140
|
+
} catch (error) {
|
|
141
|
+
return { connection, ok: false, error };
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
);
|
|
121
145
|
const claimed = new Set(args.agent.tools.map((tool) => tool.name));
|
|
122
146
|
const resolved: DiscoveredTool[] = [];
|
|
123
|
-
for (const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
source = await sourceFor(connection, args.session, args.hostMcp);
|
|
128
|
-
listed = await source.listTools();
|
|
129
|
-
} catch (error) {
|
|
147
|
+
for (const listing of listings) {
|
|
148
|
+
const { connection } = listing;
|
|
149
|
+
if (!listing.ok) {
|
|
130
150
|
if (args.onConnectionError !== undefined) {
|
|
131
|
-
args.onConnectionError(connection.name, error);
|
|
151
|
+
args.onConnectionError(connection.name, listing.error);
|
|
132
152
|
continue;
|
|
133
153
|
}
|
|
134
154
|
throw new Error(
|
|
135
|
-
`Failed to list tools on advertised connection "${connection.name}": ${describeError(error)}`,
|
|
136
|
-
{ cause: error }
|
|
155
|
+
`Failed to list tools on advertised connection "${connection.name}": ${describeError(listing.error)}`,
|
|
156
|
+
{ cause: listing.error }
|
|
137
157
|
);
|
|
138
158
|
}
|
|
159
|
+
const { source, listed } = listing;
|
|
139
160
|
const intended = listed.filter(
|
|
140
161
|
(info) =>
|
|
141
162
|
!isDoNotCallTool(info.annotations) &&
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* In-memory gate for human-in-the-loop
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* {@link ApprovalGate.resolve}.
|
|
2
|
+
* In-memory gate for human-in-the-loop parks. The session engine parks
|
|
3
|
+
* inside a server-tool `execute` by awaiting {@link ApprovalGate.wait};
|
|
4
|
+
* HTTP (or the playground) unblocks via {@link ApprovalGate.resolve}.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
* durability of the *list* across
|
|
9
|
-
* in-flight SDK tool callback is gone,
|
|
10
|
-
* the host treats the
|
|
6
|
+
* Used for `needsApproval` and MCP on-demand auth. Pending rows are also
|
|
7
|
+
* mirrored onto {@link SessionRecord} for durability of the *list* across
|
|
8
|
+
* reloads. After a process restart the in-flight SDK tool callback is gone,
|
|
9
|
+
* so resolve returns false and the host treats the park as interrupted.
|
|
11
10
|
*/
|
|
12
11
|
|
|
13
12
|
import type { ApprovalDecision, PendingApproval } from "../types.js";
|
|
@@ -21,33 +20,25 @@ export interface ApprovalResolution {
|
|
|
21
20
|
by?: string;
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
interface Waiter {
|
|
25
|
-
meta:
|
|
23
|
+
interface Waiter<T> {
|
|
24
|
+
meta: T;
|
|
26
25
|
resolve: (resolution: ApprovalResolution) => void;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
export class ApprovalGate {
|
|
30
|
-
private readonly waiters = new Map<string, Waiter
|
|
28
|
+
export class ApprovalGate<T extends { callId: string } = PendingApproval> {
|
|
29
|
+
private readonly waiters = new Map<string, Waiter<T>>();
|
|
31
30
|
|
|
32
|
-
wait(
|
|
33
|
-
|
|
34
|
-
): Promise<ApprovalResolution> {
|
|
35
|
-
const key = approvalKey(meta.sessionId, meta.callId);
|
|
31
|
+
wait(sessionId: string, meta: T): Promise<ApprovalResolution> {
|
|
32
|
+
const key = approvalKey(sessionId, meta.callId);
|
|
36
33
|
const existing = this.waiters.get(key);
|
|
37
34
|
if (existing !== undefined) {
|
|
38
35
|
throw new Error(
|
|
39
|
-
`Approval already pending for session ${
|
|
36
|
+
`Approval already pending for session ${sessionId} call ${meta.callId}`
|
|
40
37
|
);
|
|
41
38
|
}
|
|
42
39
|
return new Promise<ApprovalResolution>((resolveDecision) => {
|
|
43
40
|
this.waiters.set(key, {
|
|
44
|
-
meta
|
|
45
|
-
callId: meta.callId,
|
|
46
|
-
turnId: meta.turnId,
|
|
47
|
-
toolName: meta.toolName,
|
|
48
|
-
args: meta.args,
|
|
49
|
-
requestedAt: meta.requestedAt,
|
|
50
|
-
},
|
|
41
|
+
meta,
|
|
51
42
|
resolve: resolveDecision,
|
|
52
43
|
});
|
|
53
44
|
});
|
|
@@ -69,11 +60,11 @@ export class ApprovalGate {
|
|
|
69
60
|
return false;
|
|
70
61
|
}
|
|
71
62
|
this.waiters.delete(key);
|
|
63
|
+
const by =
|
|
64
|
+
resolvedBy === undefined || resolvedBy === "" ? undefined : resolvedBy;
|
|
72
65
|
waiter.resolve({
|
|
73
66
|
decision,
|
|
74
|
-
|
|
75
|
-
? {}
|
|
76
|
-
: { by: resolvedBy }),
|
|
67
|
+
by,
|
|
77
68
|
});
|
|
78
69
|
return true;
|
|
79
70
|
}
|
|
@@ -82,9 +73,9 @@ export class ApprovalGate {
|
|
|
82
73
|
return this.waiters.has(approvalKey(sessionId, callId));
|
|
83
74
|
}
|
|
84
75
|
|
|
85
|
-
list(sessionId: string):
|
|
76
|
+
list(sessionId: string): T[] {
|
|
86
77
|
const prefix = `${sessionId}\0`;
|
|
87
|
-
const out:
|
|
78
|
+
const out: T[] = [];
|
|
88
79
|
for (const [key, waiter] of this.waiters) {
|
|
89
80
|
if (key.startsWith(prefix)) {
|
|
90
81
|
out.push(waiter.meta);
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const TIMEZONE_SUFFIX = /(?:Z|[+-]\d{2}:?\d{2})$/i;
|
|
2
|
+
|
|
3
|
+
export class InvalidAsOfError extends Error {
|
|
4
|
+
constructor(value: string) {
|
|
5
|
+
super(
|
|
6
|
+
`asOf must be an ISO-8601 instant with a timezone (e.g. ` +
|
|
7
|
+
`2026-08-31T12:00:00Z); received ${JSON.stringify(value)}.`
|
|
8
|
+
);
|
|
9
|
+
this.name = "InvalidAsOfError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function parseInstant(value: string): Date | undefined {
|
|
14
|
+
const trimmed = value.trim();
|
|
15
|
+
if (trimmed === "" || !TIMEZONE_SUFFIX.test(trimmed)) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const instant = new Date(trimmed);
|
|
19
|
+
return Number.isNaN(instant.getTime()) ? undefined : instant;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function normalizeAsOf(value: string | undefined): string | undefined {
|
|
23
|
+
if (value === undefined) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const instant = parseInstant(value);
|
|
27
|
+
if (instant === undefined) {
|
|
28
|
+
throw new InvalidAsOfError(value);
|
|
29
|
+
}
|
|
30
|
+
return instant.toISOString();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function sessionClock(asOf: string | undefined): () => Date {
|
|
34
|
+
if (asOf === undefined) {
|
|
35
|
+
return () => new Date();
|
|
36
|
+
}
|
|
37
|
+
const frozen = new Date(asOf).getTime();
|
|
38
|
+
return () => new Date(frozen);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class VacuousTimeArgsError extends Error {
|
|
42
|
+
constructor(toolName: string, missing: readonly string[]) {
|
|
43
|
+
super(
|
|
44
|
+
`Tool "${toolName}" declares timeArgs ` +
|
|
45
|
+
`${JSON.stringify(missing)} that its input schema does not define, ` +
|
|
46
|
+
`so bounding would silently check nothing. Make the declaration ` +
|
|
47
|
+
`match the schema's property names.`
|
|
48
|
+
);
|
|
49
|
+
this.name = "VacuousTimeArgsError";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function assertTimeArgs(
|
|
54
|
+
tools: readonly {
|
|
55
|
+
name: string;
|
|
56
|
+
definition: { timeArgs?: readonly string[] };
|
|
57
|
+
inputSchema?: { properties?: Record<string, unknown> };
|
|
58
|
+
}[],
|
|
59
|
+
asOf: string | undefined
|
|
60
|
+
): void {
|
|
61
|
+
if (asOf === undefined) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
for (const tool of tools) {
|
|
65
|
+
const declared = tool.definition.timeArgs;
|
|
66
|
+
if (declared === undefined || declared.length === 0) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const properties = tool.inputSchema?.properties ?? {};
|
|
70
|
+
const missing = declared.filter((name) => !(name in properties));
|
|
71
|
+
if (missing.length > 0) {
|
|
72
|
+
throw new VacuousTimeArgsError(tool.name, missing);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function timeArgViolation(
|
|
78
|
+
input: unknown,
|
|
79
|
+
timeArgs: readonly string[],
|
|
80
|
+
asOf: string
|
|
81
|
+
): string | undefined {
|
|
82
|
+
const record =
|
|
83
|
+
typeof input === "object" && input !== null
|
|
84
|
+
? (input as Record<string, unknown>)
|
|
85
|
+
: {};
|
|
86
|
+
const frozen = new Date(asOf).getTime();
|
|
87
|
+
for (const name of timeArgs) {
|
|
88
|
+
const value = record[name];
|
|
89
|
+
const instant = typeof value === "string" ? parseInstant(value) : undefined;
|
|
90
|
+
if (instant === undefined) {
|
|
91
|
+
return (
|
|
92
|
+
`Time argument "${name}" must be an absolute ISO-8601 instant with ` +
|
|
93
|
+
`a timezone (e.g. ${asOf}); received ${JSON.stringify(value)}. This ` +
|
|
94
|
+
`session reads the world as of ${asOf} — supply absolute bounds at ` +
|
|
95
|
+
`or before that instant and retry.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
if (instant.getTime() > frozen) {
|
|
99
|
+
return (
|
|
100
|
+
`Time argument "${name}" (${JSON.stringify(value)}) is later than ` +
|
|
101
|
+
`the instant this session reads the world as of (${asOf}). Supply ` +
|
|
102
|
+
`bounds at or before that instant and retry.`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
@@ -483,6 +483,25 @@ async function streamTurn(args: StreamTurnArgs): Promise<number> {
|
|
|
483
483
|
);
|
|
484
484
|
continue;
|
|
485
485
|
}
|
|
486
|
+
if (event.type === "action.auth_requested") {
|
|
487
|
+
closeAssistant();
|
|
488
|
+
write(
|
|
489
|
+
` ${c.yellow("⏸")} ${c.bold(event.data.connection)} ${c.dim(
|
|
490
|
+
"awaiting MCP authorization"
|
|
491
|
+
)}\n`
|
|
492
|
+
);
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
if (event.type === "action.auth_resolved") {
|
|
496
|
+
const mark =
|
|
497
|
+
event.data.decision === "approve" ? c.green("✓") : c.red("✗");
|
|
498
|
+
write(
|
|
499
|
+
` ${mark} ${c.bold(event.data.connection)} ${c.dim(
|
|
500
|
+
event.data.decision === "approve" ? "connected" : "denied"
|
|
501
|
+
)}\n`
|
|
502
|
+
);
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
486
505
|
if (event.type === "action.result") {
|
|
487
506
|
if (
|
|
488
507
|
event.data.toolName === "task" &&
|