experimental-ash 0.34.0 → 0.36.0
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 +35 -0
- package/dist/docs/internals/context.md +6 -5
- package/dist/docs/internals/core-beliefs.md +2 -2
- package/dist/docs/internals/hooks.md +16 -11
- package/dist/docs/internals/mechanical-invariants.md +4 -4
- package/dist/docs/internals/testing.md +1 -1
- package/dist/docs/public/README.md +1 -1
- package/dist/docs/public/auth-and-route-protection.md +12 -3
- package/dist/docs/public/channels/{README.md → index.md} +2 -2
- package/dist/docs/public/channels/slack.md +3 -3
- package/dist/docs/public/cli-build-and-debugging.md +1 -1
- package/dist/docs/public/faqs.md +4 -5
- package/dist/docs/public/hooks.md +18 -23
- package/dist/docs/public/meta.json +4 -4
- package/dist/docs/public/sandbox.md +51 -30
- package/dist/docs/public/schedules.md +1 -1
- package/dist/docs/public/session-context.md +26 -28
- package/dist/docs/public/skills.md +3 -4
- package/dist/docs/public/subagents.md +1 -1
- package/dist/docs/public/tools.md +13 -17
- package/dist/docs/public/typescript-api.md +10 -11
- package/dist/src/channel/session.d.ts +3 -29
- package/dist/src/channel/session.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +2 -2
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +11 -2
- package/dist/src/compiled/@vercel/sandbox/index.js +3 -3
- package/dist/src/compiled/@vercel/sandbox/package.json +1 -1
- package/dist/src/compiled/_chunks/node/{auth-ZhCJAHxl.js → auth-CVVvWjaK.js} +1 -1
- package/dist/src/compiled/_chunks/node/{version-D4IYmfaS.js → version-nR4RSpFw.js} +1 -1
- package/dist/src/context/build-callback-context.d.ts +8 -0
- package/dist/src/context/build-callback-context.js +1 -0
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/sandbox/bash-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/bash-tool.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +1 -1
- package/dist/src/execution/sandbox/glob-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/glob-tool.js +3 -3
- package/dist/src/execution/sandbox/grep-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/grep-tool.js +3 -3
- package/dist/src/execution/sandbox/read-file-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/read-file-tool.js +1 -1
- package/dist/src/execution/sandbox/session.js +1 -1
- package/dist/src/execution/sandbox/write-file-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/write-file-tool.js +1 -1
- package/dist/src/execution/tool-compaction.js +1 -1
- package/dist/src/harness/code-mode-approval.js +1 -1
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/logging.js +1 -1
- package/dist/src/internal/workflow-bundle/builder.js +2 -2
- package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/index.js +1 -1
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/manager.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/worker-source.js +408 -0
- package/dist/src/packages/ash-scaffold/src/channels.js +2 -12
- package/dist/src/packages/ash-scaffold/src/pnpm-workspace.js +11 -0
- package/dist/src/packages/ash-scaffold/src/project.js +1 -1
- package/dist/src/packages/ash-scaffold/src/web-template.js +2 -2
- package/dist/src/public/channels/auth.d.ts +22 -11
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/public/context/index.d.ts +3 -2
- package/dist/src/public/context/index.js +1 -1
- package/dist/src/public/definitions/callback-context.d.ts +22 -0
- package/dist/src/public/definitions/callback-context.js +1 -0
- package/dist/src/public/definitions/hook.d.ts +9 -49
- package/dist/src/public/definitions/sandbox.d.ts +1 -1
- package/dist/src/public/definitions/tool.d.ts +14 -15
- package/dist/src/public/hooks/index.d.ts +1 -1
- package/dist/src/public/sandbox/index.d.ts +1 -2
- package/dist/src/public/sandbox/index.js +1 -1
- package/dist/src/public/sandbox/vercel-sandbox.d.ts +4 -4
- package/dist/src/public/skills/index.d.ts +0 -1
- package/dist/src/public/skills/index.js +1 -1
- package/dist/src/public/tools/defaults.js +1 -1
- package/dist/src/public/tools/define-bash-tool.js +1 -1
- package/dist/src/public/tools/define-glob-tool.js +1 -1
- package/dist/src/public/tools/define-grep-tool.js +1 -1
- package/dist/src/public/tools/define-read-file-tool.js +1 -1
- package/dist/src/public/tools/define-write-file-tool.js +1 -1
- package/dist/src/public/tools/index.d.ts +2 -1
- package/dist/src/public/tools/internal.d.ts +4 -0
- package/dist/src/public/tools/internal.js +1 -1
- package/dist/src/runtime/framework-tools/bash.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search.js +1 -1
- package/dist/src/runtime/framework-tools/connection-tools.js +1 -1
- package/dist/src/runtime/framework-tools/file-state.d.ts +2 -2
- package/dist/src/runtime/framework-tools/file-state.js +1 -1
- package/dist/src/runtime/framework-tools/glob.js +1 -1
- package/dist/src/runtime/framework-tools/grep.js +1 -1
- package/dist/src/runtime/framework-tools/read-file.js +2 -2
- package/dist/src/runtime/framework-tools/todo.js +1 -1
- package/dist/src/runtime/framework-tools/write-file.js +1 -1
- package/dist/src/runtime/governance/auth/oidc.js +1 -1
- package/dist/src/runtime/governance/auth/token-claims.d.ts +2 -0
- package/dist/src/runtime/governance/auth/token-claims.js +1 -1
- package/dist/src/runtime/governance/auth/types.d.ts +6 -0
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/shared/sandbox-session.d.ts +0 -17
- package/package.json +3 -3
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/manager.js +0 -1
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/worker-source.js +0 -1153
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime-assets.js +0 -1
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/approval-continuation.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/approval-response.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/code-mode-tool.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/continuation-capability.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/errors.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/fetch-policy.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/host-interrupt.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/interrupt-continuation.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/options.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/run-code-mode.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/runtime/max-workers.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/serialization.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/source-cache.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/telemetry.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/tool-invocation.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/tool-prompt.js +0 -0
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"./files.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"./web-template.js";import"./project.js";import{patchPackageJson}from"./package-json.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/ash/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`],
|
|
1
|
+
import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"./files.js";import{PNPM_WORKSPACE_PATH,ensurePnpmWorkspacePolicy}from"./pnpm-workspace.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"./web-template.js";import"./project.js";import{patchPackageJson}from"./package-json.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/ash/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`],WEB_VERCEL_JSON_PATH=`vercel.json`,WEB_VERCEL_JSON_SCHEMA=`https://openapi.vercel.sh/vercel.json`,WEB_DEFAULT_VERCEL_SERVICES={web:{entrypoint:`.`,framework:`nextjs`,routePrefix:`/`},ash:{buildCommand:`ash build`,entrypoint:`.`,framework:`ash`,routePrefix:`/_ash_internal/ash`}};function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readDependencyVersion(e,t){let n=JSON.parse(await readFile(e,`utf8`));if(!isJsonObject(n)||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,t){if(!await pathExists(e))return!1;let r=JSON.parse(await readFile(e,`utf8`));return isJsonObject(r)&&packageJsonHasDependency(r,t)}async function ensurePackageDependency(e,t,r){return!await pathExists(e)||await readDependencyVersion(e,t)===r?[]:(await patchPackageJson(e,{dependencies:{[t]:r}}),[{path:e,dependencies:[t],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{ashPackageVersion:e?.ashPackageVersion??`0.36.0`,aiPackageVersion:e?.aiPackageVersion??`7.0.0-canary.154`,nextPackageVersion:e?.nextPackageVersion??`16.2.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,tsgoPackageVersion:e?.tsgoPackageVersion??`7.0.0-dev.20260523.1`,typesNodePackageVersion:e?.typesNodePackageVersion??`25.9.1`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatAshDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,t){if(!await pathExists(e))return[];assertStampedVersion(`ashPackageVersion`,t.ashPackageVersion),assertStampedVersion(`aiPackageVersion`,t.aiPackageVersion),assertStampedVersion(`nextPackageVersion`,t.nextPackageVersion),assertStampedVersion(`reactPackageVersion`,t.reactPackageVersion),assertStampedVersion(`reactDomPackageVersion`,t.reactDomPackageVersion),assertStampedVersion(`streamdownPackageVersion`,t.streamdownPackageVersion),assertStampedVersion(`zodPackageVersion`,t.zodPackageVersion),assertStampedVersion(`tsgoPackageVersion`,t.tsgoPackageVersion),assertStampedVersion(`typesNodePackageVersion`,t.typesNodePackageVersion),assertStampedVersion(`typesReactPackageVersion`,t.typesReactPackageVersion),assertStampedVersion(`typesReactDomPackageVersion`,t.typesReactDomPackageVersion);let r={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:t.aiPackageVersion,"experimental-ash":formatAshDependencySpecifier(t.ashPackageVersion),next:t.nextPackageVersion,react:t.reactPackageVersion,"react-dom":t.reactDomPackageVersion,streamdown:t.streamdownPackageVersion,zod:t.zodPackageVersion},i={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":t.typesNodePackageVersion,"@types/react":t.typesReactPackageVersion,"@types/react-dom":t.typesReactDomPackageVersion,"@typescript/native-preview":t.tsgoPackageVersion},a=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts;return await patchPackageJson(e,{dependencies:r,devDependencies:i,scripts:a}),[{path:e,dependencies:Object.keys(r),devDependencies:Object.keys(i),scripts:Object.keys(a)}]}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackTemplate(e){return`import { connectSlackCredentials } from "@vercel/connect/ash";
|
|
2
2
|
import { slackChannel } from "experimental-ash/channels/slack";
|
|
3
3
|
|
|
4
4
|
export default slackChannel({
|
|
5
5
|
credentials: connectSlackCredentials("slack/${e}"),
|
|
6
6
|
});
|
|
7
|
-
`}function renderWebAppTemplate(e,t){return e.replaceAll(`__ASH_INIT_APP_NAME__`,t)}function
|
|
8
|
-
`)?e:`${e}\n`,n=t.split(`
|
|
9
|
-
`),r=n.findIndex(e=>e===`allowBuilds:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}allowBuilds:\n${WEB_SHARP_BUILD_POLICY}\n`;let i=findYamlBlockEnd(n,r);if(n.slice(r+1,i).some(e=>/^\s+sharp:/.test(e)))return e;let a=i;for(;a>r+1&&n[a-1]===``;)--a;return n.splice(a,0,WEB_SHARP_BUILD_POLICY),n.join(`
|
|
10
|
-
`)}function withExperimentalAshReleaseAgeExclusion(e){let t=e.endsWith(`
|
|
11
|
-
`)?e:`${e}\n`,n=t.split(`
|
|
12
|
-
`),r=n.findIndex(e=>e===`minimumReleaseAgeExclude:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}minimumReleaseAgeExclude:\n${WEB_ASH_RELEASE_AGE_EXCLUSION}\n`;let i=findYamlBlockEnd(n,r);if(n.slice(r+1,i).some(e=>e.trim()===`- experimental-ash`))return e;let a=i;for(;a>r+1&&n[a-1]===``;)--a;return n.splice(a,0,WEB_ASH_RELEASE_AGE_EXCLUSION),n.join(`
|
|
13
|
-
`)}async function ensureWebPnpmWorkspacePolicy(e,t){if(!await pathExists(e))return await writeTextFile(e,t,{force:!0}),`written`;let i=await readFile(e,`utf8`),a=withExperimentalAshReleaseAgeExclusion(withSharpBuildPolicy(i));return a===i?`skipped`:(await writeFile(e,a,`utf8`),`written`)}function withWebVercelServices(e){let t=JSON.parse(e);if(!isJsonObject(t))throw Error(`${WEB_VERCEL_JSON_PATH} must contain a JSON object.`);let n=t.experimentalServices;if(n!==void 0&&!isJsonObject(n))throw Error(`${WEB_VERCEL_JSON_PATH} experimentalServices must contain a JSON object.`);let r={...t,$schema:typeof t.$schema==`string`?t.$schema:WEB_VERCEL_JSON_SCHEMA,experimentalServices:{...n,web:n?.web??WEB_DEFAULT_VERCEL_SERVICES.web,ash:n?.ash??WEB_DEFAULT_VERCEL_SERVICES.ash}};return JSON.stringify(t)===JSON.stringify(r)?e:`${JSON.stringify(r,null,2)}\n`}async function ensureWebVercelServices(e){if(!await pathExists(e))return await writeTextFile(e,`${JSON.stringify({$schema:WEB_VERCEL_JSON_SCHEMA,experimentalServices:WEB_DEFAULT_VERCEL_SERVICES},null,2)}\n`,{force:!0}),`written`;let t=await readFile(e,`utf8`),i=withWebVercelServices(t);return i===t?`skipped`:(await writeFile(e,i,`utf8`),`written`)}function assertStampedVersion(e,t){if(t.startsWith(`__`))throw Error(`Channel scaffold received unstamped version token (${e}=${t}). Build @vercel/ash-scaffold before using its dist entrypoint.`)}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),a=await pathExists(join(e.projectRoot,`app/page.tsx`));if(!e.force&&await hasPackageDependency(t,`next`))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let o=await patchWebPackageJson(t,resolveWebPackageVersions(e.webPackageVersions)),c=[],l=[],u=basename(resolve(e.projectRoot)),d=join(e.projectRoot,WEB_VERCEL_JSON_PATH);await ensureWebVercelServices(d)===`written`?c.push(d):l.push(d);let f=join(e.projectRoot,`pnpm-workspace.yaml`);await ensureWebPnpmWorkspacePolicy(f,`minimumReleaseAgeExclude:
|
|
14
|
-
- experimental-ash
|
|
15
|
-
allowBuilds:
|
|
16
|
-
sharp: false
|
|
17
|
-
`)===`written`?c.push(f):l.push(f);for(let[t,a]of Object.entries(WEB_APP_TEMPLATE_FILES)){let i=join(e.projectRoot,t);if(t===`agent/channels/ash.ts`&&!e.force&&await pathExists(i)){l.push(i);continue}await writeTextFile(i,renderWebAppTemplate(a,u),{force:!0}),c.push(i)}return{kind:`web`,action:a?`overwritten`:`created`,filesWritten:c,filesSkipped:l,packageJsonUpdated:o}}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),i=await pathExists(t);if(!e.force&&i)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let a=e.connectPackageVersion??`0.0.6-alpha.1`;assertStampedVersion(`connectPackageVersion`,a);let o=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,a),s=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot);return await writeTextFile(t,buildSlackTemplate(s),{force:e.force}),{kind:`slack`,action:i?`overwritten`:`created`,filesWritten:[t],filesSkipped:[],packageJsonUpdated:o,slackConnectorSlug:s}}async function listAuthoredChannels(n){let r=join(n,`agent/channels`),i;try{i=await readdir(r,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let a=[];for(let n of i){if(n.isFile()){let t=getSupportedModuleBaseName(n.name);t!==null&&a.push(t);continue}if(n.isDirectory())try{(await readdir(join(r,n.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&a.push(n.name)}catch{}}return a.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,listAuthoredChannels,normalizeSlackConnectorSlug};
|
|
7
|
+
`}function renderWebAppTemplate(e,t){return e.replaceAll(`__ASH_INIT_APP_NAME__`,t)}function withWebVercelServices(e){let t=JSON.parse(e);if(!isJsonObject(t))throw Error(`${WEB_VERCEL_JSON_PATH} must contain a JSON object.`);let n=t.experimentalServices;if(n!==void 0&&!isJsonObject(n))throw Error(`${WEB_VERCEL_JSON_PATH} experimentalServices must contain a JSON object.`);let r={...t,$schema:typeof t.$schema==`string`?t.$schema:WEB_VERCEL_JSON_SCHEMA,experimentalServices:{...n,web:n?.web??WEB_DEFAULT_VERCEL_SERVICES.web,ash:n?.ash??WEB_DEFAULT_VERCEL_SERVICES.ash}};return JSON.stringify(t)===JSON.stringify(r)?e:`${JSON.stringify(r,null,2)}\n`}async function ensureWebVercelServices(e){if(!await pathExists(e))return await writeTextFile(e,`${JSON.stringify({$schema:WEB_VERCEL_JSON_SCHEMA,experimentalServices:WEB_DEFAULT_VERCEL_SERVICES},null,2)}\n`,{force:!0}),`written`;let t=await readFile(e,`utf8`),i=withWebVercelServices(t);return i===t?`skipped`:(await writeFile(e,i,`utf8`),`written`)}function assertStampedVersion(e,t){if(t.startsWith(`__`))throw Error(`Channel scaffold received unstamped version token (${e}=${t}). Build @vercel/ash-scaffold before using its dist entrypoint.`)}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),s=await pathExists(join(e.projectRoot,`app/page.tsx`));if(!e.force&&await hasPackageDependency(t,`next`))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let c=await patchWebPackageJson(t,resolveWebPackageVersions(e.webPackageVersions)),l=[],u=[],d=basename(resolve(e.projectRoot)),f=join(e.projectRoot,WEB_VERCEL_JSON_PATH);await ensureWebVercelServices(f)===`written`?l.push(f):u.push(f);let p=join(e.projectRoot,PNPM_WORKSPACE_PATH);await ensurePnpmWorkspacePolicy(p)===`written`?l.push(p):u.push(p);for(let[t,i]of Object.entries(WEB_APP_TEMPLATE_FILES)){let a=join(e.projectRoot,t);if(t===`agent/channels/ash.ts`&&!e.force&&await pathExists(a)){u.push(a);continue}await writeTextFile(a,renderWebAppTemplate(i,d),{force:!0}),l.push(a)}return{kind:`web`,action:s?`overwritten`:`created`,filesWritten:l,filesSkipped:u,packageJsonUpdated:c}}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),i=await pathExists(t);if(!e.force&&i)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let a=e.connectPackageVersion??`0.0.6-alpha.1`;assertStampedVersion(`connectPackageVersion`,a);let o=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,a),s=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot);return await writeTextFile(t,buildSlackTemplate(s),{force:e.force}),{kind:`slack`,action:i?`overwritten`:`created`,filesWritten:[t],filesSkipped:[],packageJsonUpdated:o,slackConnectorSlug:s}}async function listAuthoredChannels(n){let r=join(n,`agent/channels`),i;try{i=await readdir(r,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let a=[];for(let n of i){if(n.isFile()){let t=getSupportedModuleBaseName(n.name);t!==null&&a.push(t);continue}if(n.isDirectory())try{(await readdir(join(r,n.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&a.push(n.name)}catch{}}return a.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,listAuthoredChannels,normalizeSlackConnectorSlug};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{pathExists,writeTextFile}from"./files.js";import{readFile,writeFile}from"node:fs/promises";const PNPM_WORKSPACE_PATH=`pnpm-workspace.yaml`,PNPM_WORKSPACE_CONTENT=`minimumReleaseAgeExclude:
|
|
2
|
+
- experimental-ash
|
|
3
|
+
allowBuilds:
|
|
4
|
+
sharp: false
|
|
5
|
+
`,ASH_RELEASE_AGE_EXCLUSION=` - experimental-ash`,SHARP_BUILD_POLICY=` sharp: false`;function findYamlBlockEnd(e,t){let n=t+1;for(;n<e.length;){let t=e[n]??``;if(t.length>0&&!t.startsWith(` `)&&!t.startsWith(` `))break;n+=1}return n}function withSharpBuildPolicy(e){let t=e.endsWith(`
|
|
6
|
+
`)?e:`${e}\n`,n=t.split(`
|
|
7
|
+
`),r=n.findIndex(e=>e===`allowBuilds:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}allowBuilds:\n${SHARP_BUILD_POLICY}\n`;let i=findYamlBlockEnd(n,r);if(n.slice(r+1,i).some(e=>/^\s+sharp:/.test(e)))return e;let a=i;for(;a>r+1&&n[a-1]===``;)--a;return n.splice(a,0,SHARP_BUILD_POLICY),n.join(`
|
|
8
|
+
`)}function withExperimentalAshReleaseAgeExclusion(e){let t=e.endsWith(`
|
|
9
|
+
`)?e:`${e}\n`,n=t.split(`
|
|
10
|
+
`),r=n.findIndex(e=>e===`minimumReleaseAgeExclude:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}minimumReleaseAgeExclude:\n${ASH_RELEASE_AGE_EXCLUSION}\n`;let i=findYamlBlockEnd(n,r);if(n.slice(r+1,i).some(e=>e.trim()===`- experimental-ash`))return e;let a=i;for(;a>r+1&&n[a-1]===``;)--a;return n.splice(a,0,ASH_RELEASE_AGE_EXCLUSION),n.join(`
|
|
11
|
+
`)}async function ensurePnpmWorkspacePolicy(i){if(!await pathExists(i))return await writeTextFile(i,PNPM_WORKSPACE_CONTENT,{force:!0}),`written`;let o=await readFile(i,`utf8`),s=withExperimentalAshReleaseAgeExclusion(withSharpBuildPolicy(o));return s===o?`skipped`:(await writeFile(i,s,`utf8`),`written`)}export{PNPM_WORKSPACE_CONTENT,PNPM_WORKSPACE_PATH,ensurePnpmWorkspacePolicy};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"./module-files.js";import"./files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{join}from"node:path";import{stat}from"node:fs/promises";new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),WEB_APP_TEMPLATE_FILES[`agent/channels/ash.ts`];async function isAshProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{isAshProject};
|
|
1
|
+
import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"./module-files.js";import"./files.js";import"./pnpm-workspace.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{join}from"node:path";import{stat}from"node:fs/promises";new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),WEB_APP_TEMPLATE_FILES[`agent/channels/ash.ts`];async function isAshProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{isAshProject};
|
|
@@ -16,10 +16,10 @@ function exampleProductionAuth(): AuthFn<Request> {
|
|
|
16
16
|
|
|
17
17
|
export default ashChannel({
|
|
18
18
|
auth: [
|
|
19
|
-
// Lets the Ash TUI and your Vercel deployments reach the deployed agent.
|
|
20
|
-
vercelOidc(),
|
|
21
19
|
// Open on localhost for \`ash dev\` and the REPL; ignored in production.
|
|
22
20
|
localDev(),
|
|
21
|
+
// Lets the Ash TUI and your Vercel deployments reach the deployed agent.
|
|
22
|
+
vercelOidc(),
|
|
23
23
|
// Your end-user auth — replace the placeholder above.
|
|
24
24
|
exampleProductionAuth(),
|
|
25
25
|
],
|
|
@@ -198,11 +198,12 @@ export declare function routeAuth(request: Request, auth: AuthFn<Request> | read
|
|
|
198
198
|
*/
|
|
199
199
|
export declare function none<TEvent = unknown>(): AuthFn<TEvent>;
|
|
200
200
|
/**
|
|
201
|
-
* Returns an {@link AuthFn} that authenticates requests
|
|
202
|
-
* inbound request was addressed to a
|
|
201
|
+
* Returns an {@link AuthFn} that authenticates requests during local
|
|
202
|
+
* development — either when the inbound request was addressed to a
|
|
203
|
+
* loopback hostname, or when the process is running under `vercel dev`.
|
|
203
204
|
*
|
|
204
|
-
* The check is on the request URL's hostname, not the host
|
|
205
|
-
* hostname is treated as loopback when it is one of:
|
|
205
|
+
* The primary check is on the request URL's hostname, not the host
|
|
206
|
+
* process. A hostname is treated as loopback when it is one of:
|
|
206
207
|
*
|
|
207
208
|
* - `localhost` or any `*.localhost` subdomain (per RFC 6761, browsers
|
|
208
209
|
* and DNS resolvers route the whole `.localhost` TLD to loopback);
|
|
@@ -216,13 +217,16 @@ export declare function none<TEvent = unknown>(): AuthFn<TEvent>;
|
|
|
216
217
|
* `[localDev(), vercelOidc()]` the canonical "open on localhost,
|
|
217
218
|
* Vercel OIDC in prod" pattern.
|
|
218
219
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
* `
|
|
225
|
-
*
|
|
220
|
+
* The hostname check is intentionally not based on bare
|
|
221
|
+
* `process.env.VERCEL`: sniffing only that flag is unsafe because a
|
|
222
|
+
* deployment outside Vercel (Fly, Railway, raw container, etc.) leaves
|
|
223
|
+
* `VERCEL` unset and would accept every request from the public
|
|
224
|
+
* internet. The one process-level exception is `vercel dev`, detected
|
|
225
|
+
* by `VERCEL=1` **and** `VERCEL_ENV=development` together. That pair is
|
|
226
|
+
* only ever set by the local `vercel dev` server — preview and
|
|
227
|
+
* production deployments report `VERCEL_ENV=preview`/`production` — so
|
|
228
|
+
* it opens the local dev server (which may serve over a non-loopback
|
|
229
|
+
* host) without ever opening a real deployment.
|
|
226
230
|
*
|
|
227
231
|
* Caveat: this helper assumes a sane edge in front of public origins.
|
|
228
232
|
* If you publish an origin that trusts an attacker-controlled `Host`
|
|
@@ -256,6 +260,13 @@ export interface VerifyVercelOidcOptions {
|
|
|
256
260
|
* accepted regardless of `subjects`. This guarantees the deployment's
|
|
257
261
|
* own runtime callers (subagent, internal fetches, etc.) authenticate
|
|
258
262
|
* without authors having to enumerate them.
|
|
263
|
+
* - Vercel OIDC tokens with an `external_sub` claim authenticate as
|
|
264
|
+
* `principalType: "user"` when they match the current
|
|
265
|
+
* `VERCEL_PROJECT_ID` (if set) and current `VERCEL_TARGET_ENV` /
|
|
266
|
+
* `VERCEL_ENV` (if set). Their `external_sub` becomes the Ash subject,
|
|
267
|
+
* `external_iss` or `connector_id` becomes the Ash issuer when present,
|
|
268
|
+
* and string-valued OIDC profile claims such as `name`, `picture`, and
|
|
269
|
+
* `email` are exposed as auth attributes.
|
|
259
270
|
* - Tokens from other Vercel projects are accepted **only** when their
|
|
260
271
|
* `sub` matches one of the supplied {@link VerifyVercelOidcOptions.subjects}
|
|
261
272
|
* patterns.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{decodeJwt}from"#compiled/jose/index.js";import{authenticateHttpBasicStrategy}from"#runtime/governance/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#runtime/governance/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#runtime/governance/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#runtime/governance/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#runtime/governance/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#runtime/governance/network/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let r=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return r.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(r.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtHmacStrategy({strategy:{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}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtEcdsaStrategy({strategy:{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}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){return e===null||e.length===0?{kind:`not-authenticated`}:await authenticateOidcStrategy({strategy:{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}},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?!1: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}="${escapeChallengeValue(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeChallengeValue(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];for(let t of n){let n=await t(e);if(n)return n}return createUnauthorizedResponse({challenges:[{scheme:`Bearer`}]})}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return e=>isLoopbackRequest(e)?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}const LOOPBACK_HOSTNAMES=new Set([`localhost`,`[::1]`]),LOOPBACK_IPV4_PREFIX=/^127\./;function isLoopbackRequest(e){let t;try{t=new URL(e.url).hostname}catch{return!1}return!!(LOOPBACK_HOSTNAMES.has(t)||LOOPBACK_IPV4_PREFIX.test(t)||t.endsWith(`.localhost`))}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
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{decodeJwt}from"#compiled/jose/index.js";import{authenticateHttpBasicStrategy}from"#runtime/governance/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#runtime/governance/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#runtime/governance/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#runtime/governance/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#runtime/governance/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#runtime/governance/network/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let r=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return r.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(r.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtHmacStrategy({strategy:{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}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtEcdsaStrategy({strategy:{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}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){return e===null||e.length===0?{kind:`not-authenticated`}:await authenticateOidcStrategy({strategy:{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}},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?!1: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}="${escapeChallengeValue(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeChallengeValue(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];for(let t of n){let n=await t(e);if(n)return n}return createUnauthorizedResponse({challenges:[{scheme:`Bearer`}]})}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return e=>process.env.VERCEL&&process.env.VERCEL_ENV===`development`||isLoopbackRequest(e)?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}const LOOPBACK_HOSTNAMES=new Set([`localhost`,`[::1]`]),LOOPBACK_IPV4_PREFIX=/^127\./;function isLoopbackRequest(e){let t;try{t=new URL(e.url).hostname}catch{return!1}return!!(LOOPBACK_HOSTNAMES.has(t)||LOOPBACK_IPV4_PREFIX.test(t)||t.endsWith(`.localhost`))}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(!n.issuer.startsWith(`https://oidc.vercel.com/`))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};let r=await runOidcVerification(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,issuer:n.issuer,subjects:t.subjects??[]});return r.kind===`authenticated`?(vercelOidcLog.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:r.principal.principalType,subject:r.principal.subject}),{ok:!0,sessionAuth:createRuntimeSessionAuthContext(r.principal)}):(vercelOidcLog.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:r.kind,subjectsConfigured:(t.subjects??[]).length>0,...r.kind===`misconfigured`?{detail:r.message}:{}}),{ok:!1})}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 async t=>{let n=await verifyVercelOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function httpBasic(e){return t=>{let n=verifyHttpBasic(t.headers.get(`authorization`),e);return n.ok?n.sessionAuth:null}}function jwtHmac(e){return async t=>{let n=await verifyJwtHmac(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function jwtEcdsa(e){return async t=>{let n=await verifyJwtEcdsa(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function oidc(e){return async t=>{let n=await verifyOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function decodeUnverifiedJwtClaims(e){let n;try{n=decodeJwt(e)}catch{return null}return typeof n.iss!=`string`||n.iss.length===0?null:{audiences:typeof n.aud==`string`?[n.aud]:Array.isArray(n.aud)?n.aud.filter(e=>typeof e==`string`):[],issuer:n.iss}}export{createIpAllowList,createUnauthorizedResponse,extractBearerToken,httpBasic,isIpAllowed,jwtEcdsa,jwtHmac,localDev,none,oidc,routeAuth,vercelOidc,vercelSubject,verifyHttpBasic,verifyJwtEcdsa,verifyJwtHmac,verifyOidc,verifyVercelOidc};
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* ```ts
|
|
9
|
-
* import { defineState
|
|
9
|
+
* import { defineState } from "experimental-ash/context";
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
|
-
export {
|
|
12
|
+
export type { Session, SessionAuth, SessionAuthContext, SessionParent, SessionTurn, } from "#context/accessors.js";
|
|
13
13
|
export { defineState, type StateHandle } from "#public/definitions/state.js";
|
|
14
|
+
export type { AshCallbackContext } from "#public/definitions/callback-context.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{defineState}from"#public/definitions/state.js";export{defineState};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SkillHandle } from "#execution/skills/types.js";
|
|
2
|
+
import type { SandboxSession } from "#shared/sandbox-session.js";
|
|
3
|
+
import type { SessionAuth, SessionParent, SessionTurn } from "#context/keys.js";
|
|
4
|
+
export type { SessionAuth, SessionParent, SessionTurn };
|
|
5
|
+
/**
|
|
6
|
+
* Shared runtime context available to all authored callbacks that run
|
|
7
|
+
* inside the ALS-scoped harness step (tools, hooks, channel events).
|
|
8
|
+
*
|
|
9
|
+
* Non-ALS callbacks (schedule `run`, sandbox `bootstrap`/`onSession`,
|
|
10
|
+
* instrumentation `setup`) do not receive this context — they get
|
|
11
|
+
* domain-specific arguments instead.
|
|
12
|
+
*/
|
|
13
|
+
export interface AshCallbackContext {
|
|
14
|
+
readonly session: {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly auth: SessionAuth;
|
|
17
|
+
readonly turn: SessionTurn;
|
|
18
|
+
readonly parent?: SessionParent;
|
|
19
|
+
};
|
|
20
|
+
getSandbox(): Promise<SandboxSession>;
|
|
21
|
+
getSkill(identifier: string): SkillHandle;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import type { ModelMessage } from "ai";
|
|
2
|
-
import type { ContextAccessor } from "../../context/key.js";
|
|
3
2
|
import type { HandleMessageStreamEvent } from "../../protocol/message.js";
|
|
3
|
+
import type { AshCallbackContext } from "./callback-context.js";
|
|
4
4
|
import type { NamedSkillDefinition } from "./skill.js";
|
|
5
5
|
/**
|
|
6
6
|
* Context passed to every hook handler.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* `
|
|
10
|
-
* surface deliberately introduces no parallel state-patch channel — one
|
|
11
|
-
* `AshContext`, one set of keys, one place to look when debugging.
|
|
8
|
+
* Extends {@link AshCallbackContext} with agent and channel metadata.
|
|
9
|
+
* `ctx` is always the last argument.
|
|
12
10
|
*/
|
|
13
|
-
export interface HookContext {
|
|
11
|
+
export interface HookContext extends AshCallbackContext {
|
|
14
12
|
readonly agent: {
|
|
15
13
|
readonly name: string;
|
|
16
14
|
readonly nodeId?: string;
|
|
@@ -19,27 +17,6 @@ export interface HookContext {
|
|
|
19
17
|
readonly kind?: string;
|
|
20
18
|
readonly continuationToken?: string;
|
|
21
19
|
};
|
|
22
|
-
readonly session: {
|
|
23
|
-
readonly sessionId: string;
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Read/write access to durable and virtual context keys. Same accessor
|
|
27
|
-
* tools, providers, and channels use.
|
|
28
|
-
*/
|
|
29
|
-
readonly ash: ContextAccessor;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Input passed to every lifecycle hook handler
|
|
33
|
-
* (`lifecycle.session`, `lifecycle.turn`).
|
|
34
|
-
*/
|
|
35
|
-
export interface LifecycleHookInput {
|
|
36
|
-
readonly session: {
|
|
37
|
-
readonly sessionId: string;
|
|
38
|
-
};
|
|
39
|
-
readonly turn: {
|
|
40
|
-
readonly sequence: number;
|
|
41
|
-
readonly turnId: string;
|
|
42
|
-
};
|
|
43
20
|
}
|
|
44
21
|
/**
|
|
45
22
|
* Result returned by a lifecycle hook (`lifecycle.session` or
|
|
@@ -67,25 +44,14 @@ export interface LifecycleHookResult {
|
|
|
67
44
|
* Lifecycle hook signature shared by `lifecycle.session` and
|
|
68
45
|
* `lifecycle.turn`.
|
|
69
46
|
*
|
|
70
|
-
* `
|
|
71
|
-
*
|
|
72
|
-
* runs, so a thrown hook leaves the flag set and the chain does not
|
|
73
|
-
* retry on the next turn — the throw fails the session terminally
|
|
74
|
-
* (`session.failed`).
|
|
75
|
-
*
|
|
76
|
-
* `lifecycle.turn` runs once per fresh delivery (tool-loop continuations
|
|
77
|
-
* and runtime-action resumes do not re-fire it). A thrown hook fails the
|
|
78
|
-
* current turn (`turn.failed`) but the session keeps living.
|
|
47
|
+
* `ctx` is the sole argument — session identity, auth, turn info,
|
|
48
|
+
* agent metadata, and channel metadata are all on `ctx`.
|
|
79
49
|
*/
|
|
80
|
-
export type LifecycleHook = (
|
|
50
|
+
export type LifecycleHook = (ctx: HookContext) => void | LifecycleHookResult | Promise<void | LifecycleHookResult>;
|
|
81
51
|
/**
|
|
82
52
|
* Side-effect-only handler for one accepted runtime stream event.
|
|
83
53
|
*
|
|
84
|
-
*
|
|
85
|
-
* it to the durable stream; their return values are ignored. Errors
|
|
86
|
-
* propagate through the emit composer and fail the current turn
|
|
87
|
-
* (`turn.failed`). Authors who want belt-and-suspenders semantics
|
|
88
|
-
* wrap their body in `try`/`catch`.
|
|
54
|
+
* The typed event is the first argument, `ctx` is the last.
|
|
89
55
|
*/
|
|
90
56
|
export type StreamEventHook<TEvent> = (event: TEvent, ctx: HookContext) => void | Promise<void>;
|
|
91
57
|
/**
|
|
@@ -115,9 +81,6 @@ export type StreamEventHooks = {
|
|
|
115
81
|
* stream-event subscribers (under `events:`), or both. The structural
|
|
116
82
|
* split makes the contract explicit: `lifecycle:` can mutate the next
|
|
117
83
|
* model call's context; `events:` is observe-only.
|
|
118
|
-
*
|
|
119
|
-
* Filenames carry stable identity for diagnostics and ordering; they
|
|
120
|
-
* have no runtime semantics beyond identity.
|
|
121
84
|
*/
|
|
122
85
|
export interface HookDefinition {
|
|
123
86
|
readonly lifecycle?: LifecycleHooks;
|
|
@@ -127,8 +90,5 @@ export interface HookDefinition {
|
|
|
127
90
|
* Identity-with-types helper. Authors export
|
|
128
91
|
* `defineHook({ lifecycle: { session, turn }, events: { "session.started": … } })`
|
|
129
92
|
* and receive a typed {@link HookDefinition}.
|
|
130
|
-
*
|
|
131
|
-
* `defineHook` runs no side effects — it exists purely so authors get
|
|
132
|
-
* type checking and editor inference on the lifecycle and event keys.
|
|
133
93
|
*/
|
|
134
|
-
export declare function defineHook(definition:
|
|
94
|
+
export declare function defineHook<T extends HookDefinition>(definition: T): T;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Optional } from "#shared/optional.js";
|
|
2
2
|
import type { SandboxDefinition as SharedSandboxDefinition } from "#shared/sandbox-definition.js";
|
|
3
|
-
export type { SandboxCommandResult, SandboxProcess, SandboxReadBinaryFileOptions, SandboxReadFileOptions, SandboxReadTextFileOptions,
|
|
3
|
+
export type { SandboxCommandResult, SandboxProcess, SandboxReadBinaryFileOptions, SandboxReadFileOptions, SandboxReadTextFileOptions, SandboxRunOptions, SandboxSession, SandboxSpawnOptions, SandboxWriteBinaryFileOptions, SandboxWriteFileOptions, SandboxWriteTextFileOptions, } from "#shared/sandbox-session.js";
|
|
4
4
|
export type { SandboxBootstrapUseFn, SandboxSessionUseFn, SandboxBootstrapContext, SandboxSessionContext, } from "#shared/sandbox-definition.js";
|
|
5
5
|
export type SandboxDefinition<BO = Record<string, never>, SO = Record<string, never>> = Optional<SharedSandboxDefinition<BO, SO>, "backend">;
|
|
6
6
|
/**
|
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
|
|
2
2
|
import type { ModelMessage } from "ai";
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import type { PublicToolDefinitionWithExecuteFn } from "#shared/tool-definition.js";
|
|
3
|
+
import type { PublicToolDefinition } from "#shared/tool-definition.js";
|
|
4
|
+
import type { AshCallbackContext } from "#public/definitions/callback-context.js";
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Hooks run inside the same `AshContext` scope as the surrounding harness
|
|
10
|
-
* step, so they may read or mutate context state via {@link ctx}. The
|
|
11
|
-
* {@link session} is the harness session as it stands immediately after
|
|
12
|
-
* message-history compaction.
|
|
6
|
+
* Domain input passed to a tool's {@link ToolDefinition.onCompact} hook.
|
|
13
7
|
*/
|
|
14
|
-
export interface
|
|
15
|
-
readonly
|
|
16
|
-
readonly session: HarnessSession;
|
|
8
|
+
export interface CompactionInput {
|
|
9
|
+
readonly history: readonly ModelMessage[];
|
|
17
10
|
readonly signal: AbortSignal;
|
|
18
11
|
}
|
|
19
12
|
/**
|
|
@@ -85,6 +78,11 @@ export interface RetentionSummary {
|
|
|
85
78
|
* pure — no external I/O.
|
|
86
79
|
*/
|
|
87
80
|
export type ToolRetentionPolicy<TOutput = unknown> = "auto" | "keep" | ((output: TOutput) => RetentionSummary);
|
|
81
|
+
/**
|
|
82
|
+
* Authored tool context. Passed as the last argument to
|
|
83
|
+
* {@link ToolDefinition.execute}.
|
|
84
|
+
*/
|
|
85
|
+
export type ToolContext = AshCallbackContext;
|
|
88
86
|
/**
|
|
89
87
|
* Public tool definition authored in `agent/tools/*.ts`.
|
|
90
88
|
*
|
|
@@ -95,7 +93,8 @@ export type ToolRetentionPolicy<TOutput = unknown> = "auto" | "keep" | ((output:
|
|
|
95
93
|
* `get-weather`. Authored definitions do not carry a `name` field —
|
|
96
94
|
* identity is path-derived.
|
|
97
95
|
*/
|
|
98
|
-
export type ToolDefinition<TInput = unknown, TOutput = unknown> =
|
|
96
|
+
export type ToolDefinition<TInput = unknown, TOutput = unknown> = PublicToolDefinition<TInput> & {
|
|
97
|
+
execute(input: TInput, ctx: ToolContext): Promise<TOutput> | TOutput;
|
|
99
98
|
/**
|
|
100
99
|
* Optional per-tool approval gate. When set, the function's return value
|
|
101
100
|
* determines whether user approval is required before executing this tool.
|
|
@@ -133,7 +132,7 @@ export type ToolDefinition<TInput = unknown, TOutput = unknown> = PublicToolDefi
|
|
|
133
132
|
* Return `void` (or `{}`) for "no change". Errors fail the compaction
|
|
134
133
|
* step — do not swallow them.
|
|
135
134
|
*/
|
|
136
|
-
onCompact?(input:
|
|
135
|
+
onCompact?(input: CompactionInput, ctx: ToolContext): CompactionHookResult | Promise<CompactionHookResult> | void | Promise<void>;
|
|
137
136
|
};
|
|
138
137
|
/**
|
|
139
138
|
* Defines a tool configuration.
|
|
@@ -141,7 +140,7 @@ export type ToolDefinition<TInput = unknown, TOutput = unknown> = PublicToolDefi
|
|
|
141
140
|
export declare function defineTool<TSchema extends StandardJSONSchemaV1<unknown, unknown>, TOutput>(definition: {
|
|
142
141
|
description: ToolDefinition<unknown, unknown>["description"];
|
|
143
142
|
inputSchema: TSchema;
|
|
144
|
-
execute:
|
|
143
|
+
execute(input: StandardJSONSchemaV1.InferOutput<TSchema>, ctx: ToolContext): Promise<TOutput> | TOutput;
|
|
145
144
|
needsApproval?: ToolDefinition<unknown, unknown>["needsApproval"];
|
|
146
145
|
retentionPolicy?: ToolDefinition<unknown, TOutput>["retentionPolicy"];
|
|
147
146
|
toModelOutput?: ToolDefinition<unknown, TOutput>["toModelOutput"];
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
* authoring shape and {@link HookContext} for the runtime context every
|
|
7
7
|
* handler receives.
|
|
8
8
|
*/
|
|
9
|
-
export { type HookContext, type HookDefinition, type LifecycleHook, type
|
|
9
|
+
export { type HookContext, type HookDefinition, type LifecycleHook, type LifecycleHookResult, type LifecycleHooks, type StreamEventHook, type StreamEventHooks, defineHook, } from "../definitions/hook.js";
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Sandbox authoring helpers for `agent/sandbox.ts` (or
|
|
3
3
|
* `agent/sandbox/sandbox.ts` when paired with a `workspace/` folder).
|
|
4
4
|
*/
|
|
5
|
-
export {
|
|
6
|
-
export { defineSandbox, type SandboxBootstrapContext, type SandboxBootstrapUseFn, type SandboxCommandResult, type SandboxDefinition, type SandboxProcess, type SandboxReadBinaryFileOptions, type SandboxReadFileOptions, type SandboxReadTextFileOptions, type SandboxRunCommandOptions, type SandboxRunOptions, type SandboxSession, type SandboxSpawnOptions, type SandboxSessionContext, type SandboxSessionUseFn, type SandboxWriteBinaryFileOptions, type SandboxWriteFileOptions, type SandboxWriteTextFileOptions, } from "#public/definitions/sandbox.js";
|
|
5
|
+
export { defineSandbox, type SandboxBootstrapContext, type SandboxBootstrapUseFn, type SandboxCommandResult, type SandboxDefinition, type SandboxProcess, type SandboxReadBinaryFileOptions, type SandboxReadFileOptions, type SandboxReadTextFileOptions, type SandboxRunOptions, type SandboxSession, type SandboxSpawnOptions, type SandboxSessionContext, type SandboxSessionUseFn, type SandboxWriteBinaryFileOptions, type SandboxWriteFileOptions, type SandboxWriteTextFileOptions, } from "#public/definitions/sandbox.js";
|
|
7
6
|
export type { SandboxBackend, SandboxBackendCreateInput, SandboxBackendHandle, SandboxBackendPrewarmInput, SandboxBackendRuntimeContext, SandboxBackendSessionState, SandboxSeedFile, } from "#public/definitions/sandbox-backend.js";
|
|
8
7
|
export { SandboxTemplateNotProvisionedError } from "#public/definitions/sandbox-backend.js";
|
|
9
8
|
export { defaultBackend } from "#public/sandbox/backends/default.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";import{
|
|
1
|
+
import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";import{localBackend}from"#public/sandbox/backends/local.js";import{vercelBackend}from"#public/sandbox/backends/vercel.js";import{defineSandbox}from"#public/definitions/sandbox.js";import{defaultBackend}from"#public/sandbox/backends/default.js";export{SandboxTemplateNotProvisionedError,defaultBackend,defineSandbox,localBackend,vercelBackend};
|
|
@@ -6,9 +6,9 @@ import type { Sandbox as SdkSandbox, SandboxUpdateParams } from "#compiled/@verc
|
|
|
6
6
|
* session-create). Skipped on resume (`Sandbox.get`) since no create
|
|
7
7
|
* happens there.
|
|
8
8
|
*
|
|
9
|
-
* Framework-injected fields (`name`, `persistent`, `signal`)
|
|
10
|
-
* excluded — the framework owns those and overrides any
|
|
11
|
-
* values.
|
|
9
|
+
* Framework-injected fields (`name`, `onResume`, `persistent`, `signal`)
|
|
10
|
+
* are excluded — the framework owns those and overrides any
|
|
11
|
+
* author-supplied values.
|
|
12
12
|
*
|
|
13
13
|
* `source` is honored only on the template create at prewarm time, so
|
|
14
14
|
* an author-supplied snapshot, git revision, or tarball becomes the
|
|
@@ -20,7 +20,7 @@ import type { Sandbox as SdkSandbox, SandboxUpdateParams } from "#compiled/@verc
|
|
|
20
20
|
* snapshot, force a template rebuild (e.g. by changing the sandbox
|
|
21
21
|
* definition so its template key changes).
|
|
22
22
|
*/
|
|
23
|
-
export type VercelSandboxCreateOptions = Omit<NonNullable<Parameters<typeof SdkSandbox.create>[0]>, "name" | "persistent" | "signal">;
|
|
23
|
+
export type VercelSandboxCreateOptions = Omit<NonNullable<Parameters<typeof SdkSandbox.create>[0]>, "name" | "onResume" | "persistent" | "signal">;
|
|
24
24
|
/**
|
|
25
25
|
* Options accepted by the Vercel backend's `bootstrap({ use })` hook.
|
|
26
26
|
* Aliases the Vercel SDK's `SandboxUpdateParams` because bootstrap
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Skill authoring helpers and runtime accessors.
|
|
3
3
|
*/
|
|
4
|
-
export { getSkill } from "#context/accessors.js";
|
|
5
4
|
export type { SkillFile, SkillHandle } from "#execution/skills/types.js";
|
|
6
5
|
export { defineSkill, type NamedSkillDefinition, type SkillDefinition, type SkillFileContent, type SkillPackageDefinition, } from "#public/definitions/skill.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineSkill}from"#public/definitions/skill.js";
|
|
1
|
+
import{defineSkill}from"#public/definitions/skill.js";export{defineSkill};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WEB_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-search.js";import{BASH_TOOL_DEFINITION}from"#runtime/framework-tools/bash.js";import{GLOB_TOOL_DEFINITION}from"#runtime/framework-tools/glob.js";import{GREP_TOOL_DEFINITION}from"#runtime/framework-tools/grep.js";import{READ_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/read-file.js";import{SKILL_TOOL_DEFINITION}from"#runtime/framework-tools/skill.js";import{TODO_TOOL_DEFINITION}from"#runtime/framework-tools/todo.js";import{WEB_FETCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-fetch.js";import{WRITE_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/write-file.js";import{toPublicToolDefinition}from"#public/tools/internal.js";const bash=toPublicToolDefinition(BASH_TOOL_DEFINITION),glob=toPublicToolDefinition(GLOB_TOOL_DEFINITION),grep=toPublicToolDefinition(GREP_TOOL_DEFINITION),readFile=toPublicToolDefinition(READ_FILE_TOOL_DEFINITION),writeFile=toPublicToolDefinition(WRITE_FILE_TOOL_DEFINITION),webFetch=toPublicToolDefinition(WEB_FETCH_TOOL_DEFINITION),todo=toPublicToolDefinition(TODO_TOOL_DEFINITION),loadSkill=toPublicToolDefinition(SKILL_TOOL_DEFINITION),webSearch={description:WEB_SEARCH_TOOL_DEFINITION.description,inputSchema:{},execute(){throw Error(`web_search is provider-managed and has no local execute. Override with defineTool() to provide a custom implementation.`)}};export{bash,glob,grep,loadSkill,readFile,todo,webFetch,webSearch,writeFile};
|
|
1
|
+
import{WEB_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-search.js";import{BASH_TOOL_DEFINITION}from"#runtime/framework-tools/bash.js";import{GLOB_TOOL_DEFINITION}from"#runtime/framework-tools/glob.js";import{GREP_TOOL_DEFINITION}from"#runtime/framework-tools/grep.js";import{READ_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/read-file.js";import{SKILL_TOOL_DEFINITION}from"#runtime/framework-tools/skill.js";import{TODO_TOOL_DEFINITION}from"#runtime/framework-tools/todo.js";import{WEB_FETCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-fetch.js";import{WRITE_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/write-file.js";import{toPublicToolDefinition}from"#public/tools/internal.js";const bash=toPublicToolDefinition(BASH_TOOL_DEFINITION),glob=toPublicToolDefinition(GLOB_TOOL_DEFINITION),grep=toPublicToolDefinition(GREP_TOOL_DEFINITION),readFile=toPublicToolDefinition(READ_FILE_TOOL_DEFINITION),writeFile=toPublicToolDefinition(WRITE_FILE_TOOL_DEFINITION),webFetch=toPublicToolDefinition(WEB_FETCH_TOOL_DEFINITION),todo=toPublicToolDefinition(TODO_TOOL_DEFINITION),loadSkill=toPublicToolDefinition(SKILL_TOOL_DEFINITION),webSearch={description:WEB_SEARCH_TOOL_DEFINITION.description,inputSchema:{},execute(e){throw Error(`web_search is provider-managed and has no local execute. Override with defineTool() to provide a custom implementation.`)}};export{bash,glob,grep,loadSkill,readFile,todo,webFetch,webSearch,writeFile};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{BASH_INPUT_SCHEMA}from"#runtime/framework-tools/bash.js";import{executeBashOnSandbox}from"#execution/sandbox/bash-tool.js";function defineBashTool(t={}){return{description:t.description??`Execute a shell command in the workspace sandbox.`,async execute(e){return executeBashOnSandbox(e)},inputSchema:BASH_INPUT_SCHEMA}}export{defineBashTool};
|
|
1
|
+
import{BASH_INPUT_SCHEMA}from"#runtime/framework-tools/bash.js";import{executeBashOnSandbox}from"#execution/sandbox/bash-tool.js";function defineBashTool(t={}){return{description:t.description??`Execute a shell command in the workspace sandbox.`,async execute(e,t){return executeBashOnSandbox(await t.getSandbox(),e)},inputSchema:BASH_INPUT_SCHEMA}}export{defineBashTool};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{GLOB_INPUT_SCHEMA}from"#runtime/framework-tools/glob.js";import{executeGlobOnSandbox}from"#execution/sandbox/glob-tool.js";function defineGlobTool(t={}){return{description:t.description??`Search for files by glob pattern in the workspace sandbox.`,async execute(e){return executeGlobOnSandbox(e)},inputSchema:GLOB_INPUT_SCHEMA}}export{defineGlobTool};
|
|
1
|
+
import{GLOB_INPUT_SCHEMA}from"#runtime/framework-tools/glob.js";import{executeGlobOnSandbox}from"#execution/sandbox/glob-tool.js";function defineGlobTool(t={}){return{description:t.description??`Search for files by glob pattern in the workspace sandbox.`,async execute(e,t){return executeGlobOnSandbox(await t.getSandbox(),e)},inputSchema:GLOB_INPUT_SCHEMA}}export{defineGlobTool};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{GREP_INPUT_SCHEMA}from"#runtime/framework-tools/grep.js";import{executeGrepOnSandbox}from"#execution/sandbox/grep-tool.js";function defineGrepTool(t={}){return{description:t.description??`Search file contents by pattern in the workspace sandbox.`,async execute(e){return executeGrepOnSandbox(e)},inputSchema:GREP_INPUT_SCHEMA}}export{defineGrepTool};
|
|
1
|
+
import{GREP_INPUT_SCHEMA}from"#runtime/framework-tools/grep.js";import{executeGrepOnSandbox}from"#execution/sandbox/grep-tool.js";function defineGrepTool(t={}){return{description:t.description??`Search file contents by pattern in the workspace sandbox.`,async execute(e,t){return executeGrepOnSandbox(await t.getSandbox(),e)},inputSchema:GREP_INPUT_SCHEMA}}export{defineGrepTool};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{clearReadFileState}from"#runtime/framework-tools/file-state.js";import{READ_FILE_INPUT_SCHEMA}from"#runtime/framework-tools/read-file.js";import{executeReadFileOnSandbox}from"#execution/sandbox/read-file-tool.js";function defineReadFileTool(n={}){let r=n.onCompact??((
|
|
1
|
+
import{clearReadFileState}from"#runtime/framework-tools/file-state.js";import{READ_FILE_INPUT_SCHEMA}from"#runtime/framework-tools/read-file.js";import{executeReadFileOnSandbox}from"#execution/sandbox/read-file-tool.js";function defineReadFileTool(n={}){let r=n.onCompact??(()=>(clearReadFileState(),{}));return{description:n.description??`Read a file from the workspace sandbox.`,async execute(e,t){return executeReadFileOnSandbox(await t.getSandbox(),e)},inputSchema:READ_FILE_INPUT_SCHEMA,onCompact:r}}export{defineReadFileTool};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WRITE_FILE_INPUT_SCHEMA}from"#runtime/framework-tools/write-file.js";import{executeWriteFileOnSandbox}from"#execution/sandbox/write-file-tool.js";function defineWriteFileTool(t={}){return{description:t.description??`Write a file to the workspace sandbox.`,async execute(e){return executeWriteFileOnSandbox(e)},inputSchema:WRITE_FILE_INPUT_SCHEMA}}export{defineWriteFileTool};
|
|
1
|
+
import{WRITE_FILE_INPUT_SCHEMA}from"#runtime/framework-tools/write-file.js";import{executeWriteFileOnSandbox}from"#execution/sandbox/write-file-tool.js";function defineWriteFileTool(t={}){return{description:t.description??`Write a file to the workspace sandbox.`,async execute(e,t){return executeWriteFileOnSandbox(await t.getSandbox(),e)},inputSchema:WRITE_FILE_INPUT_SCHEMA}}export{defineWriteFileTool};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool authoring helpers for `agent/tools/*.ts` files.
|
|
3
3
|
*/
|
|
4
|
-
export { type
|
|
4
|
+
export { type CompactionInput, type CompactionHookResult, type DisabledToolSentinel, defineTool, disableTool, isDisabledToolSentinel, type NeedsApprovalContext, type RetentionSummary, type ToolDefinition, type ToolContext, type ToolModelOutput, type ToolRetentionPolicy, } from "#public/definitions/tool.js";
|
|
5
|
+
export { type AshCallbackContext } from "#public/definitions/callback-context.js";
|
|
5
6
|
export { toolResultFrom, type MatchedConnectionResult, type MatchedToolResult, type ToolResultFromFn, } from "#public/tool-result-narrowing.js";
|
|
6
7
|
export { type DefineBashToolInput, defineBashTool } from "#public/tools/define-bash-tool.js";
|
|
7
8
|
export { type DefineGlobToolInput, defineGlobTool } from "#public/tools/define-glob-tool.js";
|
|
@@ -4,5 +4,9 @@ import type { ToolDefinition } from "#public/definitions/tool.js";
|
|
|
4
4
|
* Converter that strips internal identity fields from a framework
|
|
5
5
|
* {@link ResolvedToolDefinition} so it can be re-exported as a public
|
|
6
6
|
* {@link ToolDefinition}.
|
|
7
|
+
*
|
|
8
|
+
* Framework tools have the internal `(input) => output` signature.
|
|
9
|
+
* The public {@link ToolDefinition.execute} expects `(input, ctx)`.
|
|
10
|
+
* This wrapper bridges the gap — `ctx` is trailing and omitted.
|
|
7
11
|
*/
|
|
8
12
|
export declare function toPublicToolDefinition(definition: ResolvedToolDefinition): ToolDefinition;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function toPublicToolDefinition(e){if(!e.execute)throw Error(`Tool "${e.name}" is client-side and cannot be re-exported publicly.`);let t=e.execute,n=e.inputSchema,r={description:e.description,execute:t,inputSchema:n??{}};return e.needsApproval!==void 0&&(r.needsApproval=e.needsApproval),e.onCompact!==void 0&&(r.onCompact=e.onCompact),r}export{toPublicToolDefinition};
|
|
1
|
+
function toPublicToolDefinition(e){if(!e.execute)throw Error(`Tool "${e.name}" is client-side and cannot be re-exported publicly.`);let t=e.execute,n=e.inputSchema,r={description:e.description,execute:e=>t(e),inputSchema:n??{}};return e.needsApproval!==void 0&&(r.needsApproval=e.needsApproval),e.onCompact!==void 0&&(r.onCompact=e.onCompact),r}export{toPublicToolDefinition};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{executeBashOnSandbox}from"#execution/sandbox/bash-tool.js";const BASH_INPUT_SCHEMA={additionalProperties:!1,properties:{command:{description:`The shell command to execute.`,type:`string`}},required:[`command`],type:`object`};async function executeBash(e){return executeBashOnSandbox(e)}const BASH_TOOL_DEFINITION={description:`Execute a shell command in the shared workspace environment.`,execute:executeBash,inputSchema:BASH_INPUT_SCHEMA,logicalPath:`ash:framework/bash`,name:`bash`,sourceId:`ash:bash-tool`,sourceKind:`module`};export{BASH_INPUT_SCHEMA,BASH_TOOL_DEFINITION};
|
|
1
|
+
import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeBashOnSandbox}from"#execution/sandbox/bash-tool.js";const BASH_INPUT_SCHEMA={additionalProperties:!1,properties:{command:{description:`The shell command to execute.`,type:`string`}},required:[`command`],type:`object`};async function executeBash(e){return executeBashOnSandbox(await requireSandboxSession(),e)}const BASH_TOOL_DEFINITION={description:`Execute a shell command in the shared workspace environment.`,execute:executeBash,inputSchema:BASH_INPUT_SCHEMA,logicalPath:`ash:framework/bash`,name:`bash`,sourceId:`ash:bash-tool`,sourceKind:`module`};export{BASH_INPUT_SCHEMA,BASH_TOOL_DEFINITION};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{requestCodeModeInterrupt}from"../../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.
|
|
1
|
+
import{requestCodeModeInterrupt}from"../../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/host-interrupt.js";import"../../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/index.js";import{createLogger}from"#internal/logging.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,isCodeModeToolExecutionOptions,readCodeModeConnectionAuthContext,toCodeModeConnectionAuthArgs}from"#runtime/framework-tools/code-mode-connection-auth.js";import{qualifiedConnectionToolName}from"#runtime/framework-tools/connection-tools.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";const logger=createLogger(`framework.connection-search`),ConnectionRegistryKey=new ContextKey(`ash.connectionRegistry`),DiscoveredConnectionToolsKey=new ContextKey(`ash.discoveredConnectionTools`),CONNECTION_SEARCH_TOOL_DEFINITION={description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. linear__list_issues) in your next response.`,execute:async(e,t)=>executeConnectionSearch(e,{codeMode:isCodeModeToolExecutionOptions(t),codeModeInterrupt:readCodeModeConnectionAuthContext(t)}),inputSchema:{additionalProperties:!1,properties:{connection:{description:`Optional: limit search to a specific connection name.`,type:`string`},limit:{description:`Max results to return. Default 10.`,type:`number`},keywords:{description:`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`,type:`string`}},required:[`keywords`],type:`object`},logicalPath:`ash:framework/connection-search`,name:`connection_search`,onCompact(){return loadContext().set(DiscoveredConnectionToolsKey,{byConnection:{}}),{}},sourceId:`ash:connection-search-tool`,sourceKind:`module`};async function executeConnectionSearch(t,r){let i=loadContext(),c=i.get(ConnectionRegistryKey);if(c===void 0)return[];await completePendingAuthorizations(c);let l=t.limit??10,u=tokenize(t.keywords),d=[],f=[],p=t.connection!==void 0&&t.connection!==``?c.getConnections().filter(e=>e.connectionName===t.connection):c.getConnections(),m={...i.get(DiscoveredConnectionToolsKey)?.byConnection},h=[];for(let n of p){if(r?.codeModeInterrupt?.resolution.status===`failed`&&r.codeModeInterrupt.payload.connectionName===n.connectionName){let{resolution:e}=r.codeModeInterrupt;f.push({connection:n.connectionName,description:n.description,error:e.reason,needsAuthorization:e.retryable});continue}let i;try{i=await c.getClient(n.connectionName).getToolMetadata()}catch(i){if(isConnectionAuthorizationRequiredError(i)){let i=resolveInteractiveAuth(c,n.connectionName);if(i&&r?.codeMode===!0&&requestCodeModeInterrupt({args:toCodeModeConnectionAuthArgs(t),connectionName:n.connectionName,kind:CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,toolName:`connection_search`}),i){let e=getHookUrl(n.connectionName);if(e){let t=resolveConnectionPrincipal(n.connectionName,i);try{let{challenge:r,state:a}=await i.startAuthorization({callbackUrl:e,connection:{url:n.url??``},principal:t});h.push({name:n.connectionName,challenge:r,hookUrl:e,state:a})}catch(e){logger.warn(`startAuthorization failed`,{connection:n.connectionName,error:e instanceof Error?e:Error(String(e))})}}}f.push({connection:n.connectionName,description:n.description,needsAuthorization:!0});continue}if(isConnectionAuthorizationFailedError(i)){logger.warn(`connection authorization failed`,{connection:n.connectionName,reason:i.reason,retryable:i.retryable,error:i}),f.push({connection:n.connectionName,description:n.description,error:`Authorization failed for ${n.connectionName}: ${i.message}`});continue}let o=i instanceof Error?i.message:`unknown error`;logger.warn(`failed to load connection tools`,{connection:n.connectionName,error:i instanceof Error?i:Error(o)}),f.push({connection:n.connectionName,description:n.description,error:`Failed to load tools for "${n.connectionName}": ${o}`});continue}m[n.connectionName]=i;for(let e of i){let t=scoreMatch(u,e);t>0&&d.push({item:{connection:n.connectionName,description:e.description,inputSchema:e.inputSchema,qualifiedName:qualifiedConnectionToolName(n.connectionName,e.name),tool:e.name},score:t})}}if(i.set(DiscoveredConnectionToolsKey,{byConnection:m}),h.length>0)return requestAuthorization(h);d.sort((e,t)=>t.score-e.score);let g=d.slice(0,l).map(e=>e.item);return g.length>0?[...g,...f]:p.map(e=>f.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}async function completePendingAuthorizations(e){let t=loadContext();for(let n of e.getConnections()){let r=getAuthorizationResult(n.connectionName);if(!r)continue;let a=resolveInteractiveAuth(e,n.connectionName);if(!a)continue;let o=resolveConnectionPrincipal(n.connectionName,a),s=await a.completeAuthorization({callbackUrl:r.hookUrl,connection:{url:n.url??``},principal:o,request:r.callback,state:r.state});writeCachedToken(t,n.connectionName,principalKey(o),s)}}function tokenize(e){return e.toLowerCase().split(/[\s_\-./]+/).filter(e=>e.length>1)}function scoreMatch(e,t){let n=tokenize(t.name),r=tokenize(t.description),i=0;for(let t of e){for(let e of n)(e.includes(t)||t.includes(e))&&(i+=3);for(let e of r)(e.includes(t)||t.includes(e))&&(i+=1)}return i}function resolveInteractiveAuth(e,t){let n=e.getConnections().find(e=>e.connectionName===t);if(n?.authorization&&supportsInteractiveAuthorization(n.authorization))return n.authorization}export{CONNECTION_SEARCH_TOOL_DEFINITION,ConnectionRegistryKey,DiscoveredConnectionToolsKey,executeConnectionSearch,scoreMatch,tokenize};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{requestCodeModeInterrupt}from"../../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.
|
|
1
|
+
import{requestCodeModeInterrupt}from"../../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/host-interrupt.js";import"../../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/index.js";import{isObject}from"#shared/guards.js";import{loadContext}from"#context/container.js";import"#runtime/framework-tools/connection-search.js";import{jsonSchema}from"ai";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,toCodeModeConnectionAuthArgs}from"#runtime/framework-tools/code-mode-connection-auth.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";function qualifiedConnectionToolName(e,t){return`${e}__${t}`}async function resolveConnectionToolsFromState(e,n,r){let i={};for(let[a,o]of Object.entries(n.byConnection)){let n=r.authMode===`code-mode`&&r.codeModeMetadataOnlyConnectionNames?.has(a)===!0,s=n?void 0:await e.getClient(a).getTools(),c=e.getConnectionApproval(a);for(let l of o){let o=qualifiedConnectionToolName(a,l.name);if(r.existingToolNames?.has(o))continue;let u=s?.[l.name]??(n?createMetadataOnlyTool(l,o):void 0);if(u===void 0)continue;let d=!n&&c!==void 0?async e=>c({approvedTools:r.approvedTools??new Set,toolInput:isObject(e)?e:void 0,toolName:o}):void 0,f=e.getConnections().find(e=>e.connectionName===a),p=u.execute,m=r.authMode===`code-mode`?wrapCodeModeConnectionToolExecute({connectionDefinition:f,connectionName:a,originalExecute:p,toolName:l.name}):wrapConnectionToolExecute({connectionDefinition:f,connectionName:a,originalExecute:p,toolName:l.name});i[o]={...u,execute:m,needsApproval:d}}}return i}function createMetadataOnlyTool(e,t){return{description:e.description,execute:async()=>{throw Error(`Connection tool "${t}" cannot execute without authorization.`)},inputSchema:jsonSchema(e.inputSchema)}}function wrapCodeModeConnectionToolExecute(t){let{connectionDefinition:r,connectionName:a,originalExecute:o,toolName:m}=t;if(o===void 0)return;let h=r?.authorization&&supportsInteractiveAuthorization(r.authorization)?r.authorization:void 0,g=r?.url??``;return async(t,r)=>{if(h){let e=getAuthorizationResult(a);if(e){let t=loadContext(),r=resolveConnectionPrincipal(a,h),i=await h.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:g},principal:r,request:e.callback,state:e.state});writeCachedToken(t,a,principalKey(r),i)}}try{return await o(t,r)}catch(n){if(!isConnectionAuthorizationRequiredError(n)||!h)throw n;requestCodeModeInterrupt({args:toCodeModeConnectionAuthArgs(t),connectionName:a,kind:CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,toolName:m})}}}function wrapConnectionToolExecute(e){let{connectionDefinition:t,connectionName:r,originalExecute:s}=e;if(s===void 0)return;let c=t?.authorization&&supportsInteractiveAuthorization(t.authorization)?t.authorization:void 0,m=t?.url??``;return async(e,t)=>{if(c){let e=getAuthorizationResult(r);if(e){let t=loadContext(),i=resolveConnectionPrincipal(r,c),a=await c.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:m},principal:i,request:e.callback,state:e.state});writeCachedToken(t,r,principalKey(i),a)}}try{return await s(e,t)}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!c)throw e;let t=getHookUrl(r);if(!t)throw e;let n=resolveConnectionPrincipal(r,c),{challenge:i,state:s}=await c.startAuthorization({callbackUrl:t,connection:{url:m},principal:n});return requestAuthorization([{name:r,challenge:i,hookUrl:t,state:s}])}}}export{qualifiedConnectionToolName,resolveConnectionToolsFromState,wrapCodeModeConnectionToolExecute,wrapConnectionToolExecute};
|