eve 0.74.0 → 0.75.1
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/CHANGELOG.md +34 -0
- package/dist/src/channel/auth/result.d.ts +4 -0
- package/dist/src/channel/auth/result.js +1 -0
- package/dist/src/channel/types.d.ts +14 -2
- package/dist/src/chunks/{use-eve-agent-mP0M7SrL.js → use-eve-agent-B2Kne9z6.js} +7 -2
- package/dist/src/chunks/{use-eve-agent-DOOXadF0.js → use-eve-agent-DK_T88EP.js} +7 -2
- package/dist/src/cli/commands/deploy.js +1 -1
- package/dist/src/cli/commands/integration-connect.d.ts +2 -0
- package/dist/src/cli/commands/integration-connect.js +1 -1
- package/dist/src/cli/commands/integration-setup.js +1 -1
- package/dist/src/cli/commands/link.d.ts +2 -1
- package/dist/src/cli/commands/link.js +1 -1
- package/dist/src/cli/commands/registry-declared-setups.d.ts +19 -0
- package/dist/src/cli/commands/registry-declared-setups.js +1 -1
- package/dist/src/cli/commands/registry-recovery.d.ts +3 -1
- package/dist/src/cli/commands/registry-recovery.js +1 -1
- package/dist/src/cli/commands/registry.d.ts +12 -4
- package/dist/src/cli/commands/registry.js +1 -1
- package/dist/src/cli/commands/vercel-non-interactive.d.ts +6 -4
- package/dist/src/cli/commands/vercel-non-interactive.js +1 -1
- package/dist/src/cli/dev/tui/registry-result-message.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +2 -0
- package/dist/src/cli/dev/tui/setup-commands.js +2 -2
- package/dist/src/client/index.d.ts +1 -0
- package/dist/src/client/session.d.ts +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/sessions.d.ts +1 -1
- package/dist/src/client/types.d.ts +6 -0
- package/dist/src/compiled/.vendor-stamp.json +8 -8
- package/dist/src/compiled/@eve/catalog/index.js +1 -1
- package/dist/src/compiled/@workflow/core/global.d.ts +10 -0
- package/dist/src/compiled/@workflow/core/index.js +1 -1
- package/dist/src/compiled/@workflow/core/private.d.ts +11 -0
- package/dist/src/compiled/@workflow/core/private.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +36 -8
- package/dist/src/compiled/@workflow/core/runtime/helpers.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime/lifecycle-hooks.d.ts +10 -6
- package/dist/src/compiled/@workflow/core/runtime/out-of-band-observation.d.ts +159 -0
- package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +28 -4
- package/dist/src/compiled/@workflow/core/runtime.js +4 -4
- package/dist/src/compiled/@workflow/core/serialization.js +1 -1
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/world-local/index.js +5 -5
- package/dist/src/compiled/@workflow/world-vercel/index.js +4 -4
- package/dist/src/compiled/_chunks/workflow/{attribute-changes-CSqvJx6j.js → attribute-changes-BW-kbMMn.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/dist-CyBgVS7g.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{helpers-BXCuoPUb.js → helpers-DlLD3ov_.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/private-tQUuwBoQ.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{resume-hook-CvENCrxc.js → resume-hook-DMsV_b4n.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{run-8pLWuR2U.js → run-DzdAqdb1.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{serialization-vDozzDhh.js → serialization-DPdYS_w2.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/sleep-BY6leHh8.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{token-BKeK6DmC.js → token-D5ugC3PI.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{token-util-CddTZ_ef.js → token-util-Bla5Z0G9.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/undici-D-ILjOKD.js +95 -0
- package/dist/src/compiled/_chunks/workflow/{wait-until-A344L2AG.js → wait-until-xbRRDuUf.js} +1 -1
- package/dist/src/compiler/extension-compatibility.d.ts +18 -12
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/context/dynamic-connection-lifecycle.d.ts +6 -0
- package/dist/src/context/dynamic-connection-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +4 -1
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/providers/sandbox.js +1 -1
- package/dist/src/context/providers/tool-stubs-key.d.ts +8 -0
- package/dist/src/context/providers/tool-stubs-key.js +1 -0
- package/dist/src/context/providers/tool-stubs.d.ts +10 -0
- package/dist/src/context/providers/tool-stubs.js +1 -0
- package/dist/src/context/run-step.js +1 -1
- package/dist/src/evals/index.d.ts +1 -0
- package/dist/src/evals/runner/execute-task.js +1 -1
- package/dist/src/evals/session-manager.d.ts +2 -0
- package/dist/src/evals/session-manager.js +1 -1
- package/dist/src/eve-channel/create-request.d.ts +2 -0
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/eve-channel/request.js +1 -1
- package/dist/src/execution/agent-sessions/context.d.ts +2 -0
- package/dist/src/execution/agent-sessions/context.js +1 -1
- package/dist/src/execution/agent-sessions/steps.js +1 -1
- package/dist/src/execution/cancelled-model-call-batch.js +1 -1
- package/dist/src/execution/dynamic-connection-recovery.d.ts +14 -0
- package/dist/src/execution/dynamic-connection-recovery.js +1 -0
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/forward-session-input.js +1 -1
- package/dist/src/execution/legacy-session/authorization.js +1 -1
- package/dist/src/execution/legacy-session/completion-step.js +1 -1
- package/dist/src/execution/legacy-session/inbox.js +1 -1
- package/dist/src/execution/legacy-session/interrupt-step.js +1 -1
- package/dist/src/execution/ndjson-stream.d.ts +6 -6
- package/dist/src/execution/ndjson-stream.js +3 -3
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/ensure.d.ts +3 -1
- package/dist/src/execution/sandbox/ensure.js +1 -1
- package/dist/src/execution/session/active-turn.js +1 -1
- package/dist/src/execution/session/admission.js +1 -1
- package/dist/src/execution/session/checkpoint-migrations.js +1 -1
- package/dist/src/execution/session/end-sandbox-step.d.ts +12 -0
- package/dist/src/execution/session/end-sandbox-step.js +1 -0
- package/dist/src/execution/session/finalization.js +1 -1
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/handoff.d.ts +1 -1
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/timeout-steps.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session-inbox/inbox.d.ts +6 -1
- package/dist/src/execution/session-inbox/inbox.js +1 -1
- package/dist/src/execution/session-inbox/release-step.js +1 -1
- package/dist/src/execution/session-inbox/resume.d.ts +2 -1
- package/dist/src/execution/session-inbox/resume.js +1 -1
- package/dist/src/execution/session-workflow-tool-run.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/tasks/model-step.js +1 -1
- package/dist/src/execution/tasks/steps.js +1 -1
- package/dist/src/execution/tasks/table.d.ts +7 -1
- package/dist/src/execution/tasks/table.js +1 -1
- package/dist/src/execution/tool-stubs/playback.d.ts +11 -0
- package/dist/src/execution/tool-stubs/playback.js +1 -0
- package/dist/src/execution/tool-stubs/steps.d.ts +18 -0
- package/dist/src/execution/tool-stubs/steps.js +1 -0
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/connection-tools.d.ts +0 -6
- package/dist/src/execution/tools/connection-tools.js +2 -2
- package/dist/src/execution/tools/workflow/authorization-completion.js +1 -1
- package/dist/src/execution/tools/workflow/body.js +1 -1
- package/dist/src/execution/tools/workflow/serve.js +1 -1
- package/dist/src/execution/tools/workflow/withdraw-step.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-webhook-route.js +1 -1
- package/dist/src/harness/compaction/engine.d.ts +8 -19
- package/dist/src/harness/compaction/engine.js +1 -1
- package/dist/src/harness/compaction/step.d.ts +7 -1
- package/dist/src/harness/compaction/step.js +1 -1
- package/dist/src/harness/coordination.js +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/hitl/approved-calls.d.ts +2 -0
- package/dist/src/harness/hitl/approved-calls.js +1 -1
- package/dist/src/harness/hitl/index.d.ts +9 -1
- package/dist/src/harness/hitl/index.js +1 -1
- package/dist/src/harness/hitl/intake.js +1 -1
- package/dist/src/harness/model-call/call.d.ts +2 -3
- package/dist/src/harness/model-call/call.js +1 -1
- package/dist/src/harness/model-call/model.d.ts +4 -5
- package/dist/src/harness/model-call/model.js +1 -1
- package/dist/src/harness/model-call/request.d.ts +1 -2
- package/dist/src/harness/model-call/request.js +1 -1
- package/dist/src/harness/model-call/retry.d.ts +1 -1
- package/dist/src/harness/model-call/retry.js +1 -1
- package/dist/src/harness/model-call/run.js +1 -1
- package/dist/src/harness/model-call/tools.d.ts +3 -4
- package/dist/src/harness/model-call/tools.js +1 -1
- package/dist/src/harness/model-call/usage.js +1 -1
- package/dist/src/harness/model-profile.d.ts +23 -0
- package/dist/src/harness/model-profile.js +1 -0
- package/dist/src/harness/prompt-cache.d.ts +5 -53
- package/dist/src/harness/prompt-cache.js +1 -1
- package/dist/src/harness/provider-safety.d.ts +3 -5
- package/dist/src/harness/provider-safety.js +1 -1
- package/dist/src/harness/provider-tools.d.ts +5 -13
- package/dist/src/harness/provider-tools.js +1 -1
- package/dist/src/harness/proxy-input-requests.d.ts +17 -6
- package/dist/src/harness/proxy-input-requests.js +1 -1
- package/dist/src/harness/session-machine/current.d.ts +4 -0
- package/dist/src/harness/session-machine/current.js +1 -1
- package/dist/src/harness/step/after-model.js +1 -1
- package/dist/src/harness/step/context.d.ts +7 -2
- package/dist/src/harness/step/context.js +1 -1
- package/dist/src/harness/step-hooks.d.ts +2 -3
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-call-io.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/tools.d.ts +2 -3
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/harness/turn-tag-state.d.ts +12 -0
- package/dist/src/harness/turn-tag-state.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/gateway.d.ts +0 -13
- package/dist/src/internal/gateway.js +1 -1
- package/dist/src/internal/invocation/workflow-execution.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/workflow/cancel-expired-development-run.js +1 -1
- package/dist/src/protocol/routes.d.ts +4 -0
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/auth.d.ts +21 -4
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/public/channels/mcp.js +1 -1
- package/dist/src/public/schedules/providers/in-memory.js +1 -1
- package/dist/src/public/schedules/providers/vercel.js +1 -1
- package/dist/src/public/schedules/subscription.d.ts +0 -1
- package/dist/src/sandbox/state.d.ts +1 -0
- package/dist/src/self-modification/extension/subagents/agent/instructions.js +1 -1
- package/dist/src/self-modification/extension/subagents/agent/tools/registry_add.js +1 -1
- package/dist/src/setup/flows/registry-session.d.ts +10 -2
- package/dist/src/setup/flows/registry-session.js +1 -1
- package/dist/src/setup/flows/registry.d.ts +2 -0
- package/dist/src/setup/flows/registry.js +1 -1
- package/dist/src/setup/integrations/shared/prerequisite.d.ts +8 -0
- package/dist/src/setup/integrations/shared/prerequisite.js +1 -1
- package/dist/src/setup/registry-setup-client.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +3 -2
- package/dist/src/setup/scaffold/create/web-template.js +383 -411
- package/dist/src/setup/scaffold/index.js +1 -1
- package/dist/src/setup/vercel-project.d.ts +2 -3
- package/dist/src/setup/vercel-project.js +0 -0
- package/dist/src/shared/sandbox-provider.d.ts +9 -2
- package/dist/src/subagents/adapter.d.ts +3 -2
- package/dist/src/subagents/adapter.js +1 -1
- package/dist/src/subagents/callback-route.js +1 -1
- package/dist/src/subagents/hitl-proxy.d.ts +4 -3
- package/dist/src/subagents/hitl-proxy.js +1 -1
- package/dist/src/subagents/parent-notification.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tool-stubs/execute.d.ts +13 -0
- package/dist/src/tool-stubs/execute.js +1 -0
- package/dist/src/tool-stubs/output.d.ts +4 -0
- package/dist/src/tool-stubs/output.js +1 -0
- package/dist/src/tool-stubs/playback.d.ts +15 -0
- package/dist/src/tool-stubs/playback.js +1 -0
- package/dist/src/tool-stubs/rules.d.ts +3 -0
- package/dist/src/tool-stubs/rules.js +1 -0
- package/dist/src/tool-stubs/schema.d.ts +4 -0
- package/dist/src/tool-stubs/schema.js +1 -0
- package/dist/src/tool-stubs/target.d.ts +8 -0
- package/dist/src/tool-stubs/target.js +1 -0
- package/dist/src/tool-stubs/types.d.ts +56 -0
- package/dist/src/tool-stubs/types.js +1 -0
- package/dist/src/tool-stubs/validate-targets.d.ts +6 -0
- package/dist/src/tool-stubs/validate-targets.js +1 -0
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +2 -2
- package/docs/evals/meta.json +10 -1
- package/docs/evals/overview.mdx +2 -0
- package/docs/evals/tool-stubs.mdx +257 -0
- package/docs/extensions.md +1 -1
- package/docs/guides/auth-and-route-protection.md +25 -0
- package/docs/guides/dynamic-capabilities.md +10 -3
- package/docs/guides/frontend/nextjs.mdx +17 -4
- package/docs/sandbox/index.mdx +10 -2
- package/docs/subagents/index.mdx +1 -1
- package/docs/tools/human-in-the-loop.md +1 -1
- package/docs/tools/overview.mdx +8 -4
- package/docs/tools/workflows.mdx +15 -7
- package/package.json +6 -6
- package/dist/src/compiled/_chunks/workflow/dist-DmXynLVH.js +0 -1
- package/dist/src/compiled/_chunks/workflow/private-Dlf90Zvn.js +0 -1
- package/dist/src/compiled/_chunks/workflow/signal-exit-iIdjQcCK.js +0 -95
- package/dist/src/compiled/_chunks/workflow/sleep-BMqbraZM.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{fileURLToPath}from"node:url";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";let cachedPackageInfo,cachedPackageLocation;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.
|
|
1
|
+
import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{fileURLToPath}from"node:url";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";let cachedPackageInfo,cachedPackageLocation;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.75.1`,WORKFLOW_MODULE_ALIASES={"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`};function resolveFallbackPackageVersion(){return BUNDLED_FALLBACK_PACKAGE_VERSION.startsWith(`__`)?`0.0.0`:BUNDLED_FALLBACK_PACKAGE_VERSION}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const packageRequire=createRequire(resolveCurrentModulePath());function tryResolveVerifiedPackageRoot(e){try{let t=realpathSync.native(e);return tryReadInstalledPackageInfo(t,EVE_PACKAGE_NAME)===void 0?void 0:dirname(t)}catch{return}}function findNearestVerifiedPackageRoot(e){let t=e;for(;;){let e=tryResolveVerifiedPackageRoot(join(t,`package.json`));if(e!==void 0)return e;let n=dirname(t);if(n===t)return;t=n}}function tryResolveDirectBuildLocation(e){let t=dirname(e);for(;;){if(basename(t)===`dist`){let e=tryResolveVerifiedPackageRoot(join(dirname(t),`package.json`));if(e!==void 0)return{packageBuildRoot:t,packageRoot:e}}let e=dirname(t);if(e===t)return;t=e}}function isSourceCheckout(e){return existsSync(join(e,`src`,`internal`,`application`,`package.ts`))}function tryCreatePackageLocation(e){if(isSourceCheckout(e))return{packageBuildRoot:null,packageRoot:e};let t=join(e,`dist`);if(existsSync(t))return{packageBuildRoot:t,packageRoot:e}}function resolveSelfPackageJsonPath(e){return createRequire(e).resolve(`${EVE_PACKAGE_NAME}/package.json`)}function resolvePackageLocationFromModulePath(e,t=resolveSelfPackageJsonPath){let n=realpathSync.native(e),r=tryResolveDirectBuildLocation(n);if(r!==void 0)return r;let i=findNearestVerifiedPackageRoot(dirname(n));if(i!==void 0&&isSourceCheckout(i))return{packageBuildRoot:null,packageRoot:i};try{let e=tryResolveVerifiedPackageRoot(t(n)),r=e===void 0?void 0:tryCreatePackageLocation(e);if(r!==void 0)return r}catch{}let a=i===void 0?void 0:tryCreatePackageLocation(i);if(a!==void 0)return a;throw Error(`Failed to resolve the eve package root from "${e}".`)}function resolvePackageLocation(){return cachedPackageLocation??=resolvePackageLocationFromModulePath(resolveCurrentModulePath()),cachedPackageLocation}function resolvePackageBuildRoot(){return resolvePackageLocation().packageBuildRoot}function resolvePackageRoot(){return resolvePackageLocation().packageRoot}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){try{return packageRequire.resolve(e)}catch(t){let n=tryResolvePackageRoot(),r=n===void 0||!isSourceCheckout(n)?void 0:resolveSourceCheckoutExport(n,e);if(r!==void 0)return r;throw t}}function resolveSourceCheckoutExport(e,t){if(t!==EVE_PACKAGE_NAME&&!t.startsWith(`${EVE_PACKAGE_NAME}/`))return;let n=t===EVE_PACKAGE_NAME?`.`:`.${t.slice(EVE_PACKAGE_NAME.length)}`;try{let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`)).exports?.[n],r=typeof t==`string`?t:t?.[`eve-source`]??t?.import??t?.default;if(r===void 0)return;let i=r.replace(/^\.\/dist\/src\//,`src/`).replace(/\.[cm]?js$/u,`.ts`),a=join(e,i);return existsSync(a)?a:void 0}catch{return}}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(typeof t.name==`string`&&typeof t.version==`string`)return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let n=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(n?.name===t)return n}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(packageRequire.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function readWorkflowVersionFromManifest(e){let t=e;for(let e of[t.devDependencies,t.dependencies,t.peerDependencies]){let t=e?.[`@workflow/core`];if(typeof t==`string`&&t.trim().length>0)return t}}function resolveExpectedWorkflowVersion(){let e=tryResolvePackageRoot();if(e!==void 0)try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(join(e,`package.json`),`utf8`)))}catch{}try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(packageRequire.resolve(`${EVE_PACKAGE_NAME}/package.json`),`utf8`)))}catch{return}}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/api`||e===`workflow/runtime`)return resolvePackageSourceFilePath(`src/internal/workflow/runtime.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?packageRequire.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveExpectedWorkflowVersion,resolveInstalledPackageInfo,resolvePackageCompiledFilePath,resolvePackageDependencyPath,resolvePackageLocationFromModulePath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { LanguageModel } from "ai";
|
|
2
1
|
/** AI Gateway model listing endpoint (OpenAI-compatible `/v1/models`). */
|
|
3
2
|
export declare const AI_GATEWAY_MODELS_URL = "https://ai-gateway.vercel.sh/v1/models";
|
|
4
3
|
/** AI Gateway model catalog endpoint, the richer variant of {@link AI_GATEWAY_MODELS_URL}. */
|
|
@@ -10,15 +9,3 @@ export declare const AI_GATEWAY_MODELS_CATALOG_URL = "https://ai-gateway.vercel.
|
|
|
10
9
|
* constructed per call site, so this is a value rather than a factory.
|
|
11
10
|
*/
|
|
12
11
|
export declare const vercelGatewayFetch: typeof globalThis.fetch;
|
|
13
|
-
/**
|
|
14
|
-
* Request headers eve attaches for a model's provider, or `undefined` when
|
|
15
|
-
* the provider needs none. Gateway-routed models (bare ids and `gateway.*`
|
|
16
|
-
* instances) get the eve User-Agent product token so AI Gateway can attribute
|
|
17
|
-
* the traffic; direct-provider models get no extra headers.
|
|
18
|
-
*/
|
|
19
|
-
export declare function resolveProviderHeaders(model: LanguageModel): Record<string, string> | undefined;
|
|
20
|
-
/** Provider identity reported by the model, normalized for bare Gateway ids. */
|
|
21
|
-
export declare function resolveModelProvider(model: LanguageModel): string | undefined;
|
|
22
|
-
export declare function isGatewayModel(model: LanguageModel): boolean;
|
|
23
|
-
/** Groups Gateway generations under the same identity used by eve's agent spans. */
|
|
24
|
-
export declare function mergeGatewaySessionId(model: LanguageModel, providerOptions: Readonly<Record<string, unknown>> | undefined, conversationId: string): Record<string, unknown> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{withPackageUserAgent}from"#internal/user-agent.js";const GATEWAY_BASE_URL=`https://ai-gateway.vercel.sh`,AI_GATEWAY_MODELS_URL=`${GATEWAY_BASE_URL}/v1/models`,AI_GATEWAY_MODELS_CATALOG_URL=`${GATEWAY_BASE_URL}/v1/models/catalog`,vercelGatewayFetch=withPackageUserAgent();export{AI_GATEWAY_MODELS_CATALOG_URL,AI_GATEWAY_MODELS_URL,vercelGatewayFetch};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseInputResponses}from"#shared/input.js";import{parseJsonValue}from"#shared/json.js";import{
|
|
1
|
+
import{parseInputResponses}from"#shared/input.js";import{parseJsonValue}from"#shared/json.js";import{getRun,getWorld}from"#internal/workflow/runtime.js";import{RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{parseNdjsonStream}from"#execution/ndjson-stream.js";import{INVOCATION_OWNER_ATTRIBUTE,INVOCATION_TOKEN_ATTRIBUTE,invocationInputRequestId,invocationOwnerKey}from"#internal/invocation/metadata.js";var WorkflowAgentInvocationExecution=class{#e;#t;constructor(e){this.#e=e.createSession,this.#t=e.from}async create(e){let t=`invocation:${crypto.randomUUID()}`,n=await this.#e({auth:e.auth,capabilities:{requestInput:!0},continuationToken:t,externalInvocation:{continuationToken:t,ownerKey:invocationOwnerKey(e.auth)},input:{message:e.message}}),r=await this.#n(n.sessionId,e.auth);if(r===void 0)throw Error(`Invocation run was unavailable after durable creation.`);return workingInvocation(n.sessionId,r.createdAt.toISOString(),r.expiredAt?.toISOString())}async read(e){let t=await this.#n(e.invocationId,e.auth);if(t===void 0)return;let n={createdAt:t.createdAt.toISOString(),expiresAt:t.expiredAt?.toISOString(),invocationId:t.runId};return t.status===`cancelled`?{...n,status:`cancelled`}:projectInvocation(n,t.status,await readRecentPersistedEvents(e.invocationId))}async update(e){let t=await this.read(e);if(t===void 0)return{type:`not_found`};if(t.status!==`input_required`)return replaysResolvedBatch(await readRecentPersistedEvents(e.invocationId),e.responses)?{invocation:t,type:`success`}:conflict(`Invocation is not waiting for input.`);let n=await this.#n(e.invocationId,e.auth);if(n===void 0)return{type:`not_found`};let r=latestPendingInputBatch(await readRecentPersistedEvents(e.invocationId));if(r===void 0)return conflict(`Invocation input changed before the update could be applied.`);let i=new Set,a=[];for(let t of e.responses){let e=r.rawRequestIds[t.requestId];if(e===void 0)return conflict(`Unknown input request: ${t.requestId}`);i.add(t.requestId),a.push({...t,requestId:e})}if(i.size!==e.responses.length||i.size!==Object.keys(r.requests).length)return conflict(`Responses must answer the complete pending input batch exactly once.`);let o=n.attributes[INVOCATION_TOKEN_ATTRIBUTE];if(o===void 0)return{type:`not_found`};try{await this.#t(o).respond(parseInputResponses(a),{auth:e.auth})}catch(e){if(RunExpiredError.is(e))return{type:`not_found`};throw e}return{invocation:workingInvocation(e.invocationId,t.createdAt,t.expiresAt),type:`success`}}async cancel(e){let t=await this.read(e);if(t===void 0||isTerminal(t.status))return t;try{await getRun(e.invocationId).cancel()}catch(e){if(WorkflowRunNotFoundError.is(e)||RunExpiredError.is(e))return;throw e}return await this.read(e)}async#n(e,t){let n=await getWorld();try{let r=await n.runs.get(e);return r.attributes[INVOCATION_TOKEN_ATTRIBUTE]===void 0?void 0:r.attributes[INVOCATION_OWNER_ATTRIBUTE]===invocationOwnerKey(t)?r:void 0}catch(e){if(WorkflowRunNotFoundError.is(e)||RunExpiredError.is(e))return;throw e}}};async function readRecentPersistedEvents(e){let t=getRun(e).getReadable({startIndex:-64}),n=await t.getTailIndex();if(n<0)return await t.cancel(`invocation event stream is empty`).catch(()=>{}),[];let r=Math.min(n+1,64),i=parseNdjsonStream(()=>t).getReader(),a=[];try{for(;a.length<r;){let{done:e,value:t}=await i.read();if(e)break;a.push(t)}}finally{await i.cancel(`invocation event window read complete`).catch(()=>{}),i.releaseLock()}return a}function pendingInputBatch(e){let t={},n={};for(let r of e.data.requests){let i=invocationInputRequestId(e.meta.id,r.requestId);t[i]=r.requestId,n[i]={...r,requestId:i}}return{id:e.meta.id,rawRequestIds:t,requests:n}}function withoutResolved(e,t){let n=new Set(t.map(e=>e.requestId)),r={},i={};for(let[t,a]of Object.entries(e.rawRequestIds)){if(n.has(a))continue;r[t]=a;let o=e.requests[t];o!==void 0&&(i[t]=o)}return Object.keys(r).length===0?void 0:{id:e.id,rawRequestIds:r,requests:i}}function foldInputBatches(e){let t,n,r;for(let i of e)if(i.type===`input.requested`)n=pendingInputBatch(i),t=n;else if(i.type===`input.resolved`){if(n===void 0)continue;let e=new Map;for(let t of i.data.resolutions)e.set(t.requestId,t.response);r={batch:n,responses:e},t!==void 0&&(t=withoutResolved(t,i.data.resolutions))}else i.type===`turn.started`&&(t=void 0);return{pending:t,resolved:r}}function latestPendingInputBatch(e){return foldInputBatches(e).pending}function replaysResolvedBatch(e,t){let n=foldInputBatches(e).resolved;if(n===void 0||t.length!==n.responses.size)return!1;let r=new Set;for(let e of t){let t=n.batch.rawRequestIds[e.requestId];if(t===void 0||r.has(t)||(r.add(t),!n.responses.has(t)))return!1;let i=n.responses.get(t);if(i?.optionId!==e.optionId||i?.text!==e.text)return!1}return!0}function projectInvocation(e,t,n){let r=new Map,i,a,o;for(let e of n)switch(e.type){case`turn.started`:r.clear(),i=void 0,a=void 0,o=void 0;break;case`input.requested`:i=pendingInputBatch(e);break;case`input.resolved`:i!==void 0&&(i=withoutResolved(i,e.data.resolutions)),o=void 0;break;case`authorization.required`:{let t={description:e.data.description,name:e.data.name};e.data.authorization!==void 0&&(t.authorization=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),r.set(e.data.name,t);break}case`authorization.completed`:r.delete(e.data.name),o=void 0;break;case`message.completed`:e.data.finishReason!==`tool-calls`&&(a=safeJson(e.data.message));break;case`turn.waiting`:a=void 0;break;case`turn.completed`:o=`completed`;break;case`turn.cancelled`:o=`cancelled`;break;case`turn.failed`:case`session.failed`:o=e}let s=typeof o==`object`?o:void 0,failed=()=>({...e,error:publicInvocationFailure(e.invocationId,s),status:`failed`});if(t===`failed`||s?.type===`session.failed`)return failed();if(t===`completed`)return{...e,result:a,status:`completed`};let c=[...r.values()];return c.length>0?{...e,authorizations:c,pollAfterMs:1e3,result:a,status:`authorization_required`}:i===void 0?s===void 0?o===`cancelled`?{...e,status:`cancelled`}:o===`completed`?{...e,result:a,status:`completed`}:{...e,pollAfterMs:1e3,result:a,status:`working`}:failed():{...e,inputRequests:i.requests,result:a,status:`input_required`}}function workingInvocation(e,t,n){return{createdAt:t,expiresAt:n,invocationId:e,pollAfterMs:1e3,status:`working`}}function safeJson(e){try{return parseJsonValue(e)}catch{return String(e)}}function publicInvocationFailure(e,t){let n={runId:e};t!==void 0&&(n.eveCode=t.data.code);let r=vercelDeploymentId();r!==void 0&&(n.vercelDeploymentId=r),typeof t?.data.details?.errorId==`string`&&(n.errorId=t.data.details.errorId);let i=t===void 0?null:semanticFailure(t.data);if(i===null){let e=t===void 0?null:fallbackFailure(t.data);return e===null?{code:-32603,data:n,message:`Invocation failed.`}:(e.name!==void 0&&(n.name=e.name),{code:-32603,data:n,message:e.message})}return n.semanticErrorId=i.id,n.name=i.name,i.hint!==void 0&&(n.hint=i.hint),{code:-32603,data:n,message:i.message}}function semanticFailure(e){let t=e.details;if(typeof t?.semanticErrorId!=`string`||t.semanticErrorId.trim().length===0||typeof t.name!=`string`||t.name.trim().length===0)return null;let n=typeof t.message==`string`&&t.message.trim().length>0?t.message.trim():e.message.trim();if(n.length===0)return null;let r=typeof t.hint==`string`&&t.hint.trim().length>0?t.hint.trim():void 0,i={id:t.semanticErrorId,message:n,name:t.name};return r!==void 0&&(i.hint=r),i}function fallbackFailure(e){let t=e.message.trim(),n=typeof e.details?.name==`string`?e.details.name.trim():``;if(t.length===0&&n.length===0)return null;let r={message:t.length===0?n:truncateForDisplay(t)};return n.length>0&&(r.name=n),r}function truncateForDisplay(e,t=160){return e.length<=t?e:`${e.slice(0,t-1).trimEnd()}…`}function vercelDeploymentId(){if(process.env.VERCEL!==`1`)return;let e=process.env.VERCEL_DEPLOYMENT_ID?.trim();return e&&e.length>0?e:void 0}function conflict(e){return{message:e,type:`conflict`}}function isTerminal(e){return e===`completed`||e===`failed`||e===`cancelled`}export{WorkflowAgentInvocationExecution};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createAttachSessionFn}from"#channel/session.js";import{createLogger,logError}from"#internal/logging.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{createChannelOperations}from"#channel/channel-operations.js";import{getChannelInstrumentationKind}from"#channel/compiled-channel.js";import{createCrossChannelToFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{readVercelProjectLink}from"#internal/vercel/project-link.js";import{attachAgentInfoRouteResponse,attachHomeRouteMetadata,attachRemoteAgentStreamHeadersResolver,attachRouteChannelName,attachRouteSessionCreator,attachSkillFileSource}from"#internal/nitro/routes/channel-route-context.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{
|
|
1
|
+
import{createAttachSessionFn}from"#channel/session.js";import{createLogger,logError}from"#internal/logging.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{createChannelOperations}from"#channel/channel-operations.js";import{getChannelInstrumentationKind}from"#channel/compiled-channel.js";import{createCrossChannelToFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{readVercelProjectLink}from"#internal/vercel/project-link.js";import{getWorld}from"#internal/workflow/runtime.js";import{attachAgentInfoRouteResponse,attachHomeRouteMetadata,attachRemoteAgentStreamHeadersResolver,attachRouteChannelName,attachRouteSessionCreator,attachSkillFileSource}from"#internal/nitro/routes/channel-route-context.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{DEVELOPMENT_WORKFLOW_SECRET_ENV}from"#internal/workflow/development-world-protocol.js";import{readTrustedDevelopmentClientAddress}from"#internal/nitro/dev-client-address.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";import{withLocalDevRequestScope}from"#runtime/local-dev-capability.js";import{createAgentDescriptionRouteArgs}from"#channel/agent-description.js";import{traceChannelRequest}from"#internal/nitro/routes/channel-request-instrumentation.js";import{resolveNitroChannelRuntimeBundle}from"#internal/nitro/routes/runtime-stack.js";import{createRouteInvokeTool}from"#internal/nitro/routes/route-invoke-tool.js";import{withVercelOidcProjectResolver}from"#channel/auth/vercel-oidc-project.js";const log=createLogger(`channel.dispatch`);async function dispatchChannelRequest(e,t,n){return await traceChannelRequest({request:e.req,routeKey:t},async r=>{let i=r?.spanContext()??trace.getSpan(context.active())?.spanContext(),a=await resolveNitroChannelRuntimeBundle(n),o=a.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(o===void 0)return Response.json({error:`No matching channel for this request.`,ok:!1},{status:404});r?.setAttribute(`eve.channel.name`,o.name);let s=getChannelInstrumentationKind(o.definition)??o.adapter?.kind;s!==void 0&&r?.setAttribute(`eve.channel.kind`,s);let c=await buildRouteArgs(e,a,o.name,s??`channel`,n,i),l;try{l=await withDevelopmentVercelOidcContext(n,e.req,async()=>{if(o.handler)return await o.handler(e.req,c.args);let t={waitUntil:c.args.waitUntil,params:c.args.params,requestIp:c.args.requestIp};return await o.fetch(e.req,t)})}catch(n){let r=logError(log,`channel handler threw`,n,{routeKey:t,channel:o.name});return flushBackgroundTasks(e,c.backgroundTasks,t,o.name),Response.json({error:`Channel handler failed.`,errorId:r,ok:!1},{status:500})}return flushBackgroundTasks(e,c.backgroundTasks,t,o.name),l})}async function dispatchChannelWebSocketRequest(e,t,n){let r=await resolveNitroChannelRuntimeBundle(n),i=r.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(i===void 0||i.websocket===void 0)return rejectWebSocketUpgrade({error:`No matching websocket channel for this request.`,ok:!1},404);let a=i.websocket,o=getChannelInstrumentationKind(i.definition)??i.adapter?.kind??`channel`,s=await buildRouteArgs(e,r,i.name,o,n,void 0);try{let r=await withDevelopmentVercelOidcContext(n,e.req,async()=>await a(e.req,s.args));return flushBackgroundTasks(e,s.backgroundTasks,t,i.name),r}catch(n){let r=logError(log,`channel websocket handler threw`,n,{routeKey:t,channel:i.name});return flushBackgroundTasks(e,s.backgroundTasks,t,i.name),rejectWebSocketUpgrade({error:`Channel websocket handler failed.`,errorId:r,ok:!1},500)}}async function withDevelopmentVercelOidcContext(e,t,n){return e.kind===`development`?await withLocalDevRequestScope(t,async()=>await withVercelOidcProjectResolver({request:t,resolveCurrentProject:async()=>{let t=await readVercelProjectLink(e.appRoot);return t===void 0?void 0:{environment:`development`,projectId:t.projectId}}},n)):await n()}async function buildRouteArgs(e,t,n,r,i,a){let o=readVercelRequestId(e.req.headers),s=extractRequestIp(e,i),c=[],l=e.context.params??{},u={};for(let[e,t]of Object.entries(l))u[e]=decodeURIComponent(t);let waitUntil=e=>{c.push(e)},d=t.channels.find(e=>e.name===n),f=d?.adapter??{kind:`channel`},p={acceptedDeploymentId:await resolveAcceptedDeploymentId(i),channelKind:r,channelName:n,requestId:o,requestTraceContext:a===void 0?void 0:{spanId:a.spanId,traceFlags:a.traceFlags,traceId:a.traceId}},m=createChannelOperations({adapter:f,channelName:n,metadata:p,runtime:t.runtime,turnPolicy:d?.turnPolicy}),h=createAttachSessionFn(t.runtime,{...p,turnPolicy:d?.turnPolicy}),g=createCrossChannelToFn(t.runtime,toCrossChannelTargets(t.channels)),_=createAgentDescriptionRouteArgs(()=>resolveNitroCompiledArtifactsSource(i)),v=attachRouteSessionCreator(attachHomeRouteMetadata(attachRouteChannelName(attachAgentInfoRouteResponse({attachSession:h,...m,..._.args,invokeTool:createRouteInvokeTool({agentName:t.agentName,config:i,origin:{adapter:f,agentName:t.agentName,channelName:n},requestUrl:e.req.url}),params:u,requestIp:s,to:g,waitUntil},async()=>{let{handleAgentInfoRequest:e}=await import(`#internal/nitro/routes/info.js`);return await e(i)}),n),{agentName:t.agentName}),async e=>await t.runtime.createSession({...e,adapter:f,channelName:n,continuationToken:e.continuationToken===void 0?void 0:`${n}:${e.continuationToken}`,delivery:createChannelDeliveryMetadata(p),requestId:o}));return attachSkillFileSource(v,_.skillFiles),t.resolveRemoteAgentStreamHeaders!==void 0&&attachRemoteAgentStreamHeadersResolver(v,t.resolveRemoteAgentStreamHeaders),{args:v,backgroundTasks:c}}async function resolveAcceptedDeploymentId(e){let t=process.env.VERCEL_DEPLOYMENT_ID?.trim();if(t!==void 0&&t.length>0)return validateDeploymentId(t);if(e.kind!==`development`||process.env[DEVELOPMENT_WORKFLOW_SECRET_ENV]!==void 0)return validateDeploymentId(await(await getWorld()).getDeploymentId())}function validateDeploymentId(e){if(e.length===0||e===`latest`)throw Error(`Channel ingress could not resolve an exact deployment id.`);return e}function readVercelRequestId(e){let t=e.get(`x-vercel-id`)?.trim();return t===``?void 0:t}function rejectWebSocketUpgrade(e,t){return{upgrade(){throw Response.json(e,{status:t})}}}function flushBackgroundTasks(e,t,n,r){t.length!==0&&e.waitUntil(Promise.allSettled(t).then(e=>{for(let t of e)t.status===`rejected`&&logError(log,`channel background task failed`,t.reason,{routeKey:n,channel:r})}))}function extractRequestIp(e,t){if(t.kind===`development`){let t=readTrustedDevelopmentClientAddress(e.req.headers,process.env[DEVELOPMENT_WORKFLOW_SECRET_ENV]);if(t!==void 0)return t}return extractSocketIp(e)}function extractSocketIp(e){let t=e.req.ip;return typeof t==`string`&&t.length>0?t:null}export{dispatchChannelRequest,dispatchChannelWebSocketRequest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{cancelRun}from"#internal/workflow/runtime.js";import{isInactiveWorkflowRunError}from"#internal/workflow/is-inactive-workflow-run-error.js";async function cancelExpiredDevelopmentRun(e,t){try{let n=await e.runs.get(t,{resolveData:`none`});if(n.status!==`pending`&&n.status!==`running`)return;try{await cancelRun(e,t,{cancelReason:`Development runtime snapshot is no longer available`})}catch(n){if(isInactiveWorkflowRunError(n))return;let r=await e.runs.get(t,{resolveData:`none`});if(r.status===`pending`||r.status===`running`)throw n}}catch(e){if(!isInactiveWorkflowRunError(e))throw e}}export{cancelExpiredDevelopmentRun};
|
|
@@ -27,6 +27,8 @@ export declare const EVE_SESSION_COMPACT_ROUTE_PATTERN = "/eve/v1/session/:sessi
|
|
|
27
27
|
export declare const EVE_SESSION_CLEAR_ROUTE_PATTERN = "/eve/v1/session/:sessionId/clear";
|
|
28
28
|
/** Stable route pattern for resetting one exact session ID. */
|
|
29
29
|
export declare const EVE_SESSION_RESET_ROUTE_PATTERN = "/eve/v1/session/:sessionId/reset";
|
|
30
|
+
/** Stable route pattern for eval tool-stub verification. */
|
|
31
|
+
export declare const EVE_SESSION_STUBS_ROUTE_PATTERN = "/eve/v1/session/:sessionId/stubs";
|
|
30
32
|
/** Stable event-stream route pattern for one exact session ID. */
|
|
31
33
|
export declare const EVE_SESSION_STREAM_ROUTE_PATTERN = "/eve/v1/session/:sessionId/stream";
|
|
32
34
|
/**
|
|
@@ -128,3 +130,5 @@ export declare function createEveConnectionCallbackRoutePath(name: string, attem
|
|
|
128
130
|
export declare function createEveCallbackRoutePath(token: string): string;
|
|
129
131
|
/** Builds the capability path used to answer one remote child turn. */
|
|
130
132
|
export declare function createEveTaskInputRoutePath(token: string): string;
|
|
133
|
+
/** Builds the tool-stub verification route for one session. */
|
|
134
|
+
export declare function createEveSessionStubsRoutePath(sessionId: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const EVE_ROUTE_PREFIX=`/eve/v1`,EVE_PRODUCTION_CRON_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/cron/:token`,EVE_HEALTH_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/health`,EVE_INFO_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/info`,EVE_SESSION_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/session`,EVE_SESSION_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId`,EVE_SESSION_CANCEL_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/cancel`,EVE_SESSION_COMPACT_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/compact`,EVE_SESSION_CLEAR_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/clear`,EVE_SESSION_RESET_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/reset`,EVE_SESSION_STREAM_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/stream`,EVE_SUBAGENT_STREAM_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:parentSessionId/subagents/:callId/:childSessionId/stream`,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/suspend`,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/resume`;function createEveDevDispatchSchedulePath(e){return`${EVE_ROUTE_PREFIX}/dev/schedules/${encodeURIComponent(e)}`}const EVE_CONNECTION_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/connections/:name/callback/:attemptId/:token`,EVE_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/callback/:token`;function createEveSessionRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}`}function createEveSessionCancelRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/cancel`}function createEveSubagentStreamRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e.parentSessionId)}/subagents/${encodeURIComponent(e.callId)}/${encodeURIComponent(e.childSessionId)}/stream`}function createEveSessionCompactRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/compact`}function createEveSessionClearRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/clear`}function createEveSessionResetRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/reset`}function createEveSessionStreamRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/stream`}function createEveConnectionCallbackRoutePath(e,t,n){return`${EVE_ROUTE_PREFIX}/connections/${encodeURIComponent(e)}/callback/${encodeURIComponent(t)}/${encodeURIComponent(n)}`}function createEveCallbackRoutePath(e){return`${EVE_ROUTE_PREFIX}/callback/${encodeURIComponent(e)}`}function createEveTaskInputRoutePath(e){return`${EVE_ROUTE_PREFIX}/task-input/${encodeURIComponent(e)}`}export{EVE_CALLBACK_ROUTE_PATTERN,EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH,EVE_HEALTH_ROUTE_PATH,EVE_INFO_ROUTE_PATH,EVE_PRODUCTION_CRON_ROUTE_PATTERN,EVE_ROUTE_PREFIX,EVE_SESSION_CANCEL_ROUTE_PATTERN,EVE_SESSION_CLEAR_ROUTE_PATTERN,EVE_SESSION_COMPACT_ROUTE_PATTERN,EVE_SESSION_RESET_ROUTE_PATTERN,EVE_SESSION_ROUTE_PATH,EVE_SESSION_ROUTE_PATTERN,EVE_SESSION_STREAM_ROUTE_PATTERN,EVE_SUBAGENT_STREAM_ROUTE_PATTERN,createEveCallbackRoutePath,createEveConnectionCallbackRoutePath,createEveDevDispatchSchedulePath,createEveSessionCancelRoutePath,createEveSessionClearRoutePath,createEveSessionCompactRoutePath,createEveSessionResetRoutePath,createEveSessionRoutePath,createEveSessionStreamRoutePath,createEveSubagentStreamRoutePath,createEveTaskInputRoutePath};
|
|
1
|
+
const EVE_ROUTE_PREFIX=`/eve/v1`,EVE_PRODUCTION_CRON_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/cron/:token`,EVE_HEALTH_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/health`,EVE_INFO_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/info`,EVE_SESSION_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/session`,EVE_SESSION_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId`,EVE_SESSION_CANCEL_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/cancel`,EVE_SESSION_COMPACT_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/compact`,EVE_SESSION_CLEAR_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/clear`,EVE_SESSION_RESET_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/reset`,EVE_SESSION_STUBS_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/stubs`,EVE_SESSION_STREAM_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/stream`,EVE_SUBAGENT_STREAM_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:parentSessionId/subagents/:callId/:childSessionId/stream`,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/suspend`,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/resume`;function createEveDevDispatchSchedulePath(e){return`${EVE_ROUTE_PREFIX}/dev/schedules/${encodeURIComponent(e)}`}const EVE_CONNECTION_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/connections/:name/callback/:attemptId/:token`,EVE_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/callback/:token`;function createEveSessionRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}`}function createEveSessionCancelRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/cancel`}function createEveSubagentStreamRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e.parentSessionId)}/subagents/${encodeURIComponent(e.callId)}/${encodeURIComponent(e.childSessionId)}/stream`}function createEveSessionCompactRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/compact`}function createEveSessionClearRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/clear`}function createEveSessionResetRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/reset`}function createEveSessionStreamRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/stream`}function createEveConnectionCallbackRoutePath(e,t,n){return`${EVE_ROUTE_PREFIX}/connections/${encodeURIComponent(e)}/callback/${encodeURIComponent(t)}/${encodeURIComponent(n)}`}function createEveCallbackRoutePath(e){return`${EVE_ROUTE_PREFIX}/callback/${encodeURIComponent(e)}`}function createEveTaskInputRoutePath(e){return`${EVE_ROUTE_PREFIX}/task-input/${encodeURIComponent(e)}`}function createEveSessionStubsRoutePath(e){return`${createEveSessionRoutePath(e)}/stubs`}export{EVE_CALLBACK_ROUTE_PATTERN,EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH,EVE_HEALTH_ROUTE_PATH,EVE_INFO_ROUTE_PATH,EVE_PRODUCTION_CRON_ROUTE_PATTERN,EVE_ROUTE_PREFIX,EVE_SESSION_CANCEL_ROUTE_PATTERN,EVE_SESSION_CLEAR_ROUTE_PATTERN,EVE_SESSION_COMPACT_ROUTE_PATTERN,EVE_SESSION_RESET_ROUTE_PATTERN,EVE_SESSION_ROUTE_PATH,EVE_SESSION_ROUTE_PATTERN,EVE_SESSION_STREAM_ROUTE_PATTERN,EVE_SESSION_STUBS_ROUTE_PATTERN,EVE_SUBAGENT_STREAM_ROUTE_PATTERN,createEveCallbackRoutePath,createEveConnectionCallbackRoutePath,createEveDevDispatchSchedulePath,createEveSessionCancelRoutePath,createEveSessionClearRoutePath,createEveSessionCompactRoutePath,createEveSessionResetRoutePath,createEveSessionRoutePath,createEveSessionStreamRoutePath,createEveSessionStubsRoutePath,createEveSubagentStreamRoutePath,createEveTaskInputRoutePath};
|
|
@@ -220,6 +220,13 @@ export declare class ForbiddenError extends Error {
|
|
|
220
220
|
readonly response: Response;
|
|
221
221
|
constructor(opts?: AuthErrorOptions);
|
|
222
222
|
}
|
|
223
|
+
export interface AuthResult extends SessionAuthContext {
|
|
224
|
+
/**
|
|
225
|
+
* Set to true to let this authenticated caller create sessions with tool stubs.
|
|
226
|
+
* Callers without this permission cannot supply stubs.
|
|
227
|
+
*/
|
|
228
|
+
readonly allowToolStubs?: boolean;
|
|
229
|
+
}
|
|
223
230
|
/**
|
|
224
231
|
* Route auth callback. Returned value semantics inside {@link routeAuth}:
|
|
225
232
|
*
|
|
@@ -231,7 +238,7 @@ export declare class ForbiddenError extends Error {
|
|
|
231
238
|
* {@link UnauthenticatedError} or {@link ForbiddenError}. To accept anonymous
|
|
232
239
|
* traffic, include {@link none} as the final entry.
|
|
233
240
|
*/
|
|
234
|
-
export type AuthFn<TEvent = Request> = (event: TEvent) =>
|
|
241
|
+
export type AuthFn<TEvent = Request> = (event: TEvent) => AuthResult | null | undefined | Promise<AuthResult | null | undefined>;
|
|
235
242
|
/**
|
|
236
243
|
* OAuth protected-resource metadata attached to an inbound auth policy.
|
|
237
244
|
* `issuer` is shorthand for a single authorization server.
|
|
@@ -297,7 +304,7 @@ export declare function withAuthChallenges<TEvent>(fn: AuthFn<TEvent>, challenge
|
|
|
297
304
|
* a custom `defineChannel` route handler) should call `routeAuth` rather than
|
|
298
305
|
* re-implement the walk.
|
|
299
306
|
*/
|
|
300
|
-
export declare function routeAuth(request: Request, auth: AuthFn<Request> | readonly AuthFn<Request>[]): Promise<
|
|
307
|
+
export declare function routeAuth(request: Request, auth: AuthFn<Request> | readonly AuthFn<Request>[]): Promise<AuthResult | Response>;
|
|
301
308
|
/**
|
|
302
309
|
* Returns an {@link AuthFn} for scaffolded apps that makes unfinished
|
|
303
310
|
* production auth fail as an intentional 401 rather than an internal route
|
|
@@ -343,7 +350,7 @@ export declare function none<TEvent = unknown>(): AuthFn<TEvent>;
|
|
|
343
350
|
*/
|
|
344
351
|
export declare function localDev(): AuthFn<Request>;
|
|
345
352
|
/**
|
|
346
|
-
* Options for
|
|
353
|
+
* Options for verifying a Vercel OIDC token with {@link verifyVercelOidc}.
|
|
347
354
|
*/
|
|
348
355
|
export interface VerifyVercelOidcOptions {
|
|
349
356
|
/**
|
|
@@ -452,13 +459,23 @@ export interface VercelSubjectInput {
|
|
|
452
459
|
* not exposed in `sub`. See Vercel's OIDC reference for the token anatomy.
|
|
453
460
|
*/
|
|
454
461
|
export declare function vercelSubject(input: VercelSubjectInput): string;
|
|
462
|
+
export interface VercelOidcOptions extends Omit<VerifyVercelOidcOptions, "subjects"> {
|
|
463
|
+
/**
|
|
464
|
+
* Additional token subjects allowed to authenticate.
|
|
465
|
+
* To allow stubs, use { subject, allowToolStubs: true } for that subject.
|
|
466
|
+
*/
|
|
467
|
+
readonly subjects?: readonly (string | {
|
|
468
|
+
readonly subject: string;
|
|
469
|
+
readonly allowToolStubs?: boolean;
|
|
470
|
+
})[];
|
|
471
|
+
}
|
|
455
472
|
/**
|
|
456
473
|
* Returns an HTTP route auth callback backed by Vercel OIDC. See
|
|
457
474
|
* {@link verifyVercelOidc} for the always-on current-project bypass and how
|
|
458
475
|
* `subjects` extends acceptance to other Vercel projects. Declares a
|
|
459
476
|
* `Bearer` {@link withAuthChallenges} challenge for {@link routeAuth}'s 401.
|
|
460
477
|
*/
|
|
461
|
-
export declare function vercelOidc(opts?:
|
|
478
|
+
export declare function vercelOidc(opts?: VercelOidcOptions): AuthFn<Request>;
|
|
462
479
|
/**
|
|
463
480
|
* Options accepted by {@link httpBasic}.
|
|
464
481
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{decodeJwt}from"#compiled/jose/index.js";import{isVercelOidcIssuer}from"#shared/vercel-project.js";import{isLoopbackHostname}from"#shared/network-address.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{resolveVercelOidcCurrentProject}from"#channel/auth/vercel-oidc-project.js";import{authenticateHttpBasicStrategy}from"#channel/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#channel/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#channel/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#channel/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#channel/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#channel/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let n=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n={algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-hmac`,secret:t.secret,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},r=await authenticateJwtHmacStrategy({strategy:n,token:e});return r.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(r.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n={algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-ecdsa`,publicKey:t.publicKey,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},r=await authenticateJwtEcdsaStrategy({strategy:n,token:e});return r.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(r.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1,currentVercelProject:void 0});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){if(e===null||e.length===0)return{kind:`not-authenticated`};let n={acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},r=t.currentVercelProject===void 0?n:{...n,currentVercelProject:t.currentVercelProject};return await authenticateOidcStrategy({strategy:r,token:e})}function extractBearerToken(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function createIpAllowList(e){return createRuntimeIpAllowList(e)}function isIpAllowed(e,t){return e!==null&&isRuntimeIpAllowed(e,t)}function createUnauthorizedResponse(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,formatChallenge(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function formatChallenge(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${escapeAuthChallengeParameter(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeAuthChallengeParameter(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}function isValidOAuthIdentifierUrl(e){try{let t=new URL(e);return(t.protocol===`https:`||t.protocol===`http:`&&isLoopbackHostname(t.hostname))&&t.username.length===0&&t.password.length===0&&t.search.length===0&&t.hash.length===0}catch{return!1}}function isValidMetadataPath(e){if(!e.startsWith(`/`)||e.startsWith(`//`))return!1;let t=new URL(e,`https://eve.invalid`);return t.origin===`https://eve.invalid`&&t.search.length===0&&t.hash.length===0}var UnauthenticatedError=class extends Error{response;constructor(e={}){super(e.message??`Authorization is required for this route.`),this.name=`UnauthenticatedError`,this.response=createUnauthorizedResponse({...e,status:401})}},ForbiddenError=class extends Error{response;constructor(e={}){super(e.message??`Forbidden.`),this.name=`ForbiddenError`,this.response=createUnauthorizedResponse({...e,status:403})}};const OAUTH_RESOURCE_SYMBOL=Symbol.for(`eve.channels.auth.oauthResource`);function oauthResource(e,t){let n=t.issuer===void 0?t.authorizationServers:[t.issuer];if(n.length===0||n.some(e=>!isValidOAuthIdentifierUrl(e)))throw Error(`oauthResource requires at least one HTTPS authorization server URL (HTTP is allowed only on loopback).`);if(t.resource!==void 0&&!isValidOAuthIdentifierUrl(t.resource))throw Error(`oauthResource resource must be an HTTPS URL without credentials, query, or fragment (HTTP is allowed only on loopback).`);if(t.metadataPath!==void 0&&!isValidMetadataPath(t.metadataPath))throw Error(`oauthResource metadataPath must be an absolute path without a host, query, or fragment.`);let r=Array.isArray(e)?e:[e],composed=async e=>{for(let t of r){let n=await t(e);if(n)return n}return null},i=collectDeclaredChallenges(r),a=withAuthChallenges(composed,i.length>0?i:[{scheme:`Bearer`}]);return Object.defineProperty(a,OAUTH_RESOURCE_SYMBOL,{enumerable:!1,value:t}),a}function readOAuthResourceOptions(e){if(!Array.isArray(e))return e[OAUTH_RESOURCE_SYMBOL]}const AUTH_CHALLENGES_SYMBOL=Symbol.for(`eve.channels.auth.challenges`);function withAuthChallenges(e,t){let wrapped=t=>e(t);return Object.defineProperty(wrapped,AUTH_CHALLENGES_SYMBOL,{value:t}),wrapped}function getDeclaredChallenges(e){return e[AUTH_CHALLENGES_SYMBOL]}function collectDeclaredChallenges(e){let t=new Set,n=[];for(let r of e)for(let e of getDeclaredChallenges(r)??[]){let r=formatChallenge(e);t.has(r)||(t.add(r),n.push(e))}return n}async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];try{for(let t of n){let n=await t(e);if(n)return n}}catch(e){if(typeof e==`object`&&e&&`response`in e&&e.response instanceof Response)return e.response;throw e}let r=collectDeclaredChallenges(n);return createUnauthorizedResponse({challenges:r.length>0?addInvalidBearerTokenError(e,r):[{scheme:`Bearer`}]})}function addInvalidBearerTokenError(e,t){let n=e.headers.get(`authorization`);return n===null||!/^Bearer(?:\s|$)/i.test(n.trim())||!t.some(e=>e.scheme===`Bearer`)?t:t.map(e=>e.scheme!==`Bearer`||e.parameters?.error!==void 0?e:{...e,parameters:{...e.parameters,error:`invalid_token`}})}function placeholderAuth(){return()=>{if(process.env.VERCEL_ENV!==`production`)return null;throw new UnauthenticatedError({code:`eve_production_auth_not_configured`,message:`Production auth is not configured. Replace placeholderAuth() in agent/channels/eve.ts with your app's auth provider.`})}}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return()=>isLocalDevelopmentServer()?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}function isLocalDevelopmentServer(){return process.env.VERCEL&&process.env.VERCEL_ENV===`development`?!0:isEveDevEnvironment()}const ANONYMOUS_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`none`,principalId:`anonymous`,principalType:`anonymous`},LOCAL_DEV_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`local-dev`,principalId:`local-dev`,principalType:`local-dev`};async function verifyVercelOidc(e,t={}){if(e===null||e.length===0)return{ok:!1};let n=decodeUnverifiedJwtClaims(e);if(n===null)return vercelOidcLog.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!isVercelOidcIssuer(n.issuer))return vercelOidcLog.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:n.issuer}),{ok:!1};if(n.audiences.length===0)return vercelOidcLog.debug(`Rejected token with no audience claim.`,{issuer:n.issuer}),{ok:!1};if(!n.audiences.some(e=>e.startsWith(`https://vercel.com/`)))return vercelOidcLog.debug(`Rejected token whose audience is not a Vercel audience.`,{audiences:n.audiences,issuer:n.issuer}),{ok:!1};let r=resolveCurrentVercelProject(t),i=await runOidcVerification(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,currentVercelProject:r,issuer:n.issuer,subjects:t.subjects??[]});return i.kind===`authenticated`?(vercelOidcLog.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:i.principal.principalType,subject:i.principal.subject}),{ok:!0,sessionAuth:createRuntimeSessionAuthContext(i.principal)}):(vercelOidcLog.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:i.kind,subjectsConfigured:(t.subjects??[]).length>0,...i.kind===`misconfigured`?{detail:i.message}:{}}),{ok:!1})}function resolveCurrentVercelProject(e){if(e.currentVercelProject!==void 0)return e.currentVercelProject;let t=process.env.VERCEL_PROJECT_ID?.trim();if(t===void 0||t.length===0)return;let n=process.env.VERCEL_TARGET_ENV?.trim()||process.env.VERCEL_ENV?.trim();return n===void 0||n.length===0?{projectId:t}:{environment:n,projectId:t}}function vercelSubject(e){assertVercelSubjectSegment(`teamSlug`,e.teamSlug),assertVercelSubjectSegment(`projectName`,e.projectName);let t=e.environment??`production`;if(t!==`production`&&t!==`preview`&&t!==`development`&&t!==`*`)throw Error(`vercelSubject: invalid environment ${JSON.stringify(t)}; expected "production", "preview", "development", or "*".`);return`owner:${e.teamSlug}:project:${e.projectName}:environment:${t}`}function assertVercelSubjectSegment(e,t){if(t.length===0)throw Error(`vercelSubject: ${e} must be a non-empty string.`);if(t.includes(`*`)||t.includes(`:`))throw Error(`vercelSubject: ${e} ${JSON.stringify(t)} may not contain ${t.includes(`:`)?`':'`:`'*'`}. Hand-write the subject string when wildcards are intentional.`)}function vercelOidc(e={}){return withAuthChallenges(async t=>{let n=extractBearerToken(t.headers.get(`authorization`)),r=e.currentVercelProject??(n!==null&&isLocalDevelopmentVercelOidc()?await resolveVercelOidcCurrentProject(t):void 0),i=await verifyVercelOidc(n,r===void 0?e:{...e,currentVercelProject:r});return i.ok?i.sessionAuth:null},[{scheme:`Bearer`}])}function isLocalDevelopmentVercelOidc(){return process.env.VERCEL_ENV===`development`?!0:process.env.VERCEL_ENV===`preview`||process.env.VERCEL_ENV===`production`?!1:isEveDevEnvironment()}function httpBasic(e,t){return withAuthChallenges(t=>{let n=verifyHttpBasic(t.headers.get(`authorization`),e);return n.ok?n.sessionAuth:null},[{parameters:{realm:t?.realm??`eve`,charset:`UTF-8`},scheme:`Basic`}])}function jwtHmac(e){return withAuthChallenges(async t=>{let n=await verifyJwtHmac(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function jwtEcdsa(e){return withAuthChallenges(async t=>{let n=await verifyJwtEcdsa(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function oidc(e){return withAuthChallenges(async t=>{let n=await verifyOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function decodeUnverifiedJwtClaims(e){let t;try{t=decodeJwt(e)}catch{return null}return typeof t.iss!=`string`||t.iss.length===0?null:{audiences:typeof t.aud==`string`?[t.aud]:Array.isArray(t.aud)?t.aud.filter(e=>typeof e==`string`):[],issuer:t.iss}}export{ForbiddenError,UnauthenticatedError,createIpAllowList,createUnauthorizedResponse,escapeAuthChallengeParameter,extractBearerToken,httpBasic,isIpAllowed,jwtEcdsa,jwtHmac,localDev,none,oauthResource,oidc,placeholderAuth,readOAuthResourceOptions,routeAuth,vercelOidc,vercelSubject,verifyHttpBasic,verifyJwtEcdsa,verifyJwtHmac,verifyOidc,verifyVercelOidc,withAuthChallenges};
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{decodeJwt}from"#compiled/jose/index.js";import{areTokenClaimMatchersSatisfied}from"#channel/auth/token-claims.js";import{isVercelOidcIssuer}from"#shared/vercel-project.js";import{isLoopbackHostname}from"#shared/network-address.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{resolveVercelOidcCurrentProject}from"#channel/auth/vercel-oidc-project.js";import{authenticateHttpBasicStrategy}from"#channel/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#channel/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#channel/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#channel/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#channel/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#channel/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let n=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n={algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-hmac`,secret:t.secret,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},r=await authenticateJwtHmacStrategy({strategy:n,token:e});return r.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(r.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n={algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-ecdsa`,publicKey:t.publicKey,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},r=await authenticateJwtEcdsaStrategy({strategy:n,token:e});return r.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(r.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1,currentVercelProject:void 0});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){if(e===null||e.length===0)return{kind:`not-authenticated`};let n={acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},r=t.currentVercelProject===void 0?n:{...n,currentVercelProject:t.currentVercelProject};return await authenticateOidcStrategy({strategy:r,token:e})}function extractBearerToken(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function createIpAllowList(e){return createRuntimeIpAllowList(e)}function isIpAllowed(e,t){return e!==null&&isRuntimeIpAllowed(e,t)}function createUnauthorizedResponse(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,formatChallenge(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function formatChallenge(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${escapeAuthChallengeParameter(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeAuthChallengeParameter(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}function isValidOAuthIdentifierUrl(e){try{let t=new URL(e);return(t.protocol===`https:`||t.protocol===`http:`&&isLoopbackHostname(t.hostname))&&t.username.length===0&&t.password.length===0&&t.search.length===0&&t.hash.length===0}catch{return!1}}function isValidMetadataPath(e){if(!e.startsWith(`/`)||e.startsWith(`//`))return!1;let t=new URL(e,`https://eve.invalid`);return t.origin===`https://eve.invalid`&&t.search.length===0&&t.hash.length===0}var UnauthenticatedError=class extends Error{response;constructor(e={}){super(e.message??`Authorization is required for this route.`),this.name=`UnauthenticatedError`,this.response=createUnauthorizedResponse({...e,status:401})}},ForbiddenError=class extends Error{response;constructor(e={}){super(e.message??`Forbidden.`),this.name=`ForbiddenError`,this.response=createUnauthorizedResponse({...e,status:403})}};const OAUTH_RESOURCE_SYMBOL=Symbol.for(`eve.channels.auth.oauthResource`);function oauthResource(e,t){let n=t.issuer===void 0?t.authorizationServers:[t.issuer];if(n.length===0||n.some(e=>!isValidOAuthIdentifierUrl(e)))throw Error(`oauthResource requires at least one HTTPS authorization server URL (HTTP is allowed only on loopback).`);if(t.resource!==void 0&&!isValidOAuthIdentifierUrl(t.resource))throw Error(`oauthResource resource must be an HTTPS URL without credentials, query, or fragment (HTTP is allowed only on loopback).`);if(t.metadataPath!==void 0&&!isValidMetadataPath(t.metadataPath))throw Error(`oauthResource metadataPath must be an absolute path without a host, query, or fragment.`);let r=Array.isArray(e)?e:[e],composed=async e=>{for(let t of r){let n=await t(e);if(n)return n}return null},i=collectDeclaredChallenges(r),a=withAuthChallenges(composed,i.length>0?i:[{scheme:`Bearer`}]);return Object.defineProperty(a,OAUTH_RESOURCE_SYMBOL,{enumerable:!1,value:t}),a}function readOAuthResourceOptions(e){if(!Array.isArray(e))return e[OAUTH_RESOURCE_SYMBOL]}const AUTH_CHALLENGES_SYMBOL=Symbol.for(`eve.channels.auth.challenges`);function withAuthChallenges(e,t){let wrapped=t=>e(t);return Object.defineProperty(wrapped,AUTH_CHALLENGES_SYMBOL,{value:t}),wrapped}function getDeclaredChallenges(e){return e[AUTH_CHALLENGES_SYMBOL]}function collectDeclaredChallenges(e){let t=new Set,n=[];for(let r of e)for(let e of getDeclaredChallenges(r)??[]){let r=formatChallenge(e);t.has(r)||(t.add(r),n.push(e))}return n}async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];try{for(let t of n){let n=await t(e);if(n)return n}}catch(e){if(typeof e==`object`&&e&&`response`in e&&e.response instanceof Response)return e.response;throw e}let r=collectDeclaredChallenges(n);return createUnauthorizedResponse({challenges:r.length>0?addInvalidBearerTokenError(e,r):[{scheme:`Bearer`}]})}function addInvalidBearerTokenError(e,t){let n=e.headers.get(`authorization`);return n===null||!/^Bearer(?:\s|$)/i.test(n.trim())||!t.some(e=>e.scheme===`Bearer`)?t:t.map(e=>e.scheme!==`Bearer`||e.parameters?.error!==void 0?e:{...e,parameters:{...e.parameters,error:`invalid_token`}})}function placeholderAuth(){return()=>{if(process.env.VERCEL_ENV!==`production`)return null;throw new UnauthenticatedError({code:`eve_production_auth_not_configured`,message:`Production auth is not configured. Replace placeholderAuth() in agent/channels/eve.ts with your app's auth provider.`})}}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return()=>isLocalDevelopmentServer()?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}function isLocalDevelopmentServer(){return process.env.VERCEL&&process.env.VERCEL_ENV===`development`?!0:isEveDevEnvironment()}const ANONYMOUS_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`none`,principalId:`anonymous`,principalType:`anonymous`},LOCAL_DEV_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`local-dev`,principalId:`local-dev`,principalType:`local-dev`};async function verifyVercelOidc(e,t={}){if(e===null||e.length===0)return{ok:!1};let n=decodeUnverifiedJwtClaims(e);if(n===null)return vercelOidcLog.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!isVercelOidcIssuer(n.issuer))return vercelOidcLog.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:n.issuer}),{ok:!1};if(n.audiences.length===0)return vercelOidcLog.debug(`Rejected token with no audience claim.`,{issuer:n.issuer}),{ok:!1};if(!n.audiences.some(e=>e.startsWith(`https://vercel.com/`)))return vercelOidcLog.debug(`Rejected token whose audience is not a Vercel audience.`,{audiences:n.audiences,issuer:n.issuer}),{ok:!1};let r=resolveCurrentVercelProject(t),i=await runOidcVerification(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,currentVercelProject:r,issuer:n.issuer,subjects:t.subjects??[]});return i.kind===`authenticated`?(vercelOidcLog.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:i.principal.principalType,subject:i.principal.subject}),{ok:!0,sessionAuth:createRuntimeSessionAuthContext(i.principal)}):(vercelOidcLog.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:i.kind,subjectsConfigured:(t.subjects??[]).length>0,...i.kind===`misconfigured`?{detail:i.message}:{}}),{ok:!1})}function resolveCurrentVercelProject(e){if(e.currentVercelProject!==void 0)return e.currentVercelProject;let t=process.env.VERCEL_PROJECT_ID?.trim();if(t===void 0||t.length===0)return;let n=process.env.VERCEL_TARGET_ENV?.trim()||process.env.VERCEL_ENV?.trim();return n===void 0||n.length===0?{projectId:t}:{environment:n,projectId:t}}function vercelSubject(e){assertVercelSubjectSegment(`teamSlug`,e.teamSlug),assertVercelSubjectSegment(`projectName`,e.projectName);let t=e.environment??`production`;if(t!==`production`&&t!==`preview`&&t!==`development`&&t!==`*`)throw Error(`vercelSubject: invalid environment ${JSON.stringify(t)}; expected "production", "preview", "development", or "*".`);return`owner:${e.teamSlug}:project:${e.projectName}:environment:${t}`}function assertVercelSubjectSegment(e,t){if(t.length===0)throw Error(`vercelSubject: ${e} must be a non-empty string.`);if(t.includes(`*`)||t.includes(`:`))throw Error(`vercelSubject: ${e} ${JSON.stringify(t)} may not contain ${t.includes(`:`)?`':'`:`'*'`}. Hand-write the subject string when wildcards are intentional.`)}function vercelOidc(e={}){let{subjects:t,...n}=e,r={...n,subjects:t?.map(e=>typeof e==`string`?e:e.subject)};return withAuthChallenges(async n=>{let i=extractBearerToken(n.headers.get(`authorization`)),a=e.currentVercelProject??(i!==null&&isLocalDevelopmentVercelOidc()?await resolveVercelOidcCurrentProject(n):void 0),o=await verifyVercelOidc(i,a===void 0?r:{...r,currentVercelProject:a});if(!o.ok)return null;let s=o.sessionAuth;return(s.principalType===`service`||s.principalType===`runtime`)&&t?.some(e=>typeof e!=`string`&&e.allowToolStubs===!0&&areTokenClaimMatchersSatisfied({sub:s.subject},{subjects:[e.subject]}))?{...s,allowToolStubs:!0}:s},[{scheme:`Bearer`}])}function isLocalDevelopmentVercelOidc(){return process.env.VERCEL_ENV===`development`?!0:process.env.VERCEL_ENV===`preview`||process.env.VERCEL_ENV===`production`?!1:isEveDevEnvironment()}function httpBasic(e,t){return withAuthChallenges(t=>{let n=verifyHttpBasic(t.headers.get(`authorization`),e);return n.ok?n.sessionAuth:null},[{parameters:{realm:t?.realm??`eve`,charset:`UTF-8`},scheme:`Basic`}])}function jwtHmac(e){return withAuthChallenges(async t=>{let n=await verifyJwtHmac(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function jwtEcdsa(e){return withAuthChallenges(async t=>{let n=await verifyJwtEcdsa(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function oidc(e){return withAuthChallenges(async t=>{let n=await verifyOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function decodeUnverifiedJwtClaims(e){let t;try{t=decodeJwt(e)}catch{return null}return typeof t.iss!=`string`||t.iss.length===0?null:{audiences:typeof t.aud==`string`?[t.aud]:Array.isArray(t.aud)?t.aud.filter(e=>typeof e==`string`):[],issuer:t.iss}}export{ForbiddenError,UnauthenticatedError,createIpAllowList,createUnauthorizedResponse,escapeAuthChallengeParameter,extractBearerToken,httpBasic,isIpAllowed,jwtEcdsa,jwtHmac,localDev,none,oauthResource,oidc,placeholderAuth,readOAuthResourceOptions,routeAuth,vercelOidc,vercelSubject,verifyHttpBasic,verifyJwtEcdsa,verifyJwtHmac,verifyOidc,verifyVercelOidc,withAuthChallenges};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";import{inputRequestSchema,inputResponseSchema}from"#shared/input.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{parseJsonObject}from"#shared/json.js";import{DELETE,GET,HEAD,OPTIONS,POST,defineChannel}from"#public/definitions/channel.js";import{readAgentInfoRouteResponse,readRouteChannelName,readRouteSessionCreator,readSkillFileSource}from"#internal/nitro/routes/channel-route-context.js";import{escapeAuthChallengeParameter,readOAuthResourceOptions,routeAuth}from"#public/channels/auth.js";import{McpToolOperationError,createMcpStreamableHttpServer,defineMcpTool}from"#internal/mcp/streamable-http-server.js";import{WorkflowAgentInvocationExecution}from"#internal/invocation/workflow-execution.js";import{MCP_TOOL_SESSIONS_EXTENSION,createPublishedTools}from"#internal/mcp/published-tools.js";import{resolveMcpRequestPrincipals}from"#internal/mcp/forwarded-principal-header.js";import{createMcpSkillsFeature}from"#internal/mcp/skills.js";import{validateMcpHttpRequest,validateMcpMetadataRequest}from"#internal/mcp/http-security.js";import{createMcpProtectedResourceMetadata,createMcpResourceChallenge}from"#internal/mcp/protected-resource.js";function mcpChannel(e){if(e?.auth===void 0)throw Error(`mcpChannel requires auth. Use none() for explicit public access.`);let t={agent:e.agent??!0,skills:e.skills??!1,tools:e.tools??!1};if(!t.agent&&!t.tools&&!t.skills)throw Error(`mcpChannel publishes nothing with agent, tools, and skills all false. Enable one.`);let n=e.route??`/eve/v1/mcp`,r=readOAuthResourceOptions(e.auth),handle=async(n,i)=>await authenticateMcpRequest(n,i,e,r,t),i=[GET(n,handle),POST(n,handle),DELETE(n,handle)];return r!==void 0&&i.unshift(...protectedResourceMetadataRoutes(r,n)),defineChannel({routes:i})}function protectedResourceMetadataRoutes(e,t){let n=protectedResourceMetadataPath(e,t);return[GET(n,async n=>protectedResourceMetadataResponse(n,e,t,!1)),HEAD(n,async n=>protectedResourceMetadataResponse(n,e,t,!0)),OPTIONS(n,async e=>protectedResourceMetadataOptionsResponse(e))]}function protectedResourceMetadataPath(e,t){if(e.metadataPath!==void 0)return e.metadataPath;let n=e.resource===void 0?t:new URL(e.resource).pathname;return n===`/`?`/.well-known/oauth-protected-resource`:`/.well-known/oauth-protected-resource${n}`}function protectedResourceMetadataResponse(e,t,n,r){let i=validateMcpMetadataRequest(e);if(i!==void 0)return i;let a=t.resource??new URL(n,new URL(e.url).origin).toString(),o=t.issuer===void 0?t.authorizationServers:[t.issuer],s=Response.json(createMcpProtectedResourceMetadata({authorizationServers:o,resource:a,scopesSupported:t.scopes}),{headers:{"access-control-allow-origin":`*`,"cache-control":`no-store`}});return r?new Response(null,{headers:s.headers,status:s.status}):s}function protectedResourceMetadataOptionsResponse(e){let t=validateMcpMetadataRequest(e);if(t!==void 0)return t;let n=new Headers({"access-control-allow-methods":`GET, HEAD, OPTIONS`,"access-control-allow-origin":`*`,"cache-control":`no-store`}),r=e.headers.get(`access-control-request-headers`);return r!==null&&(n.set(`access-control-allow-headers`,r),n.set(`vary`,`Access-Control-Request-Headers`)),new Response(null,{headers:n,status:204})}function addResourceChallenge(e,t,n){if(e.status!==401&&e.status!==403)return e;let r=protectedResourceMetadataPath(n,new URL(t.url).pathname),i=n.resource??new URL(t.url).origin,a=new URL(r,i).toString(),o=new Headers(e.headers),s=o.get(`www-authenticate`);if(e.status===401)o.set(`www-authenticate`,mergeMcpBearerChallenge(s,a,n.scopes));else{let t=augmentInsufficientScopeChallenge(s,a);if(t===void 0)return e;o.set(`www-authenticate`,t)}return new Response(e.body,{headers:o,status:e.status,statusText:e.statusText})}function mergeMcpBearerChallenge(e,t,n){let r=parseAuthChallenges(e),i=r.find(e=>e.scheme.toLowerCase()===`bearer`&&hasAuthParameter(e.value,`error`))??r.find(e=>e.scheme.toLowerCase()===`bearer`);return replaceBearerChallenges(r,i,i===void 0?createMcpResourceChallenge(t,n):augmentBearerChallenge(i.value,t,n))}function augmentInsufficientScopeChallenge(e,t){let n=parseAuthChallenges(e),r=n.find(e=>e.scheme.toLowerCase()===`bearer`&&hasAuthParameter(e.value,`error`,`insufficient_scope`));if(r!==void 0)return replaceBearerChallenges(n,r,augmentBearerChallenge(r.value,t))}function replaceBearerChallenges(e,t,n){let r=[],i=!1;for(let a of e){if(a.scheme.toLowerCase()!==`bearer`){r.push(a.value);continue}!i&&a===t&&(r.push(n),i=!0)}return i||r.push(n),r.join(`, `)}function augmentBearerChallenge(e,t,n){let r=e;return hasAuthParameter(r,`resource_metadata`)||(r=appendAuthParameter(r,`resource_metadata`,t)),n?.length&&!hasAuthParameter(r,`scope`)&&(r=appendAuthParameter(r,`scope`,n.join(` `))),r}function appendAuthParameter(e,t,n){return`${e}${e.trim().toLowerCase()===`bearer`?` `:`, `}${t}="${escapeAuthChallengeParameter(n)}"`}function hasAuthParameter(e,t,n){let r=t.replaceAll(/[.*+?^${}()|[\]\\]/g,`\\$&`);if(n===void 0)return RegExp(`(?:^|[\\s,])${r}\\s*=`,`i`).test(e);let i=n.replaceAll(/[.*+?^${}()|[\]\\]/g,`\\$&`);return RegExp(`(?:^|[\\s,])${r}\\s*=\\s*(?:"${i}"|${i})(?=$|[\\s,])`,`i`).test(e)}function parseAuthChallenges(e){if(e===null)return[];let t=[];for(let n of splitQuotedHeaderList(e)){let e=readChallengeScheme(n);if(e!==void 0){t.push({scheme:e,value:n});continue}let r=t.at(-1);r!==void 0&&(r.value+=`, ${n}`)}return t}function splitQuotedHeaderList(e){let t=[],n=!1,r=!1,i=0;for(let a=0;a<e.length;a++){let o=e[a];if(n)n=!1;else if(o===`\\`)n=!0;else if(o===`"`)r=!r;else if(o===`,`&&!r){let n=e.slice(i,a).trim();n.length>0&&t.push(n),i=a+1}}let a=e.slice(i).trim();return a.length>0&&t.push(a),t}function readChallengeScheme(e){let t=/^([!#$%&'*+\-.^_`|~0-9A-Za-z]+)(?:\s+|$)/.exec(e);if(t===null)return;let n=t[1];if(n!==void 0)return e.slice(n.length).trimStart().startsWith(`=`)?void 0:n}async function authenticateMcpRequest(e,t,n,r,i){let a=validateMcpHttpRequest(e);if(a!==void 0)return a;let o=await routeAuth(e,n.auth);if(o instanceof Response)return r===void 0?o:addResourceChallenge(o,e,r);let s=await resolveMcpRequestPrincipals(e,o,n.trustedForwarders);return s instanceof Response?s:await handleMcpRequest(e,t,o,s,i)}async function handleMcpRequest(e,t,n,r,i){let a=readRouteSessionCreator(t),o=readRouteChannelName(t),s=readAgentInfoRouteResponse(t);if(o===void 0||a===void 0||s===void 0)return Response.json({error:`MCP requires agent route context.`},{status:500});let c=await s();if(!c.ok)return c;let l=await c.json();if(typeof l.agent?.name!=`string`)return Response.json({error:`MCP requires compiled agent metadata.`},{status:500});let u=typeof l.agent.description==`string`?l.agent.description:void 0,d=new WorkflowAgentInvocationExecution({createSession:a,from:t.from}),f=i.agent?createInvocationTools(d,u,n.authenticator===`none`&&n.principalType===`anonymous`):[],p=i.tools||i.skills?await t.describe():void 0,m=i.tools&&p!==void 0?createPublishedTools({invokeTool:t.invokeTool,principals:r,reserved:new Set(f.map(e=>e.name)),tools:p.tools}):[],h=[];if(i.tools&&h.push({capabilities:{extensions:{[MCP_TOOL_SESSIONS_EXTENSION]:{}}},register(){}}),i.skills&&p!==void 0){let e=readSkillFileSource(t);if(e===void 0)return Response.json({error:`MCP requires agent route context.`},{status:500});h.push(createMcpSkillsFeature({files:e,skills:p.skills}))}return await createMcpStreamableHttpServer({authenticate:async()=>n,features:h,instructions:i.agent?MCP_SERVER_INSTRUCTIONS:void 0,name:l.agent.name,tools:i.agent||i.tools?[...f,...m]:void 0,version:resolveInstalledPackageInfo().version})(e)}const MCP_SERVER_INSTRUCTIONS=[`Each invocation is one durable agent task.`,`Call agent_start once per task and keep the returned invocationId.`,`Poll agent_get, waiting at least pollAfterMs between calls, until status is completed, failed, or cancelled.`,`If status is input_required, answer every entry in inputRequests in one agent_update call; repeating accepted answers is safe.`,`If status is authorization_required, show the user the authorization url or instructions and keep polling.`,`isError on a tool result means your call was rejected; a failed status means the task failed.`,`agent_start is not idempotent and a lost response leaves no invocationId, so ask the user before starting again.`,`Work continues after your connection drops; agent_cancel stops it, then poll until any terminal status.`].join(` `);function createInvocationTools(e,t,n){let r=n?` On this public channel, the invocation ID is a bearer capability until workflow retention expires.`:``,i=`Starts durable work and returns an invocation handle immediately. Call once per task; keep invocationId and poll agent_get. Not idempotent: if the response is lost, ask the user before starting again rather than retrying.${r}`;return[defineMcpTool({definition:{annotations:{destructiveHint:!0,idempotentHint:!1,openWorldHint:!0,readOnlyHint:!1},description:t===void 0?i:`${t} ${i}`,inputSchema:z.strictObject({message:utf8Bounded(MAX_MESSAGE_BYTES).min(1)}),name:`agent_start`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(t,n){return invocationResult(await e.create({auth:n.auth,message:t.message}))}}),defineMcpTool({definition:{annotations:{destructiveHint:!1,idempotentHint:!0,openWorldHint:!1,readOnlyHint:!0},description:`Reads complete durable invocation state. Wait at least pollAfterMs between calls. Terminal statuses are completed, failed, and cancelled. input_required needs agent_update; authorization_required needs the user to follow the returned authorization.${r}`,inputSchema:z.strictObject({invocationId:z.string().min(1).max(MAX_ID_CHARS)}),name:`agent_get`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(t,n){return invocationResult(requiredInvocation(await e.read({auth:n.auth,invocationId:t.invocationId})))}}),defineMcpTool({definition:{annotations:{destructiveHint:!0,idempotentHint:!1,openWorldHint:!0,readOnlyHint:!1},description:`Answers the pending input batch on an input_required invocation. Include one response per entry in inputRequests, each keyed by its requestId, in a single call; partial batches are rejected. Returns the current invocation state; repeating the same accepted answers is safe.`,inputSchema:z.strictObject({invocationId:z.string().min(1).max(MAX_ID_CHARS),responses:z.array(MCP_INPUT_RESPONSE_SCHEMA).min(1).max(MAX_RESPONSES_PER_UPDATE)}),name:`agent_update`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(t,n){return invocationResult(requiredMutation(await e.update({auth:n.auth,invocationId:t.invocationId,responses:t.responses})))}}),defineMcpTool({definition:{annotations:{destructiveHint:!0,idempotentHint:!0,openWorldHint:!1,readOnlyHint:!1},description:`Requests cooperative cancellation of a non-terminal invocation. Cancellation is asynchronous and can race with completion: poll agent_get until status is terminal (cancelled, completed, or failed). Safe to call repeatedly.`,inputSchema:z.strictObject({invocationId:z.string().min(1).max(MAX_ID_CHARS)}),name:`agent_cancel`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(t,n){return invocationResult(requiredInvocation(await e.cancel({auth:n.auth,invocationId:t.invocationId})))}})]}const INVOCATION_NOT_FOUND=`Invocation not found. It may have expired or belong to another caller.`;function requiredInvocation(e){if(e===void 0)throw new McpToolOperationError(`not_found`,INVOCATION_NOT_FOUND);return e}function requiredMutation(e){switch(e.type){case`success`:return e.invocation;case`conflict`:throw new McpToolOperationError(`conflict`,`${e.message} Call agent_get to read the current state before answering again.`);case`not_found`:throw new McpToolOperationError(`not_found`,INVOCATION_NOT_FOUND)}}function invocationResult(e){let t=parseJsonObject(e);return{content:[{text:JSON.stringify(t),type:`text`}],structuredContent:t}}const AUTHORIZATION_CHALLENGE_SCHEMA=z.strictObject({displayName:z.string().optional(),expiresAt:z.iso.datetime().optional(),instructions:z.string().optional(),url:z.url().optional(),userCode:z.string().optional()}),AUTHORIZATION_REQUEST_SCHEMA=z.strictObject({authorization:AUTHORIZATION_CHALLENGE_SCHEMA.optional(),description:z.string(),name:z.string(),webhookUrl:z.url().optional()}),MAX_MESSAGE_BYTES=65536,MAX_ID_CHARS=256,MAX_RESPONSES_PER_UPDATE=64;function utf8Bounded(e){let t=new TextEncoder;return z.string().refine(n=>t.encode(n).byteLength<=e,{message:`must be at most ${String(e)} bytes when UTF-8 encoded`})}const MCP_INPUT_RESPONSE_SCHEMA=inputResponseSchema.safeExtend({optionId:z.string().max(256).optional(),requestId:z.string().min(1).max(256),text:utf8Bounded(16384).optional()}),MCP_INPUT_REQUEST_SCHEMA=inputRequestSchema.safeExtend({action:z.strictObject({callId:z.string(),input:z.record(z.string(),z.json()),kind:z.literal(`tool-call`),toolName:z.string()})}),AGENT_INVOCATION_BASE_SCHEMA=z.strictObject({createdAt:z.iso.datetime(),expiresAt:z.iso.datetime().optional(),invocationId:z.string()}),AGENT_INVOCATION_OUTPUT_SCHEMA=z.discriminatedUnion(`status`,[AGENT_INVOCATION_BASE_SCHEMA.extend({pollAfterMs:z.number().int().nonnegative(),result:z.json().optional(),status:z.literal(`working`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({inputRequests:z.record(z.string(),MCP_INPUT_REQUEST_SCHEMA),result:z.json().optional(),status:z.literal(`input_required`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({authorizations:z.array(AUTHORIZATION_REQUEST_SCHEMA).min(1),pollAfterMs:z.number().int().nonnegative(),result:z.json().optional(),status:z.literal(`authorization_required`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({result:z.json().optional(),status:z.literal(`completed`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({error:z.strictObject({code:z.number().int(),data:z.json().optional(),message:z.string()}),status:z.literal(`failed`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({status:z.literal(`cancelled`)})]);export{mcpChannel};
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{inputRequestSchema,inputResponseSchema}from"#shared/input.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{parseJsonObject}from"#shared/json.js";import{DELETE,GET,HEAD,OPTIONS,POST,defineChannel}from"#public/definitions/channel.js";import{readAgentInfoRouteResponse,readRouteChannelName,readRouteSessionCreator,readSkillFileSource}from"#internal/nitro/routes/channel-route-context.js";import{sessionAuthFromResult}from"#channel/auth/result.js";import{escapeAuthChallengeParameter,readOAuthResourceOptions,routeAuth}from"#public/channels/auth.js";import{McpToolOperationError,createMcpStreamableHttpServer,defineMcpTool}from"#internal/mcp/streamable-http-server.js";import{WorkflowAgentInvocationExecution}from"#internal/invocation/workflow-execution.js";import{MCP_TOOL_SESSIONS_EXTENSION,createPublishedTools}from"#internal/mcp/published-tools.js";import{resolveMcpRequestPrincipals}from"#internal/mcp/forwarded-principal-header.js";import{createMcpSkillsFeature}from"#internal/mcp/skills.js";import{validateMcpHttpRequest,validateMcpMetadataRequest}from"#internal/mcp/http-security.js";import{createMcpProtectedResourceMetadata,createMcpResourceChallenge}from"#internal/mcp/protected-resource.js";function mcpChannel(e){if(e?.auth===void 0)throw Error(`mcpChannel requires auth. Use none() for explicit public access.`);let t={agent:e.agent??!0,skills:e.skills??!1,tools:e.tools??!1};if(!t.agent&&!t.tools&&!t.skills)throw Error(`mcpChannel publishes nothing with agent, tools, and skills all false. Enable one.`);let n=e.route??`/eve/v1/mcp`,r=readOAuthResourceOptions(e.auth),handle=async(n,i)=>await authenticateMcpRequest(n,i,e,r,t),i=[GET(n,handle),POST(n,handle),DELETE(n,handle)];return r!==void 0&&i.unshift(...protectedResourceMetadataRoutes(r,n)),defineChannel({routes:i})}function protectedResourceMetadataRoutes(e,t){let n=protectedResourceMetadataPath(e,t);return[GET(n,async n=>protectedResourceMetadataResponse(n,e,t,!1)),HEAD(n,async n=>protectedResourceMetadataResponse(n,e,t,!0)),OPTIONS(n,async e=>protectedResourceMetadataOptionsResponse(e))]}function protectedResourceMetadataPath(e,t){if(e.metadataPath!==void 0)return e.metadataPath;let n=e.resource===void 0?t:new URL(e.resource).pathname;return n===`/`?`/.well-known/oauth-protected-resource`:`/.well-known/oauth-protected-resource${n}`}function protectedResourceMetadataResponse(e,t,n,r){let i=validateMcpMetadataRequest(e);if(i!==void 0)return i;let a=t.resource??new URL(n,new URL(e.url).origin).toString(),o=t.issuer===void 0?t.authorizationServers:[t.issuer],s=Response.json(createMcpProtectedResourceMetadata({authorizationServers:o,resource:a,scopesSupported:t.scopes}),{headers:{"access-control-allow-origin":`*`,"cache-control":`no-store`}});return r?new Response(null,{headers:s.headers,status:s.status}):s}function protectedResourceMetadataOptionsResponse(e){let t=validateMcpMetadataRequest(e);if(t!==void 0)return t;let n=new Headers({"access-control-allow-methods":`GET, HEAD, OPTIONS`,"access-control-allow-origin":`*`,"cache-control":`no-store`}),r=e.headers.get(`access-control-request-headers`);return r!==null&&(n.set(`access-control-allow-headers`,r),n.set(`vary`,`Access-Control-Request-Headers`)),new Response(null,{headers:n,status:204})}function addResourceChallenge(e,t,n){if(e.status!==401&&e.status!==403)return e;let r=protectedResourceMetadataPath(n,new URL(t.url).pathname),i=n.resource??new URL(t.url).origin,a=new URL(r,i).toString(),o=new Headers(e.headers),s=o.get(`www-authenticate`);if(e.status===401)o.set(`www-authenticate`,mergeMcpBearerChallenge(s,a,n.scopes));else{let t=augmentInsufficientScopeChallenge(s,a);if(t===void 0)return e;o.set(`www-authenticate`,t)}return new Response(e.body,{headers:o,status:e.status,statusText:e.statusText})}function mergeMcpBearerChallenge(e,t,n){let r=parseAuthChallenges(e),i=r.find(e=>e.scheme.toLowerCase()===`bearer`&&hasAuthParameter(e.value,`error`))??r.find(e=>e.scheme.toLowerCase()===`bearer`);return replaceBearerChallenges(r,i,i===void 0?createMcpResourceChallenge(t,n):augmentBearerChallenge(i.value,t,n))}function augmentInsufficientScopeChallenge(e,t){let n=parseAuthChallenges(e),r=n.find(e=>e.scheme.toLowerCase()===`bearer`&&hasAuthParameter(e.value,`error`,`insufficient_scope`));if(r!==void 0)return replaceBearerChallenges(n,r,augmentBearerChallenge(r.value,t))}function replaceBearerChallenges(e,t,n){let r=[],i=!1;for(let a of e){if(a.scheme.toLowerCase()!==`bearer`){r.push(a.value);continue}!i&&a===t&&(r.push(n),i=!0)}return i||r.push(n),r.join(`, `)}function augmentBearerChallenge(e,t,n){let r=e;return hasAuthParameter(r,`resource_metadata`)||(r=appendAuthParameter(r,`resource_metadata`,t)),n?.length&&!hasAuthParameter(r,`scope`)&&(r=appendAuthParameter(r,`scope`,n.join(` `))),r}function appendAuthParameter(e,t,n){return`${e}${e.trim().toLowerCase()===`bearer`?` `:`, `}${t}="${escapeAuthChallengeParameter(n)}"`}function hasAuthParameter(e,t,n){let r=t.replaceAll(/[.*+?^${}()|[\]\\]/g,`\\$&`);if(n===void 0)return RegExp(`(?:^|[\\s,])${r}\\s*=`,`i`).test(e);let i=n.replaceAll(/[.*+?^${}()|[\]\\]/g,`\\$&`);return RegExp(`(?:^|[\\s,])${r}\\s*=\\s*(?:"${i}"|${i})(?=$|[\\s,])`,`i`).test(e)}function parseAuthChallenges(e){if(e===null)return[];let t=[];for(let n of splitQuotedHeaderList(e)){let e=readChallengeScheme(n);if(e!==void 0){t.push({scheme:e,value:n});continue}let r=t.at(-1);r!==void 0&&(r.value+=`, ${n}`)}return t}function splitQuotedHeaderList(e){let t=[],n=!1,r=!1,i=0;for(let a=0;a<e.length;a++){let o=e[a];if(n)n=!1;else if(o===`\\`)n=!0;else if(o===`"`)r=!r;else if(o===`,`&&!r){let n=e.slice(i,a).trim();n.length>0&&t.push(n),i=a+1}}let a=e.slice(i).trim();return a.length>0&&t.push(a),t}function readChallengeScheme(e){let t=/^([!#$%&'*+\-.^_`|~0-9A-Za-z]+)(?:\s+|$)/.exec(e);if(t===null)return;let n=t[1];if(n!==void 0)return e.slice(n.length).trimStart().startsWith(`=`)?void 0:n}async function authenticateMcpRequest(e,t,n,r,i){let a=validateMcpHttpRequest(e);if(a!==void 0)return a;let o=await routeAuth(e,n.auth);if(o instanceof Response)return r===void 0?o:addResourceChallenge(o,e,r);let s=sessionAuthFromResult(o),c=await resolveMcpRequestPrincipals(e,s,n.trustedForwarders);return c instanceof Response?c:await handleMcpRequest(e,t,s,c,i)}async function handleMcpRequest(e,t,n,r,i){let a=readRouteSessionCreator(t),o=readRouteChannelName(t),s=readAgentInfoRouteResponse(t);if(o===void 0||a===void 0||s===void 0)return Response.json({error:`MCP requires agent route context.`},{status:500});let c=await s();if(!c.ok)return c;let l=await c.json();if(typeof l.agent?.name!=`string`)return Response.json({error:`MCP requires compiled agent metadata.`},{status:500});let u=typeof l.agent.description==`string`?l.agent.description:void 0,d=new WorkflowAgentInvocationExecution({createSession:a,from:t.from}),f=i.agent?createInvocationTools(d,u,n.authenticator===`none`&&n.principalType===`anonymous`):[],p=i.tools||i.skills?await t.describe():void 0,m=i.tools&&p!==void 0?createPublishedTools({invokeTool:t.invokeTool,principals:r,reserved:new Set(f.map(e=>e.name)),tools:p.tools}):[],h=[];if(i.tools&&h.push({capabilities:{extensions:{[MCP_TOOL_SESSIONS_EXTENSION]:{}}},register(){}}),i.skills&&p!==void 0){let e=readSkillFileSource(t);if(e===void 0)return Response.json({error:`MCP requires agent route context.`},{status:500});h.push(createMcpSkillsFeature({files:e,skills:p.skills}))}return await createMcpStreamableHttpServer({authenticate:async()=>n,features:h,instructions:i.agent?MCP_SERVER_INSTRUCTIONS:void 0,name:l.agent.name,tools:i.agent||i.tools?[...f,...m]:void 0,version:resolveInstalledPackageInfo().version})(e)}const MCP_SERVER_INSTRUCTIONS=[`Each invocation is one durable agent task.`,`Call agent_start once per task and keep the returned invocationId.`,`Poll agent_get, waiting at least pollAfterMs between calls, until status is completed, failed, or cancelled.`,`If status is input_required, answer every entry in inputRequests in one agent_update call; repeating accepted answers is safe.`,`If status is authorization_required, show the user the authorization url or instructions and keep polling.`,`isError on a tool result means your call was rejected; a failed status means the task failed.`,`agent_start is not idempotent and a lost response leaves no invocationId, so ask the user before starting again.`,`Work continues after your connection drops; agent_cancel stops it, then poll until any terminal status.`].join(` `);function createInvocationTools(e,t,n){let r=n?` On this public channel, the invocation ID is a bearer capability until workflow retention expires.`:``,i=`Starts durable work and returns an invocation handle immediately. Call once per task; keep invocationId and poll agent_get. Not idempotent: if the response is lost, ask the user before starting again rather than retrying.${r}`;return[defineMcpTool({definition:{annotations:{destructiveHint:!0,idempotentHint:!1,openWorldHint:!0,readOnlyHint:!1},description:t===void 0?i:`${t} ${i}`,inputSchema:z.strictObject({message:utf8Bounded(MAX_MESSAGE_BYTES).min(1)}),name:`agent_start`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(t,n){return invocationResult(await e.create({auth:n.auth,message:t.message}))}}),defineMcpTool({definition:{annotations:{destructiveHint:!1,idempotentHint:!0,openWorldHint:!1,readOnlyHint:!0},description:`Reads complete durable invocation state. Wait at least pollAfterMs between calls. Terminal statuses are completed, failed, and cancelled. input_required needs agent_update; authorization_required needs the user to follow the returned authorization.${r}`,inputSchema:z.strictObject({invocationId:z.string().min(1).max(MAX_ID_CHARS)}),name:`agent_get`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(t,n){return invocationResult(requiredInvocation(await e.read({auth:n.auth,invocationId:t.invocationId})))}}),defineMcpTool({definition:{annotations:{destructiveHint:!0,idempotentHint:!1,openWorldHint:!0,readOnlyHint:!1},description:`Answers the pending input batch on an input_required invocation. Include one response per entry in inputRequests, each keyed by its requestId, in a single call; partial batches are rejected. Returns the current invocation state; repeating the same accepted answers is safe.`,inputSchema:z.strictObject({invocationId:z.string().min(1).max(MAX_ID_CHARS),responses:z.array(MCP_INPUT_RESPONSE_SCHEMA).min(1).max(MAX_RESPONSES_PER_UPDATE)}),name:`agent_update`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(t,n){return invocationResult(requiredMutation(await e.update({auth:n.auth,invocationId:t.invocationId,responses:t.responses})))}}),defineMcpTool({definition:{annotations:{destructiveHint:!0,idempotentHint:!0,openWorldHint:!1,readOnlyHint:!1},description:`Requests cooperative cancellation of a non-terminal invocation. Cancellation is asynchronous and can race with completion: poll agent_get until status is terminal (cancelled, completed, or failed). Safe to call repeatedly.`,inputSchema:z.strictObject({invocationId:z.string().min(1).max(MAX_ID_CHARS)}),name:`agent_cancel`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(t,n){return invocationResult(requiredInvocation(await e.cancel({auth:n.auth,invocationId:t.invocationId})))}})]}const INVOCATION_NOT_FOUND=`Invocation not found. It may have expired or belong to another caller.`;function requiredInvocation(e){if(e===void 0)throw new McpToolOperationError(`not_found`,INVOCATION_NOT_FOUND);return e}function requiredMutation(e){switch(e.type){case`success`:return e.invocation;case`conflict`:throw new McpToolOperationError(`conflict`,`${e.message} Call agent_get to read the current state before answering again.`);case`not_found`:throw new McpToolOperationError(`not_found`,INVOCATION_NOT_FOUND)}}function invocationResult(e){let t=parseJsonObject(e);return{content:[{text:JSON.stringify(t),type:`text`}],structuredContent:t}}const AUTHORIZATION_CHALLENGE_SCHEMA=z.strictObject({displayName:z.string().optional(),expiresAt:z.iso.datetime().optional(),instructions:z.string().optional(),url:z.url().optional(),userCode:z.string().optional()}),AUTHORIZATION_REQUEST_SCHEMA=z.strictObject({authorization:AUTHORIZATION_CHALLENGE_SCHEMA.optional(),description:z.string(),name:z.string(),webhookUrl:z.url().optional()}),MAX_MESSAGE_BYTES=65536,MAX_ID_CHARS=256,MAX_RESPONSES_PER_UPDATE=64;function utf8Bounded(e){let t=new TextEncoder;return z.string().refine(n=>t.encode(n).byteLength<=e,{message:`must be at most ${String(e)} bytes when UTF-8 encoded`})}const MCP_INPUT_RESPONSE_SCHEMA=inputResponseSchema.safeExtend({optionId:z.string().max(256).optional(),requestId:z.string().min(1).max(256),text:utf8Bounded(16384).optional()}),MCP_INPUT_REQUEST_SCHEMA=inputRequestSchema.safeExtend({action:z.strictObject({callId:z.string(),input:z.record(z.string(),z.json()),kind:z.literal(`tool-call`),toolName:z.string()})}),AGENT_INVOCATION_BASE_SCHEMA=z.strictObject({createdAt:z.iso.datetime(),expiresAt:z.iso.datetime().optional(),invocationId:z.string()}),AGENT_INVOCATION_OUTPUT_SCHEMA=z.discriminatedUnion(`status`,[AGENT_INVOCATION_BASE_SCHEMA.extend({pollAfterMs:z.number().int().nonnegative(),result:z.json().optional(),status:z.literal(`working`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({inputRequests:z.record(z.string(),MCP_INPUT_REQUEST_SCHEMA),result:z.json().optional(),status:z.literal(`input_required`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({authorizations:z.array(AUTHORIZATION_REQUEST_SCHEMA).min(1),pollAfterMs:z.number().int().nonnegative(),result:z.json().optional(),status:z.literal(`authorization_required`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({result:z.json().optional(),status:z.literal(`completed`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({error:z.strictObject({code:z.number().int(),data:z.json().optional(),message:z.string()}),status:z.literal(`failed`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({status:z.literal(`cancelled`)})]);export{mcpChannel};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash,randomUUID}from"node:crypto";function inMemoryScheduleProvider(e={}){let t=new Map,n=new Map,r=new Map,i=new Set,a=new Set,o=e.now??(()=>new Date);return{kind:`in-memory`,async create(e,a){return withOperationResult(n,e.operationId,()=>{let n=scheduleKey(e,a.name);if(t.has(n))throw Error(`Schedule ${JSON.stringify(a.name)} already exists.`);let s=o().getTime(),c={createdAt:s,expression:normalizeExpression(a.expression),payload:a.payload,name:a.name,scheduleId:allocateScheduleId(e,a.name,r,i),state:a.expression.type===`single`&&Date.parse(a.expression.at)<=s?`completed
|
|
1
|
+
import{createHash,randomUUID}from"node:crypto";function inMemoryScheduleProvider(e={}){let t=new Map,n=new Map,r=new Map,i=new Set,a=new Set,o=e.now??(()=>new Date);return{kind:`in-memory`,async create(e,a){return withOperationResult(n,e.operationId,()=>{let n=scheduleKey(e,a.name);if(t.has(n))throw Error(`Schedule ${JSON.stringify(a.name)} already exists.`);let s=o().getTime(),c={createdAt:s,expression:normalizeExpression(a.expression),payload:a.payload,name:a.name,scheduleId:allocateScheduleId(e,a.name,r,i),state:a.expression.type===`single`&&Date.parse(a.expression.at)<=s?`completed`:`active`,target:e.target,updatedAt:s};return t.set(n,c),publicRecord(c)})},async list(e,n){let r=[...t.entries()].filter(([t])=>t.startsWith(collectionPrefix(e))).map(([,e])=>publicRecord(e)).sort((e,t)=>e.name.localeCompare(t.name)),i=decodeCursor(n.cursor),a=normalizeLimit(n.limit),o=r.slice(i,i+a),s=i+o.length;return{cursor:s<r.length?String(s):null,data:o}},async get(e,n){let r=t.get(scheduleKey(e,n));return r===void 0?null:publicRecord(r)},async enable(e,r){return setState(t,n,e,r,`active`,o)},async disable(e,r){return setState(t,n,e,r,`inactive`,o)},async invoke(e,r){let i=n.get(e.operationId);if(i!==void 0){e.target.deliver!==void 0&&await e.target.deliver(i);return}let s=requireSchedule(t,scheduleKey(e,r),r);if(s.state===`completed`)throw Error(`Completed schedule ${JSON.stringify(r)} cannot be invoked.`);let c=o().toISOString(),l={payload:s.payload,occurrence:{executionId:allocateOccurrenceId(e.operationId,a),name:s.name,scheduleId:s.scheduleId,scheduledAt:c}};n.set(e.operationId,l),s.target.deliver!==void 0&&await s.target.deliver(l)},async delete(e,i){return withOperationResult(n,e.operationId,()=>{let n=scheduleKey(e,i),a=t.delete(n);return a&&r.delete(n),a})}}}async function setState(e,t,n,r,i,a){return withOperationResult(t,n.operationId,()=>{let t=scheduleKey(n,r),o={...requireSchedule(e,t,r),state:i,updatedAt:a().getTime()};return e.set(t,o),publicRecord(o)})}function requireSchedule(e,t,n){let r=e.get(t);if(r===void 0)throw Error(`Schedule ${JSON.stringify(n)} was not found.`);return r}function withOperationResult(e,t,n){if(e.has(t))return e.get(t);let r=n();return e.set(t,r),r}function allocateOccurrenceId(e,t){let n=`manual_${createHash(`sha256`).update(e).digest(`base64url`)}`,r=n,i=0;for(;t.has(r);)r=`${n}_${++i}`;return t.add(r),r}function normalizeExpression(e){if(e.type===`cron`){let t={type:`cron`,cron:e.cron.trim().replace(/\s+/gu,` `)};return e.timezone!==void 0&&(t.timezone=e.timezone),e.jitter!==void 0&&(t.jitter=e.jitter),t}let t={type:`single`,at:e.at};return e.timezone!==void 0&&(t.timezone=e.timezone),t}function publicRecord(e){return{createdAt:e.createdAt,expression:e.expression,name:e.name,scheduleId:e.scheduleId,state:e.state,updatedAt:e.updatedAt}}function collectionPrefix(e){return`${e.collection}\0${e.namespace}\0`}function scheduleKey(e,t){return`${collectionPrefix(e)}${t}`}function allocateScheduleId(e,t,n,r){let i=scheduleKey(e,t),a=n.get(i);if(a!==void 0)return a;let o;do o=`mem_${createHash(`sha256`).update(`${i}:${randomUUID()}`).digest(`hex`)}`;while(r.has(o));return n.set(i,o),r.add(o),o}function normalizeLimit(e){if(e===void 0)return 20;if(!Number.isSafeInteger(e)||e<1||e>100)throw Error(`Schedule list limit must be an integer from 1 through 100.`);return e}function decodeCursor(e){if(e===void 0)return 0;let t=Number(e);if(!Number.isSafeInteger(t)||t<0)throw Error(`Invalid schedule cursor.`);return t}export{inMemoryScheduleProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{deriveEveScheduleQueueTopic}from"#runtime/schedules/queue-namespace.js";import{inMemoryScheduleProvider}from"#public/schedules/providers/in-memory.js";const DEVELOPMENT_PROVIDER=inMemoryScheduleProvider(),CLIENT_OPTIONS=new WeakMap;function readVercelScheduleClientOptions(e){return CLIENT_OPTIONS.get(e)}function vercelScheduleProvider(e={}){if(isEveDevEnvironment())return DEVELOPMENT_PROVIDER;let client=t=>createClient(e,t),t={kind:`vercel`,async create(e,t){
|
|
1
|
+
import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{deriveEveScheduleQueueTopic}from"#runtime/schedules/queue-namespace.js";import{inMemoryScheduleProvider}from"#public/schedules/providers/in-memory.js";const DEVELOPMENT_PROVIDER=inMemoryScheduleProvider(),CLIENT_OPTIONS=new WeakMap;function readVercelScheduleClientOptions(e){return CLIENT_OPTIONS.get(e)}function vercelScheduleProvider(e={}){if(isEveDevEnvironment())return DEVELOPMENT_PROVIDER;let client=t=>createClient(e,t),t={kind:`vercel`,async create(e,t){return fromVercelSchedule(await(await client(e.abortSignal)).create({expression:toVercelExpression(t.expression),jitter:t.expression.type===`cron`?t.expression.jitter:void 0,name:t.name,namespace:e.namespace,payload:createDispatchPayload(e,t.payload),target:{topic:deriveEveScheduleQueueTopic(e.target.key)},timezone:t.expression.timezone}))},async list(e,t){let n=t.cursor?.trim()||void 0,r={namespace:e.namespace};n!==void 0&&(r.cursor=n),t.limit!==void 0&&(r.limit=t.limit);let i=await(await client(e.abortSignal)).list(r);return{cursor:i.cursor,data:i.data.map(fromVercelSchedule)}},async get(e,t){let n=await getScheduleOrNull(await client(e.abortSignal),t,e.namespace);return n===null?null:fromVercelSchedule(n)},async enable(e,t){return fromVercelSchedule(await(await client(e.abortSignal)).enable({name:t,namespace:e.namespace}))},async disable(e,t){return fromVercelSchedule(await(await client(e.abortSignal)).disable({name:t,namespace:e.namespace}))},async invoke(e,t){await(await client(e.abortSignal)).invoke({name:t,namespace:e.namespace})},async delete(e,t){try{return await(await client(e.abortSignal)).delete({name:t,namespace:e.namespace}),!0}catch(e){if(isNotFoundError(e))return!1;throw e}}};return CLIENT_OPTIONS.set(t,e),t}async function createClient(e,t){assertSupportedVercelEnvironment();let{SchedulesClient:n}=await import(`#compiled/@vercel/schedules/index.js`);t.throwIfAborted();let r=e.fetch??fetch;return new n({...e,fetch:(e,n)=>r(e,{...n,signal:t})})}function createDispatchPayload(e,t){return{eve:{application:e.target.key,collection:e.collection,version:1},payload:t}}function toVercelExpression(e){return e.type===`cron`?{type:`cron`,cron:e.cron}:{type:`single`,at:e.at}}function fromVercelSchedule(e){let t;if(e.expression.type===`cron`){let n={type:`cron`,cron:e.expression.cron,timezone:e.timezone};e.jitter!==void 0&&(n.jitter=e.jitter),t=n}else t={type:`single`,at:e.expression.at,timezone:e.timezone};return{createdAt:e.createdAt,expression:t,name:e.name,scheduleId:e.scheduleId,state:e.state,updatedAt:e.updatedAt}}async function getScheduleOrNull(e,t,n){try{return await e.get({name:t,namespace:n})}catch(e){if(isNotFoundError(e))return null;throw e}}function isNotFoundError(e){return typeof e==`object`&&!!e&&Reflect.get(e,`name`)===`SchedulesApiError`&&Reflect.get(e,`status`)===404}function assertSupportedVercelEnvironment(){if(!process.env.VERCEL?.trim())throw Error(`vercelScheduleProvider() requires a Vercel production deployment or eve dev.`);if(process.env.VERCEL_ENV!==`production`)throw Error("Vercel Schedules currently supports production deployments only. Deploy with `vercel --prod`.")}export{readVercelScheduleClientOptions,vercelScheduleProvider};
|
|
@@ -105,7 +105,6 @@ export interface ScheduleCreate<TPayload> {
|
|
|
105
105
|
readonly expression: ScheduleExpression;
|
|
106
106
|
readonly payload: TPayload;
|
|
107
107
|
readonly name: string;
|
|
108
|
-
readonly state?: ScheduleState;
|
|
109
108
|
}
|
|
110
109
|
export interface ScheduleList {
|
|
111
110
|
readonly cursor?: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SandboxSession } from "#public/definitions/sandbox.js";
|
|
2
2
|
import type { SandboxEnvironmentIdentity } from "#shared/sandbox-environment.js";
|
|
3
3
|
import type { SandboxDeleteOptions, SandboxPreparedArtifact } from "#shared/sandbox-provider.js";
|
|
4
|
+
export type SandboxSessionEndReason = "completed" | "expired" | "failed";
|
|
4
5
|
export interface SandboxSessionState {
|
|
5
6
|
readonly providerName: string;
|
|
6
7
|
readonly state: SandboxPreparedArtifact;
|
|
@@ -2,7 +2,7 @@ import{resolveSelfModificationConfig}from"../../../config.js";import{isLocalSelf
|
|
|
2
2
|
|
|
3
3
|
Only when the requester explicitly names the self-modification subagent, edit whichever of /source/extensions/self-modification.ts or /source/extensions/self-modification/extension.ts exists. If neither exists, create /source/extensions/self-modification/extension.ts with write_file using this content, then make the requested model or reasoning change:
|
|
4
4
|
\`\`\`ts
|
|
5
|
-
${renderLocalSelfModificationExtension()}\`\`\``;var instructions_default=defineDynamic({events:{"session.started":()=>isLocalSelfModificationEnabled(resolveSelfModificationConfig(extension_default.config))?defineInstructions({markdown:renderInstructions([roleInstructions,sourceWorkspaceInstructions,sourceEditingInstructions,toolAuthoringInstructions,registryWorkflowInstructions,documentationInstructions,"## Local environment\n\nThe registry_add tool will complete installation for items that need no setup. In the local dev TUI, a `needs-terminal` result
|
|
5
|
+
${renderLocalSelfModificationExtension()}\`\`\``;var instructions_default=defineDynamic({events:{"session.started":()=>isLocalSelfModificationEnabled(resolveSelfModificationConfig(extension_default.config))?defineInstructions({markdown:renderInstructions([roleInstructions,sourceWorkspaceInstructions,sourceEditingInstructions,toolAuthoringInstructions,registryWorkflowInstructions,documentationInstructions,"## Local environment\n\nThe registry_add tool will complete installation for items that need no setup. In the local dev TUI, a `needs-terminal` result queues the existing setup panel, which opens after your reply and reports the setup outcome itself. Until then nothing is installed: say that setup continues in the panel and never describe the item as added, connected, or set up. In headless development, if a `needs-terminal` result includes `nextCommand`, present that exact value as the only shell command in your response. Never infer, construct, or rewrite a command: installing an item uses `eve add <item>`; `eve registry add` configures registry namespace mappings and does not install items.\n\nLocal eve dev logs are mounted read-only at /logs. Local trace segments are mounted read-only at /traces when available. For latency, failure, token, or behavior analysis, load and follow the `trace_analysis` skill. Trace searches are scoped to the invoking conversation and exclude the current investigation by default.\n\nThe application package.json is not mounted. Do not search outside /source for application files. You cannot run host binaries such as git, node, pnpm, or tsc. Use existing imports and registry_add for supported registry installations.",workingInstructions,selfModificationSubagentGuidance,`## Report results
|
|
6
6
|
|
|
7
7
|
For source-modification tasks, return a concise handoff to the caller. Use at most four short bullets covering changed paths and behavior, and any required setup or unresolved issues.
|
|
8
8
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{classifyCatalogEntry}from"../../../classify-registry-item.js";import{runEveAdd}from"../../../eve-add.js";import{defineLocalOnlyDynamic,resolveLocalOnly}from"../../../local-only.js";import{withSelfModificationWorkspaceLock}from"../../../../workspace-lock.js";import{loadRegistryIndex,resolveRegistryIndexUrl}from"./search_registry.js";import{defineTool}from"eve/tools";import{getLocalDevCapability}from"eve/local-dev";const localInputSchema={type:`object`,additionalProperties:!1,properties:{address:{type:`string`,minLength:1,maxLength:200,description:"Exact address of an item in the configured eve registry, for example `channel/slack` or `extension/browserbase`."}},required:[`address`]},localOutputSchema={type:`object`,additionalProperties:!1,properties:{status:{type:`string`,enum:[`installed`,`needs-terminal`,`failed`]},address:{type:`string`},title:{type:`string`},envVars:{type:`array`,items:{type:`string`},description:`Environment variables the item needs that are not set. The item is installed but will not work until the developer sets them. Never ask for or repeat their values.`},reason:{type:`string`,description:`Why the item was not installed here.`},changed:{type:`array`,items:{type:`string`},description:`Project-relative paths a failed install could not restore.`},nextCommand:{type:`string`,description:"The command that completes a `needs-terminal` item."},message:{type:`string`,description:`One-line summary to relay to the developer.`}},required:[`status`,`address`,`message`]};function unsetEnvVars(e,t=process.env){return(e.envVars??[]).filter(e=>{let n=t[e];return n===void 0||n===``})}function handoffMessage(e){if(e.interactiveClient)return{message:`${e.title}
|
|
1
|
+
import{classifyCatalogEntry}from"../../../classify-registry-item.js";import{runEveAdd}from"../../../eve-add.js";import{defineLocalOnlyDynamic,resolveLocalOnly}from"../../../local-only.js";import{withSelfModificationWorkspaceLock}from"../../../../workspace-lock.js";import{loadRegistryIndex,resolveRegistryIndexUrl}from"./search_registry.js";import{defineTool}from"eve/tools";import{getLocalDevCapability}from"eve/local-dev";const localInputSchema={type:`object`,additionalProperties:!1,properties:{address:{type:`string`,minLength:1,maxLength:200,description:"Exact address of an item in the configured eve registry, for example `channel/slack` or `extension/browserbase`."}},required:[`address`]},localOutputSchema={type:`object`,additionalProperties:!1,properties:{status:{type:`string`,enum:[`installed`,`needs-terminal`,`failed`]},address:{type:`string`},title:{type:`string`},envVars:{type:`array`,items:{type:`string`},description:`Environment variables the item needs that are not set. The item is installed but will not work until the developer sets them. Never ask for or repeat their values.`},reason:{type:`string`,description:`Why the item was not installed here.`},changed:{type:`array`,items:{type:`string`},description:`Project-relative paths a failed install could not restore.`},nextCommand:{type:`string`,description:"The command that completes a `needs-terminal` item."},message:{type:`string`,description:`One-line summary to relay to the developer.`}},required:[`status`,`address`,`message`]};function unsetEnvVars(e,t=process.env){return(e.envVars??[]).filter(e=>{let n=t[e];return n===void 0||n===``})}function handoffMessage(e){if(e.interactiveClient)return{message:`${e.title} has not been installed yet. ${e.reason} Its setup panel opens after this reply, asks for anything setup needs, and reports whether setup succeeded; tell the developer to complete it there, and do not describe ${e.title} as added, connected, or set up. Do not ask the developer to run another command.`};let t=`eve add ${e.address}`;return{message:`${e.title} was not installed. ${e.reason} Run \`${t}\` in a terminal to finish it.`,nextCommand:t}}async function addLocalRegistryItem(e,t={}){let n=(t.getCapability??getLocalDevCapability)();if(n===void 0)throw Error("Registry items can only be installed while `eve dev` is running. Report the item address to the developer instead of installing it.");let r=(await loadRegistryIndex({nowMs:Date.now(),signal:t.signal,url:resolveRegistryIndexUrl()})).find(t=>t.address===e);if(r===void 0)throw Error(`No item in the configured eve registry is published at "${e}". Check the address before trying again.`);let i=classifyCatalogEntry(r);if(i.kind===`self-modification-mount`)throw Error(i.reason);if(i.kind===`needs-terminal`){let t=handoffMessage({address:e,interactiveClient:n.interactiveClient,reason:i.reason,title:r.title});return{address:e,reason:i.reason,status:`needs-terminal`,title:r.title,...t}}let a=await withSelfModificationWorkspaceLock(`local:${n.appRoot}`,async()=>n.withSuspendedSource(()=>runEveAdd({address:e,appRoot:n.appRoot,signal:t.signal,spawn:t.spawn})));if(a.kind===`blocked`){let t=handoffMessage({address:e,interactiveClient:n.interactiveClient,reason:a.message,title:r.title});return{address:e,reason:a.message,status:`needs-terminal`,title:r.title,...t}}if(a.kind===`failed`)return a.changed===void 0?{address:e,status:`failed`,title:r.title,reason:a.message,message:a.message}:{address:e,status:`failed`,title:r.title,reason:a.message,message:a.message,changed:a.changed};let o=unsetEnvVars(r);return{address:e,envVars:[...o],message:o.length===0?`Installed ${r.title}.`:`Installed ${r.title}. It will not work until ${o.join(`, `)} ${o.length===1?`is`:`are`} set.`,status:`installed`,title:r.title}}function localRegistryAddTool(){return defineTool({description:`Install an item from the configured eve registry into this project. Items that need setup are handed to the local setup flow instead. Search first, then call this with the exact item address.`,inputSchema:localInputSchema,outputSchema:localOutputSchema,async execute(e,t){let{address:n}=e;if(typeof n!=`string`||n.length===0)throw Error(`address must be an exact item address from the configured eve registry.`);return await addLocalRegistryItem(n,{signal:t.abortSignal})}})}function resolveRegistryAddTool(e){return resolveLocalOnly(e,localRegistryAddTool())}var registry_add_default=defineLocalOnlyDynamic(localRegistryAddTool());export{addLocalRegistryItem,registry_add_default as default,handoffMessage,resolveRegistryAddTool,unsetEnvVars};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SetupPrerequisite } from "#setup/integrations/shared/prerequisite.js";
|
|
1
2
|
import type { Prompter } from "#setup/prompter.js";
|
|
2
3
|
import { detectDeployment } from "#setup/project-resolution.js";
|
|
3
4
|
import type { RegistrySetupCompletion, RegistrySetupFact } from "#setup/registry-setup-protocol.js";
|
|
@@ -12,11 +13,16 @@ export type RegistrySessionOutcome = {
|
|
|
12
13
|
facts: readonly RegistrySetupFact[];
|
|
13
14
|
output: readonly string[];
|
|
14
15
|
}
|
|
15
|
-
/** Files were added, but the item's setup was cancelled or
|
|
16
|
+
/** Files were added, but the item's setup was cancelled, skipped, or failed. */
|
|
16
17
|
| {
|
|
17
18
|
kind: "incomplete";
|
|
18
19
|
title: string;
|
|
20
|
+
/** Registry address, used to resume setup without reinstalling. */
|
|
21
|
+
address: string;
|
|
19
22
|
resumeCommand: string;
|
|
23
|
+
/** Why setup failed; absent when it was cancelled or skipped. */
|
|
24
|
+
reason?: string;
|
|
25
|
+
prerequisite?: SetupPrerequisite;
|
|
20
26
|
}
|
|
21
27
|
/** User-facing installation error, including any actionable follow-up lines. */
|
|
22
28
|
| {
|
|
@@ -38,7 +44,9 @@ export interface RegistrySessionResult {
|
|
|
38
44
|
}
|
|
39
45
|
interface RegistrySession {
|
|
40
46
|
add(title: string, output: readonly string[], setup?: RegistrySetupCompletion): void;
|
|
41
|
-
addIncomplete(title: string,
|
|
47
|
+
addIncomplete(title: string, incomplete: Omit<Extract<RegistrySessionOutcome, {
|
|
48
|
+
kind: "incomplete";
|
|
49
|
+
}>, "kind" | "title">): void;
|
|
42
50
|
addFailure(title: string, message: string): void;
|
|
43
51
|
addCancellation(title: string): void;
|
|
44
52
|
result(deployed?: "production"): RegistrySessionResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./deploy.js";import"#setup/project-resolution.js";function createRegistrySession(e){let t=[],n=!1;function result(e){let n={outcomes:[...t]};return e!==void 0&&(n.deployed=e),n}return{add(e,r,i={facts:[]}){t.push({kind:`installed`,title:e,facts:i.facts,output:r}),n||=i.deploymentRequired===!0},addIncomplete(e,n){t.push({kind:`incomplete`,title:e
|
|
1
|
+
import"./deploy.js";import"#setup/project-resolution.js";function createRegistrySession(e){let t=[],n=!1;function result(e){let n={outcomes:[...t]};return e!==void 0&&(n.deployed=e),n}return{add(e,r,i={facts:[]}){t.push({kind:`installed`,title:e,facts:i.facts,output:r}),n||=i.deploymentRequired===!0},addIncomplete(e,n){t.push({kind:`incomplete`,title:e,...n})},addFailure(e,n){t.push({kind:`failed`,title:e,message:n})},addCancellation(e){t.push({kind:`cancelled`,title:e})},result,async continueAfterInstall(t){if(!n)return result();let r=await e.detectDeployment(t.appRoot,{signal:t.signal}),i=r.state===`linked`||r.state===`deployed`;for(t.prompter.replaceContent?.();;){if(await t.prompter.select({message:`What would you like to do next?`,initialValue:`finish`,hintLayout:`inline`,options:[...i?[{value:`deploy`,label:`Deploy`}]:[],{value:`finish`,label:`Start chatting`}]})===`finish`)return result();if(await t.prompter.select({message:`Deploy to prod?`,initialValue:`yes`,options:[{value:`yes`,label:`Yes`},{value:`back`,label:`Back`}]})!==`back`)return result((await e.runDeployFlow({appRoot:t.appRoot,prompter:t.prompter,signal:t.signal,interactive:!0})).kind===`deployed`?`production`:void 0)}}}}export{createRegistrySession};
|
|
@@ -22,6 +22,8 @@ export declare function runRegistryFlow(input: {
|
|
|
22
22
|
signal?: AbortSignal;
|
|
23
23
|
/** Registry item supplied by `/add <item>`, installed directly. */
|
|
24
24
|
initialAddress?: string;
|
|
25
|
+
/** Rerun the item's setup only; its source is already installed. */
|
|
26
|
+
skipInstall?: boolean;
|
|
25
27
|
onScreen?: (input: {
|
|
26
28
|
screen: "registry_install";
|
|
27
29
|
registrySelectedCount?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRegistrySession}from"./registry-session.js";import{WizardCancelledError}from"#setup/step.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{withSpinner}from"#setup/with-spinner.js";function label(e){return e.name}var RegistryFlowFailedError=class extends Error{completed;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.name=`RegistryFlowFailedError`,this.completed=t}};function hasSettledOutcomes(e){return e!==void 0&&e.outcomes.length>0}async function runRegistryFlow(e){let t;try{let n=e.initialAddress?.trim(),r;if(n!==void 0&&n!==``)r=[{address:n,name:n,source:`Registry`}];else{let t=e.deps?.browseRegistryCatalog??(await import(`#cli/commands/registry.js`)).browseRegistryCatalog,n=await withSpinner(e.prompter,`Loading registry…`,()=>t(e.appRoot)),i=[...n.items],a=await e.prompter.select({message:`Add to your agent`,search:!0,options:i.map(e=>({value:e.address,label:e.name,hint:e.address,keywords:[e.title??``,e.description??``]})),notices:n.errors.map(e=>({tone:`warning`,text:`${e.registry}: ${e.message}`}))}),o=i.find(e=>e.address===a);if(o===void 0)throw Error(`That registry item is no longer available. Run /add to try again.`);r=[o]}let i=e.deps?.installRegistryItem??(await import(`#cli/commands/registry.js`)).installRegistryItem,a=e.installRoot??e.appRoot,o=e.deps?.detectDeployment??(await import(`#setup/project-resolution.js`)).detectDeployment,s=e.deps?.runDeployFlow??(await import(`./deploy.js`)).runDeployFlow;t=createRegistrySession({detectDeployment:o,runDeployFlow:s}),e.onScreen?.({screen:`registry_install`});let c=t;for(let[t,n]of r.entries()){e.signal?.throwIfAborted(),e.onItemStart?.(n,t,r.length);try{let install=(t=e.signal)=>i(a,n.address,{silent:!0,prompter:e.prompter,signal:t}),run=()=>e.runItem===void 0?install():e.runItem(install),t=await(e.prompter.withExclusiveTerminal?.(run)??run());t.setupIncomplete===void 0?c.add(label(n),t.output,t.setup):c.addIncomplete(label(n),t.setupIncomplete
|
|
1
|
+
import{createRegistrySession}from"./registry-session.js";import{WizardCancelledError}from"#setup/step.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{withSpinner}from"#setup/with-spinner.js";function label(e){return e.name}var RegistryFlowFailedError=class extends Error{completed;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.name=`RegistryFlowFailedError`,this.completed=t}};function hasSettledOutcomes(e){return e!==void 0&&e.outcomes.length>0}async function runRegistryFlow(e){let t;try{let n=e.initialAddress?.trim(),r;if(n!==void 0&&n!==``)r=[{address:n,name:n,source:`Registry`}];else{let t=e.deps?.browseRegistryCatalog??(await import(`#cli/commands/registry.js`)).browseRegistryCatalog,n=await withSpinner(e.prompter,`Loading registry…`,()=>t(e.appRoot)),i=[...n.items],a=await e.prompter.select({message:`Add to your agent`,search:!0,options:i.map(e=>({value:e.address,label:e.name,hint:e.address,keywords:[e.title??``,e.description??``]})),notices:n.errors.map(e=>({tone:`warning`,text:`${e.registry}: ${e.message}`}))}),o=i.find(e=>e.address===a);if(o===void 0)throw Error(`That registry item is no longer available. Run /add to try again.`);r=[o]}let i=e.deps?.installRegistryItem??(await import(`#cli/commands/registry.js`)).installRegistryItem,a=e.installRoot??e.appRoot,o=e.deps?.detectDeployment??(await import(`#setup/project-resolution.js`)).detectDeployment,s=e.deps?.runDeployFlow??(await import(`./deploy.js`)).runDeployFlow;t=createRegistrySession({detectDeployment:o,runDeployFlow:s}),e.onScreen?.({screen:`registry_install`});let c=t;for(let[t,n]of r.entries()){e.signal?.throwIfAborted(),e.onItemStart?.(n,t,r.length);try{let install=(t=e.signal)=>i(a,n.address,{silent:!0,...e.skipInstall===!0&&{skipInstall:!0},prompter:e.prompter,signal:t}),run=()=>e.runItem===void 0?install():e.runItem(install),t=await(e.prompter.withExclusiveTerminal?.(run)??run());t.setupIncomplete===void 0?c.add(label(n),t.output,t.setup):c.addIncomplete(label(n),{address:n.address,...t.setupIncomplete})}catch(t){if(e.signal?.throwIfAborted(),t instanceof WizardCancelledError){c.addCancellation(label(n));continue}if(t instanceof HumanActionRequiredError)throw t;let r=(t instanceof Error?t.message:String(t)).trim()||`Installation failed.`;c.addFailure(label(n),r)}}return{kind:`done`,result:await c.continueAfterInstall({appRoot:e.appRoot,prompter:e.prompter,signal:e.signal})}}catch(e){if(e instanceof WizardCancelledError){let e=t?.result();return hasSettledOutcomes(e)?{kind:`done`,result:{...e,cancelled:!0}}:{kind:`cancelled`}}let n=t?.result();throw hasSettledOutcomes(n)?new RegistryFlowFailedError(e,n):e}}export{RegistryFlowFailedError,runRegistryFlow};
|
|
@@ -15,3 +15,11 @@ export declare class SetupPrerequisiteRequired extends Error {
|
|
|
15
15
|
readonly prerequisite: SetupPrerequisite;
|
|
16
16
|
constructor(prerequisite: SetupPrerequisite);
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* The structured prerequisite behind a setup error, if any. Shared Vercel
|
|
20
|
+
* provisioning steps throw {@link HumanActionRequiredError} (for example
|
|
21
|
+
* `vercel login`); setup callers report it as a command prerequisite so the
|
|
22
|
+
* action survives process and protocol boundaries instead of being flattened
|
|
23
|
+
* into an unactionable message.
|
|
24
|
+
*/
|
|
25
|
+
export declare function setupPrerequisiteOf(error: unknown): SetupPrerequisite | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var SetupPrerequisiteRequired=class extends Error{prerequisite;constructor(e){super(e.message),this.name=`SetupPrerequisiteRequired`,this.prerequisite=e}};export{SetupPrerequisiteRequired};
|
|
1
|
+
import{HumanActionRequiredError}from"../../human-action.js";var SetupPrerequisiteRequired=class extends Error{prerequisite;constructor(e){super(e.message),this.name=`SetupPrerequisiteRequired`,this.prerequisite=e}};function setupPrerequisiteOf(e){if(e instanceof SetupPrerequisiteRequired)return e.prerequisite;if(e instanceof HumanActionRequiredError)return{kind:`command`,code:e.action.kind,message:e.action.reason,command:e.action.command}}export{SetupPrerequisiteRequired,setupPrerequisiteOf};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{InteractionRequired,InvalidAnswerError}from"./ask-signals.js";import{
|
|
1
|
+
import{InteractionRequired,InvalidAnswerError}from"./ask-signals.js";import{setupPrerequisiteOf}from"./integrations/shared/prerequisite.js";import"./ask.js";import{WizardCancelledError}from"./step.js";import{setupQuestionToWire}from"./setup-question-wire.js";import"./registry-setup-protocol.js";function send(e,t){if(e.send===void 0||!e.connected)throw Error(`The registry setup host disconnected.`);e.send(t)}function registrySetupBlocker(e){if(e instanceof InteractionRequired)return{status:`input_required`,question:setupQuestionToWire(e.question)};if(e instanceof InvalidAnswerError)return{status:`input_required`,question:setupQuestionToWire(e.question),issue:{code:`invalid_answer`,message:e.message}};let t=setupPrerequisiteOf(e);return t===void 0?void 0:{status:`prerequisite_required`,prerequisite:t}}function registrySetupError(e){if(!(e instanceof Error))return{message:String(e)};let t=e.stack?.split(`
|
|
2
2
|
`).slice(1).map(e=>e.trim()).filter(Boolean);return t===void 0||t.length===0?{message:e.message}:{message:e.message,details:t}}function createRegistrySetupClient(e={}){let t=e.process??process;if(t.send===void 0||process.env.EVE_SETUP_PROTOCOL===void 0)return;let n=new AbortController;e.signal!==void 0&&e.signal.addEventListener(`abort`,()=>n.abort(e.signal?.reason),{once:!0});let r=1,i=new Map,onMessage=e=>{if(e.type===`cancel`){n.abort(new WizardCancelledError);for(let e of i.values())e({type:`cancel`});i.clear();return}i.get(e.id)?.(e)};t.on(`message`,onMessage),send(t,{type:`ready`,version:2});async function prompt(e){n.signal.throwIfAborted();let a=r++,o=await new Promise(n=>{i.set(a,n),send(t,{type:`prompt`,id:a,prompt:e})});if(i.delete(a),o.type===`cancel`||o.cancelled===!0)throw new WizardCancelledError;return o.value}async function validatedText(e,t){let n=t.notices;for(;;){let r=await prompt({kind:e,message:t.message,placeholder:t.placeholder,defaultValue:t.defaultValue,notices:n}),i=t.validate?.(r);if(i===void 0)return r;n=[{tone:`error`,text:i}]}}function select(e){return prompt({kind:`select`,options:e})}let a={text:e=>validatedText(`text`,e),password:e=>validatedText(`password`,e),select,async selectEditable(e){let t=await prompt({kind:`editable-select`,options:{...e,editable:{value:e.editable.value,defaultValue:e.editable.defaultValue}}});if(t.kind===`selected`)return{kind:`selected`,value:t.value};let n=e.editable.validate?.(t.text);if(n!==void 0)throw Error(n);return{kind:`edited`,value:t.value,text:t.text}},acknowledge:e=>prompt({kind:`acknowledge`,options:e}),awaitChoice(e){let n=r++;return{choice:new Promise((r,a)=>{i.set(n,e=>{i.delete(n),e.type===`cancel`||e.cancelled===!0?a(new WizardCancelledError):r(e.value)}),send(t,{type:`prompt`,id:n,prompt:{kind:`choice`,options:e}})}),close:()=>{i.delete(n),send(t,{type:`close-prompt`,id:n})}}},note(e,n,r){send(t,{type:`note`,message:e,title:n,tone:r?.tone})},intro(e,n){send(t,{type:`intro`,text:e,subtitle:n})},outro(e){send(t,{type:`outro`,text:e})},log:{message:e=>send(t,{type:`log`,level:`message`,text:e}),info:e=>send(t,{type:`log`,level:`info`,text:e}),success:e=>send(t,{type:`log`,level:`success`,text:e}),warning:e=>send(t,{type:`log`,level:`warning`,text:e}),error:e=>send(t,{type:`log`,level:`error`,text:e}),commandOutput:e=>send(t,{type:`log`,level:`commandOutput`,text:e}),spinner(e){let n=r++;return send(t,{type:`status`,id:n,status:e}),{stop:()=>send(t,{type:`status`,id:n})}}}},o=!1,finish=e=>{o||(o=!0,send(t,{type:`result`,outcome:e}),t.off(`message`,onMessage),t.disconnect?.())};return{prompter:a,signal:n.signal,complete:(e={facts:[]})=>finish({kind:`completed`,...e}),cancel:()=>finish({kind:`cancelled`}),fail(e){let t=registrySetupBlocker(e);finish(t===void 0?{kind:`failed`,error:registrySetupError(e)}:{kind:`blocked`,blocker:t})}}}export{createRegistrySetupClient};
|