experimental-ash 0.13.0 → 0.14.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.
Files changed (28) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/docs/public/channels/README.md +23 -0
  3. package/dist/docs/public/channels/twilio.md +179 -0
  4. package/dist/docs/public/typescript-api.md +19 -0
  5. package/dist/src/chunks/{dev-authored-source-watcher-DA6pewzf.js → dev-authored-source-watcher-VTMbiIPX.js} +1 -1
  6. package/dist/src/chunks/{host-D_hajFPO.js → host-T9Qm64N8.js} +2 -2
  7. package/dist/src/chunks/{paths-BYaK6-t0.js → paths-Bkj-KERk.js} +1 -1
  8. package/dist/src/chunks/{prewarm-QPhmJIsB.js → prewarm-jPrr-S6_.js} +1 -1
  9. package/dist/src/cli/commands/info.js +1 -1
  10. package/dist/src/cli/run.js +1 -1
  11. package/dist/src/evals/cli/eval.js +1 -1
  12. package/dist/src/internal/application/package.js +1 -1
  13. package/dist/src/internal/authored-definition/schema-backed.js +12 -5
  14. package/dist/src/public/channels/twilio/api.d.ts +61 -0
  15. package/dist/src/public/channels/twilio/api.js +92 -0
  16. package/dist/src/public/channels/twilio/defaults.d.ts +17 -0
  17. package/dist/src/public/channels/twilio/defaults.js +69 -0
  18. package/dist/src/public/channels/twilio/inbound.d.ts +59 -0
  19. package/dist/src/public/channels/twilio/inbound.js +123 -0
  20. package/dist/src/public/channels/twilio/index.d.ts +5 -0
  21. package/dist/src/public/channels/twilio/index.js +4 -0
  22. package/dist/src/public/channels/twilio/twilioChannel.d.ts +179 -0
  23. package/dist/src/public/channels/twilio/twilioChannel.js +319 -0
  24. package/dist/src/public/channels/twilio/twiml.d.ts +37 -0
  25. package/dist/src/public/channels/twilio/twiml.js +58 -0
  26. package/dist/src/public/channels/twilio/verify.d.ts +43 -0
  27. package/dist/src/public/channels/twilio/verify.js +73 -0
  28. package/package.json +6 -1
@@ -4,7 +4,7 @@ import{i as e}from"./chunk-8L7ocgPr.js";import{t}from"./gray-matter-BxS7ZG-J.js"
4
4
  `)}function Or(e){return{modules:kr(e.manifest).sort((e,t)=>e.sourceId.localeCompare(t.sourceId)).map(t=>({bindingName:e.nextBindingName(),importSpecifier:Ar({fromDirectory:e.moduleMapDirectory,importSpecifierStyle:e.importSpecifierStyle,targetPath:Pr(e.agentRoot,t.logicalPath)}),sourceId:t.sourceId})),nodeId:e.nodeId}}function kr(e){let t=new Map;e.config.source!==void 0&&t.set(e.config.source.sourceId,e.config.source),e.config.model.source!==void 0&&t.set(e.config.model.source.sourceId,e.config.model.source);for(let n of e.channels)n.kind!==`disabled`&&t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.connections)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.tools)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.hooks)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});return e.sandbox!==null&&t.set(e.sandbox.sourceId,{exportName:e.sandbox.exportName,sourceKind:`module`,logicalPath:e.sandbox.logicalPath,sourceId:e.sandbox.sourceId}),[...t.values()]}function Ar(e){if(e.importSpecifierStyle===`absolute`)return Sr(Ir(e.targetPath));let t=Fr(e.fromDirectory,e.targetPath);return t.startsWith(`.`)?t:`./${t}`}function jr(e){return Mr([{key:`nodes`,value:Mr(e.map(e=>({key:e.nodeId,value:Mr([{key:`modules`,value:Mr(e.modules.map(e=>({key:e.sourceId,value:e.bindingName})))}],3)})))}],0)}function Mr(e,t=1){if(e.length===0)return`Object.freeze({})`;let n=` `.repeat(t),r=` `.repeat(t+1);return[`Object.freeze({`,e.map(e=>`${r}${JSON.stringify(e.key)}: ${e.value.replaceAll(`
5
5
  `,`\n${r}`)}`).join(`,
6
6
  `),`${n}})`].join(`
7
- `)}function Nr(e){let t=R(e);return t.segments.length===0?t.root.length===0?`.`:t.root:Lr(t.root,t.segments.slice(0,-1))}function Pr(e,t){let n=R(e),r=R(t);return r.root.length>0?Lr(r.root,r.segments):Lr(n.root,[...n.segments,...r.segments])}function Fr(e,t){let n=R(e),r=R(t);if(n.root!==r.root)return Ir(t);let i=0;for(;i<n.segments.length&&i<r.segments.length&&n.segments[i]===r.segments[i];)i+=1;let a=[...Array.from({length:n.segments.length-i},()=>`..`),...r.segments.slice(i)];return a.length===0?`.`:a.join(`/`)}function Ir(e){let t=R(e);return Lr(t.root,t.segments)}function R(e){let t=e.replaceAll(`\\`,`/`),n=``,r=t,i=t.match(/^[A-Za-z]:/);i===null?t.startsWith(`/`)&&(n=`/`,r=t.slice(1)):(n=i[0],r=t.slice(n.length),r.startsWith(`/`)&&(n=`${n}/`,r=r.slice(1)));let a=[];for(let e of r.split(`/`))if(!(e.length===0||e===`.`)){if(e===`..`){if(a.length>0&&a[a.length-1]!==`..`){a.pop();continue}n.length===0&&a.push(e);continue}a.push(e)}return{root:n,segments:a}}function Lr(e,t){return e===`/`?t.length===0?`/`:`/${t.join(`/`)}`:e.endsWith(`/`)?t.length===0?e:`${e}${t.join(`/`)}`:e.length>0?t.length===0?e:`${e}/${t.join(`/`)}`:t.length===0?`.`:t.join(`/`)}const Rr=`ash-model-catalog-cache`,zr=b.object({provider:b.string().min(1),providerModelId:b.string().min(1),contextWindowTokens:b.number().int().nonnegative().optional(),maxOutputTokens:b.number().int().nonnegative().optional()}).passthrough(),Br=b.object({slug:b.string().min(1),providers:b.array(zr).min(1)}).passthrough(),Vr=b.object({models:b.array(Br),providerAliases:b.record(b.string(),b.string())}).passthrough();b.object({contextWindowTokens:b.number().int().positive(),maxOutputTokens:b.number().int().positive().optional()}).strict();const Hr=b.object({fetchedAt:b.string(),kind:b.literal(Rr),models:b.array(Br),providerAliases:b.record(b.string(),b.string()),version:b.literal(2)}).strict(),Ur=new Map([[`anthropic/claude-opus-4.7`,{contextWindowTokens:2e5,maxOutputTokens:32e3}],[`openai/gpt-5.4`,{contextWindowTokens:4e5,maxOutputTokens:128e3}],[`openai/gpt-5.4-mini`,{contextWindowTokens:4e5,maxOutputTokens:128e3}]]);function Wr(e){return S(e,`.ash`,`cache`,`model-catalog.json`)}function Gr(e){let t=null,n=null,r=null,i=async()=>(t??=qr(e),await t),a=async()=>{if(n!==null)throw n;if(r!==null)return await r;r=Kr(e).then(e=>(t=Promise.resolve(e),e));try{return await r}catch(e){throw n=e,e}},o=async()=>{let e=await i();if(e!==null&&Xr(e))return e;try{return await a()}catch{return e===null?null:e}};return{async getModelLimits(e){let t=Zr(e),n=await o();if(n!==null){let e=Jr(n.models,t);if(e)for(let t of e.providers){let e=Yr(t);if(e!==null)return e}}return Ur.get(t)??null},async getByProviderModelId(e,t){let n=await o();if(n===null)return null;let r=e.split(`.`)[0],i=n.providerAliases[r]??r,a=Zr(t);for(let e of n.models)for(let t of e.providers)if(t.provider===i&&Zr(t.providerModelId)===a){let n=Yr(t);if(n!==null)return{slug:e.slug,limits:n}}return null}}}async function Kr(e){let t=await fetch(`https://ai-gateway.vercel.sh/v1/models/catalog`);if(!t.ok)throw Error(`AI Gateway model catalog request failed with HTTP ${t.status} ${t.statusText}.`);let n=Vr.safeParse(await t.json());if(!n.success)throw Error(`AI Gateway model catalog response did not match the expected schema.`);let r={fetchedAt:new Date().toISOString(),kind:Rr,models:n.data.models,providerAliases:n.data.providerAliases,version:2};try{let t=Wr(e);await w(S(e,`.ash`,`cache`),{recursive:!0}),await T(t,`${JSON.stringify(r,null,2)}\n`,`utf8`)}catch{}return r}async function qr(e){try{let t=await ge(Wr(e),`utf8`),n=Hr.safeParse(JSON.parse(t));return n.success?n.data:null}catch(e){return e instanceof Error&&`code`in e&&typeof e.code==`string`&&e.code,null}}function Jr(e,t){return e.find(e=>e.slug===t)}function Yr(e){return e.contextWindowTokens===void 0||e.contextWindowTokens<=0?null:{contextWindowTokens:e.contextWindowTokens,...e.maxOutputTokens!==void 0&&e.maxOutputTokens>0&&{maxOutputTokens:e.maxOutputTokens}}}function Xr(e){let t=Date.parse(e.fetchedAt);return Number.isFinite(t)?Date.now()-t<=864e5:!1}function Zr(e){return e.endsWith(`-thinking`)?e.slice(0,-9):e}async function z(e){let t=i(await u(S(e.agentRoot,e.source.logicalPath)),e.source);try{return await o(t)}catch(t){throw Error(`Failed to execute the ${e.kind} export "${e.source.exportName??`default`}" from "${e.source.logicalPath}": ${m(t)}`)}}var Qr=class extends Error{agentId;constructor(e){super(`Agent "${e}" does not have an agent.ts config module. The "model" field is required.`),this.name=`MissingAgentConfigModuleError`,this.agentId=e}};async function $r(e,t){if(e.configModule===void 0)throw new Qr(e.agentId);let n=et(await z({agentRoot:e.agentRoot,kind:`agent config`,source:e.configModule}),`Expected the agent config export "${e.configModule.exportName??`default`}" from "${e.configModule.logicalPath}" to match the public Ash shape.`),r=await ei({modelCatalog:t.modelCatalog,purpose:`the primary compaction trigger model`,requireContextWindowTokens:!0,contextWindowTokens:n.modelContextWindowTokens,providerOptions:n.modelOptions?.providerOptions,source:e.configModule,value:n.model}),i={},a={compaction:i,metadata:n.metadata??{},model:r,name:e.agentId};return n.description!==void 0&&(a.description=n.description),n.build!==void 0&&(a.build={externalDependencies:n.build.externalDependencies===void 0?void 0:[...n.build.externalDependencies]}),a.source={exportName:e.configModule.exportName,sourceKind:`module`,logicalPath:e.configModule.logicalPath,sourceId:e.configModule.sourceId},n.compaction?.model!==void 0&&(i.model=await ei({modelCatalog:t.modelCatalog,purpose:`the compaction summary model`,requireContextWindowTokens:!0,contextWindowTokens:n.compaction.modelContextWindowTokens,providerOptions:n.modelOptions?.providerOptions,source:e.configModule,value:n.compaction.model})),n.compaction?.thresholdPercent!==void 0&&(i.thresholdPercent=n.compaction.thresholdPercent),a}async function ei(e){if(typeof e.value==`string`)return await ti({id:le(e.value),providerOptions:e.providerOptions===void 0?void 0:ee(e.providerOptions)},e);let t=e.source;if(t===void 0)throw Error(`Expected ${e.purpose} to provide a valid AI SDK language model reference.`);let n=e.value,r=n.specificationVersion;if(r!==`v2`&&r!==`v3`&&r!==`v4`||typeof n.provider!=`string`||typeof n.modelId!=`string`||typeof n.doGenerate!=`function`||typeof n.doStream!=`function`)throw Error(`Expected the authored agent config export "${t.exportName??`default`}" from "${t.logicalPath}" to provide a valid AI SDK language model.`);let i={id:le(n),source:{exportName:t.exportName,sourceKind:`module`,logicalPath:t.logicalPath,sourceId:t.sourceId},providerOptions:e.providerOptions===void 0?void 0:ee(e.providerOptions)};if(e.contextWindowTokens===void 0){let t=await e.modelCatalog.getByProviderModelId(n.provider,n.modelId);if(t)return{...i,id:t.slug,contextWindowTokens:t.limits.contextWindowTokens}}return await ti(i,e)}async function ti(e,t){if(t.contextWindowTokens!==void 0)return{...e,contextWindowTokens:t.contextWindowTokens};let n;try{n=await t.modelCatalog.getModelLimits(e.id)}catch(n){if(!t.requireContextWindowTokens)return e;throw Error(`Failed to load AI Gateway model metadata for ${t.purpose} "${e.id}". ${m(n)}`)}if(n===null){if(!t.requireContextWindowTokens)return e;throw Error(`Cannot compile agent compaction because ${t.purpose} "${e.id}" does not have known AI Gateway context window metadata.`)}return{...e,contextWindowTokens:n.contextWindowTokens}}function ni(e){return typeof e==`object`&&!!e&&e.__kind===`ash:channel`}function ri(e,t){if(!ni(e))throw Error(`${t} Use \`defineChannel({ routes, ... })\` (or a wrapper like \`slackChannel\` / \`ashChannel\`) — bare \`{ fetch, receive? }\` channel objects are no longer supported.`);return e}function ii(e){return typeof e==`object`&&!!e&&e.kind===`ash:disabled-channel`}async function ai(e,t){let n=await z({agentRoot:e,kind:`channel`,source:t}),r=j(t.logicalPath).replace(/^channels\//,``);if(ii(n))return{kind:`disabled`,name:r,logicalPath:t.logicalPath};let i=ri(n,`Expected the channel export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`);return i.routes.map(e=>({kind:`channel`,name:r,logicalPath:t.logicalPath,method:e.method.toUpperCase(),urlPath:e.path,sourceId:t.sourceId,sourceKind:`module`,exportName:t.exportName,adapterKind:oi(i.adapter)}))}function oi(e){if(typeof e!=`object`||!e)return;let t=e.kind;return typeof t==`string`&&t.length>0?t:void 0}async function si(e,t){let n=new Map;for(let r of t){let t=await z({agentRoot:e,kind:`channel`,source:r});if(ii(t))continue;let i=j(r.logicalPath).replace(/^channels\//,``);typeof t==`object`&&t&&(n.set(t,i),s(C(S(e,r.logicalPath)),t))}return n}function ci(e,t=`auth`){if(typeof e!=`object`||!e)return`The "${t}" field must be an object with a "getToken" method.`;let n=e;if(typeof n.getToken!=`function`)return`The "${t}.getToken" field must be a function returning Promise<{ token }>.`;let r=n.startAuthorization!==void 0,i=n.completeAuthorization!==void 0;if(!r&&!i&&n.principalType!==void 0&&n.principalType!==`app`&&n.principalType!==`user`)return`The "${t}.principalType" field must be "app" or "user".`;if(r!==i)return`The "${t}" field must provide either both "startAuthorization" and "completeAuthorization" (interactive OAuth) or neither (getToken-only). Got only "${r?`startAuthorization`:`completeAuthorization`}".`;if(r&&typeof n.startAuthorization!=`function`)return`The "${t}.startAuthorization" field must be a function when provided.`;if(i&&typeof n.completeAuthorization!=`function`)return`The "${t}.completeAuthorization" field must be a function when provided.`;if(r&&n.principalType!==`user`)return`Interactive authorization (startAuthorization + completeAuthorization) is restricted to "principalType": "user" in v1. See D10 of research/connections/connection-principal-model.md for the rationale.`}function li(e,t,n=`auth`){let r=ci(e,n);if(r!==void 0)throw Error(`${t} ${r}`);let i=e,a=ui(i.vercelConnect);if(i.startAuthorization!==void 0&&i.completeAuthorization!==void 0){let e={completeAuthorization:i.completeAuthorization,getToken:i.getToken,principalType:`user`,startAuthorization:i.startAuthorization};return a===void 0?e:{...e,vercelConnect:a}}let o={getToken:i.getToken,principalType:i.principalType??`app`};return a===void 0?o:{...o,vercelConnect:a}}function ui(e){if(typeof e!=`object`||!e)return;let t=e.connector;if(!(typeof t!=`string`||t.length===0))return{connector:t}}const di=[`approval`,`auth`,`description`,`headers`,`tools`,`url`],fi=[`completeAuthorization`,`getToken`,`principalType`,`startAuthorization`,`vercelConnect`];function pi(e,t){let r=n(e,t);a(r,di,t),mi(r,t),hi(r,t);let i=gi(r,t),o=_i(r,t),s=vi(r,t);if(i!==void 0&&o!==void 0&&typeof o!=`function`&&Object.keys(o).some(e=>e.toLowerCase()===`authorization`))throw Error(`${t} "headers" must not include an "Authorization" key when "auth" is also provided.`);let c={description:r.description,url:r.url};if(i!==void 0&&(c.auth=i),o!==void 0&&(c.headers=o),s!==void 0&&(c.tools=s),r.approval!==void 0){if(typeof r.approval!=`function`)throw Error(`${t} The "approval" field must be a function when provided.`);c.approval=r.approval}return c}function mi(e,t){if(typeof e.url!=`string`||!URL.canParse(e.url))throw Error(`${t} The "url" field must be a valid URL.`);let n=new URL(e.url);if(n.protocol!==`https:`&&n.protocol!==`http:`)throw Error(`${t} The "url" field must use the http or https protocol, got "${n.protocol}".`)}function hi(e,t){if(typeof e.description!=`string`||e.description.length===0)throw Error(`${t} The "description" field must be a non-empty string.`)}function gi(e,t){if(e.auth===void 0)return;let r=n(e.auth,`${t} The "auth" field must be an object with a "getToken" method.`);return a(r,fi,`${t} The "auth" field`),li(r,t)}function _i(e,t){if(e.headers===void 0)return;if(typeof e.headers==`function`)return e.headers;if(typeof e.headers!=`object`||e.headers===null||Array.isArray(e.headers))throw Error(`${t} The "headers" field must be a plain object or a function.`);let n=e.headers;for(let[e,r]of Object.entries(n)){let n=typeof r;if(n!==`string`&&n!==`function`&&n!==`object`||n===`object`&&(r===null||typeof r.then!=`function`))throw Error(`${t} The "headers.${e}" value must be a string, Promise, or function.`)}return n}function vi(e,t){if(e.tools===void 0)return;if(typeof e.tools!=`object`||e.tools===null||Array.isArray(e.tools))throw Error(`${t} The "tools" field must specify either "allow" or "block".`);let n=e.tools,r=`allow`in n,i=`block`in n;if(r&&i)throw Error(`${t} The "tools" field must specify either "allow" or "block", not both.`);if(!r&&!i)throw Error(`${t} The "tools" field must specify either "allow" or "block".`);return r?(yi(n.allow,`${t} The "tools.allow"`),{allow:n.allow}):(yi(n.block,`${t} The "tools.block"`),{block:n.block})}function yi(e,t){if(!Array.isArray(e))throw Error(`${t} field must be an array of strings.`);for(let n=0;n<e.length;n++)if(typeof e[n]!=`string`)throw Error(`${t}[${n}] must be a string.`)}async function bi(e,t){let n=pi(await z({agentRoot:e,kind:`connection`,source:t}),`Expected the connection export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`),r={connectionName:t.connectionName,description:n.description,exportName:t.exportName,logicalPath:t.logicalPath,sourceId:t.sourceId,sourceKind:`module`,url:n.url},i=xi(n.auth);return i!==void 0&&(r.vercelConnect=i),r}function xi(e){if(typeof e!=`object`||!e)return;let t=e.vercelConnect;if(typeof t!=`object`||!t)return;let n=t.connector;if(!(typeof n!=`string`||n.length===0))return{connector:n}}function Si(e){return{exportName:e.exportName,logicalPath:e.logicalPath,slug:j(e.logicalPath).replace(/^hooks\//,``),sourceId:e.sourceId,sourceKind:`module`}}function Ci(e,t){let r=n(e,t);a(r,[`backend`,`bootstrap`,`description`,`onSession`],t);let i={};if(r.backend!==void 0&&(i.backend=wi(r.backend,t)),r.description!==void 0){if(typeof r.description!=`string`)throw Error(`${t} The "description" field must be a string when set.`);i.description=r.description}return r.bootstrap!==void 0&&(i.bootstrap=l(r.bootstrap,t)),r.onSession!==void 0&&(i.onSession=l(r.onSession,t)),i}function wi(e,t){let r=n(e,`${t} The "backend" field must be a SandboxBackend value (use vercelBackend(), localBackend(), or your own factory).`);if(typeof r.name!=`string`||r.name.length===0)throw Error(`${t} The "backend" value must expose a non-empty string "name" identifier.`);if(typeof r.create!=`function`)throw Error(`${t} The "backend" value must expose a "create" function.`);if(r.prewarm!==void 0&&typeof r.prewarm!=`function`)throw Error(`${t} The "backend.prewarm" property must be a function when set.`);return r}async function Ti(e,t){return{description:Ci(await z({agentRoot:e,kind:`sandbox`,source:t}),`Expected the sandbox export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`).description,exportName:t.exportName,logicalPath:t.logicalPath,sourceId:t.sourceId,sourceKind:`module`}}async function Ei(e,t){let n=t.sourceKind===`markdown`?at(t.definition,`Expected the compiled instructions definition at "${t.logicalPath}" to match the public Ash shape.`):at(await z({agentRoot:e,kind:`instructions`,source:t}),`Expected the instructions export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`);return{name:j(t.logicalPath),logicalPath:t.logicalPath,markdown:n.markdown,sourceId:t.sourceId,sourceKind:t.sourceKind}}async function Di(e,t,n){let r=t.sourceKind===`markdown`?st(t.definition,`Expected the compiled schedule definition at "${t.logicalPath}" to match the public Ash shape.`):st(await z({agentRoot:e,kind:`schedule`,source:t}),`Expected the schedule export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`),i={cron:r.cron,logicalPath:t.logicalPath,markdown:r.markdown.trim(),name:ki(t.logicalPath),sourceId:t.sourceId,sourceKind:t.sourceKind};return r.channel!==void 0&&(i.channel=Oi({channel:r.channel,channelIdentityMap:n,logicalPath:t.logicalPath})),i}function Oi(e){let t=e.channel,n=t.__route??t,r=t.args??{},i=e.channelIdentityMap.get(n);if(!i&&typeof t.name==`string`&&(i=t.name),!i)throw Error(`Schedule at "${e.logicalPath}" references a channel that was not discovered in agent/channels/. Import a channel module or pass { name: "<channel-name>", args: { ... } } as the channel field.`);return{name:i,args:r}}function ki(e){return j(e).replace(/^schedules\//,``)}async function Ai(e,t){if(t.sourceKind===`skill-package`)return ji(t);let n=t.sourceKind===`markdown`?ot(t.definition,`Expected the compiled skill definition at "${t.logicalPath}" to match the public Ash shape.`):ot(await z({agentRoot:e,kind:`skill`,source:t}),`Expected the skill export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`);return{description:n.description,license:n.license,logicalPath:t.logicalPath,markdown:n.markdown,metadata:n.metadata===void 0?void 0:{...n.metadata},name:j(t.logicalPath).replace(/^skills\//,``),sourceId:t.sourceId,sourceKind:t.sourceKind}}function ji(e){return{assetsPath:e.assetsPath,description:e.description,license:e.license,logicalPath:e.logicalPath,markdown:e.markdown,metadata:e.metadata===void 0?void 0:{...e.metadata},name:e.name,referencesPath:e.referencesPath,rootPath:e.rootPath,scriptsPath:e.scriptsPath,skillId:e.skillId,skillFilePath:e.skillFilePath,sourceId:e.sourceId,sourceKind:`skill-package`}}async function Mi(e){let t=[],n=[];for(let r of e.subagents){let i=await Ni({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,parentNodeId:e.parentNodeId,source:r});t.push(i.node,...i.descendants.nodes),n.push({childNodeId:i.node.nodeId,parentNodeId:e.parentNodeId},...i.descendants.edges)}return{edges:n,nodes:t}}async function Ni(e){let t=pr(e.parentNodeId,e.source.sourceId),n=e.source.subagentId,r=await e.compileAgentNodeManifest({...e.source.manifest,appRoot:e.appRoot},e.context),i=r.config.description;if(!i)throw Error(`Local subagent "${e.source.logicalPath}" is missing a "description" field on its agent config. Add \`description\` to \`defineAgent({ ... })\` so the parent agent can decide when to delegate to this subagent.`);return{descendants:await Mi({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,parentNodeId:t,subagents:e.source.manifest.subagents}),node:{agent:r,description:i,entryPath:e.source.entryPath,logicalPath:e.source.logicalPath,name:n,nodeId:t,rootPath:e.source.rootPath,sourceId:e.source.sourceId,sourceKind:`module`}}}function Pi(e){return typeof e==`object`&&!!e&&e.kind===`ash:disabled-tool`}function Fi(e){return e&&typeof e==`object`&&`~standard`in e?e[`~standard`].jsonSchema.input({target:`draft-07`}):JSON.parse(JSON.stringify(e))}function Ii(e,t){if(Pi(e))return{kind:`disabled`};let i=n(e,t);a(i,[`description`,`execute`,`inputSchema`,`needsApproval`,`onCompact`],t);let o=i.inputSchema===void 0?null:Fi(i.inputSchema),s={description:r(i.description,t),execute:l(i.execute,t),inputSchema:o};return i.onCompact!==void 0&&l(i.onCompact,t),i.needsApproval!==void 0&&l(i.needsApproval,t),{kind:`tool`,definition:s}}async function Li(e,t){let n=Ii(await z({agentRoot:e,kind:`tool`,source:t}),`Expected the tool export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`),r=j(t.logicalPath).replace(/^tools\//,``).replaceAll(`/`,`-`);return n.kind===`disabled`?{kind:`disabled`,name:r}:{kind:`tool`,definition:{description:n.definition.description,exportName:t.exportName,inputSchema:n.definition.inputSchema??null,logicalPath:t.logicalPath,name:r,sourceId:t.sourceId,sourceKind:`module`}}}async function Ri(e){let t={modelCatalog:Gr(e.appRoot)},[n,r]=await Promise.all([zi(e,t),Mi({appRoot:e.appRoot,compileAgentNodeManifest:zi,context:t,parentNodeId:L,subagents:e.subagents})]);return mr({...n,subagentEdges:r.edges,subagents:r.nodes})}async function zi(e,t){let n=await Promise.all(e.tools.map(t=>Li(e.agentRoot,t))),r=[],i=[];for(let e of n)e.kind===`tool`?r.push(e.definition):i.push(e.name);let[a,o]=await Promise.all([Promise.all(e.channels.map(t=>ai(e.agentRoot,t))),si(e.agentRoot,e.channels)]),s=a.flat();return dr({agentRoot:e.agentRoot,appRoot:e.appRoot,channels:s,config:await $r(e,t),connections:await Promise.all(e.connections.map(t=>bi(e.agentRoot,t))),diagnosticsSummary:e.diagnosticsSummary,disabledFrameworkTools:i,hooks:e.hooks.map(e=>Si(e)),sandbox:e.sandbox===null?null:await Ti(e.agentRoot,e.sandbox),sandboxWorkspaces:e.sandboxWorkspaces.map(e=>({logicalPath:e.logicalPath,rootEntries:[...e.rootEntries],sourceId:e.sourceId,sourcePath:e.sourcePath})),schedules:await Promise.all(e.schedules.map(t=>Di(e.agentRoot,t,o))),skills:await Promise.all(e.skills.map(t=>Ai(e.agentRoot,t))),instructions:e.instructions===void 0?void 0:await Ei(e.agentRoot,e.instructions),tools:r})}const Bi=`workspace-resources`;async function Vi(e){let t=S(e.compileDirectoryPath,Bi);await ve(t,{force:!0,recursive:!0});let n=await Ui({nodeId:L,resourcesRoot:t,manifest:e.manifest}),r=await Promise.all(e.manifest.subagents.map(async e=>({...e,agent:await Ui({nodeId:e.nodeId,resourcesRoot:t,manifest:e.agent})})));return{...n,kind:e.manifest.kind,subagentEdges:e.manifest.subagentEdges,subagents:r,version:e.manifest.version}}function Hi(e,t){return{logicalPath:O(S(Bi,t)),rootEntries:fr({sandboxWorkspaces:e.sandboxWorkspaces,skills:e.skills})}}async function Ui(e){for(let t of e.manifest.sandboxWorkspaces)if(t.rootEntries.some(e=>e===`skills/`||e===`skills`))throw Error(`Sandbox workspace "${t.logicalPath}" cannot define "skills" because Ash manages that workspace entry.`);let t=S(e.resourcesRoot,e.nodeId);await w(t,{recursive:!0});for(let n of e.manifest.sandboxWorkspaces)await he(n.sourcePath,t,{recursive:!0});for(let n of e.manifest.skills)await Wi({nodeRoot:t,skill:n});return{...e.manifest,workspaceResourceRoot:Hi(e.manifest,e.nodeId)}}async function Wi(e){let t=S(e.nodeRoot,`skills`,e.skill.name);if(e.skill.sourceKind===`skill-package`){await he(e.skill.rootPath,t,{recursive:!0});return}let n=S(t,`SKILL.md`);await w(x(n),{recursive:!0}),await T(n,e.skill.markdown)}function Gi(e){let t=C(e),n=S(t,`.ash`,`discovery`),r=S(t,`.ash`,`compile`);return{appRoot:t,compiledManifestPath:S(r,`compiled-agent-manifest.json`),compileDirectoryPath:r,compileMetadataPath:S(r,`compile-metadata.json`),diagnosticsPath:S(n,`diagnostics.json`),discoveryManifestPath:S(n,`agent-discovery-manifest.json`),discoveryDirectoryPath:n,moduleMapPath:S(r,`module-map.mjs`)}}function Ki(e){return{diagnostics:[...e],kind:`ash-discovery-diagnostics`,summary:Le(e),version:1}}function qi(e){let t=v(),n=Yi(e.discoveryManifestJson),r=Yi(e.diagnosticsArtifactJson),i=Yi(e.moduleMapSource);return{compile:{moduleMap:{path:Zi(e.appRoot,e.paths.moduleMapPath),sha256:i}},discovery:{diagnostics:{path:Zi(e.appRoot,e.paths.diagnosticsPath),sha256:r},manifest:{path:Zi(e.appRoot,e.paths.discoveryManifestPath),sha256:n},sourceGraphHash:Yi(`${n}:${r}:${i}`),summary:e.diagnosticsSummary},generator:{name:t.name,version:t.version},kind:`ash-compile-metadata`,status:e.diagnosticsSummary.errors>0?`failed`:`ready`,version:5}}async function Ji(e){let t=Gi(e.appRoot),n=Ki(e.diagnostics),r=await Vi({compileDirectoryPath:t.compileDirectoryPath,manifest:await Ri(e.manifest)}),i=Xi(r),a=Xi(e.manifest),o=Xi(n),s=Dr({manifest:r,moduleMapPath:t.moduleMapPath}),c=qi({appRoot:e.appRoot,diagnosticsArtifactJson:o,diagnosticsSummary:n.summary,discoveryManifestJson:a,moduleMapSource:s,paths:t}),l=Xi(c);return await w(t.discoveryDirectoryPath,{recursive:!0}),await w(t.compileDirectoryPath,{recursive:!0}),await Promise.all([T(t.compiledManifestPath,i),T(t.diagnosticsPath,o),T(t.discoveryManifestPath,a),T(t.moduleMapPath,s),T(t.compileMetadataPath,l)]),{compiledManifest:r,diagnosticsArtifact:n,metadata:c,moduleMapSource:s,paths:t}}function Yi(e){return be(`sha256`).update(e).digest(`hex`)}function Xi(e){return`${JSON.stringify(e,null,2)}\n`}function Zi(e,t){return O(fe(C(e),t))}var Qi=class extends Error{result;constructor(e){super(ta({diagnostics:e.diagnostics,diagnosticsPath:e.paths.diagnosticsPath})),this.name=`CompileAgentError`,this.result=e}};async function $i(e={}){let t=e.source??I(),n=await Mn(e.startPath,{source:t}),r=await kn({...n,source:t}),i=await Ji({appRoot:n.appRoot,diagnostics:r.diagnostics,manifest:r.manifest}),a={diagnostics:r.diagnostics,manifest:i.compiledManifest,metadata:i.metadata,paths:i.paths,project:n};if(Re(r.diagnostics))throw new Qi(a);return ea(r.diagnostics),a}function ea(e){let t=e.filter(e=>e.severity===`warning`);if(t.length!==0)for(let e of t)console.warn(`Warning [${e.code}]: ${e.message}\n source: ${e.sourcePath}`)}function ta(e){let t=Le(e.diagnostics),n=[`Discovery failed with ${t.errors} error(s) and ${t.warnings} warning(s).`];if(e.diagnosticsPath!==void 0&&n.push(`Diagnostics artifact: ${e.diagnosticsPath}`),e.diagnostics.length===0)return n.join(`
7
+ `)}function Nr(e){let t=R(e);return t.segments.length===0?t.root.length===0?`.`:t.root:Lr(t.root,t.segments.slice(0,-1))}function Pr(e,t){let n=R(e),r=R(t);return r.root.length>0?Lr(r.root,r.segments):Lr(n.root,[...n.segments,...r.segments])}function Fr(e,t){let n=R(e),r=R(t);if(n.root!==r.root)return Ir(t);let i=0;for(;i<n.segments.length&&i<r.segments.length&&n.segments[i]===r.segments[i];)i+=1;let a=[...Array.from({length:n.segments.length-i},()=>`..`),...r.segments.slice(i)];return a.length===0?`.`:a.join(`/`)}function Ir(e){let t=R(e);return Lr(t.root,t.segments)}function R(e){let t=e.replaceAll(`\\`,`/`),n=``,r=t,i=t.match(/^[A-Za-z]:/);i===null?t.startsWith(`/`)&&(n=`/`,r=t.slice(1)):(n=i[0],r=t.slice(n.length),r.startsWith(`/`)&&(n=`${n}/`,r=r.slice(1)));let a=[];for(let e of r.split(`/`))if(!(e.length===0||e===`.`)){if(e===`..`){if(a.length>0&&a[a.length-1]!==`..`){a.pop();continue}n.length===0&&a.push(e);continue}a.push(e)}return{root:n,segments:a}}function Lr(e,t){return e===`/`?t.length===0?`/`:`/${t.join(`/`)}`:e.endsWith(`/`)?t.length===0?e:`${e}${t.join(`/`)}`:e.length>0?t.length===0?e:`${e}/${t.join(`/`)}`:t.length===0?`.`:t.join(`/`)}const Rr=`ash-model-catalog-cache`,zr=b.object({provider:b.string().min(1),providerModelId:b.string().min(1),contextWindowTokens:b.number().int().nonnegative().optional(),maxOutputTokens:b.number().int().nonnegative().optional()}).passthrough(),Br=b.object({slug:b.string().min(1),providers:b.array(zr).min(1)}).passthrough(),Vr=b.object({models:b.array(Br),providerAliases:b.record(b.string(),b.string())}).passthrough();b.object({contextWindowTokens:b.number().int().positive(),maxOutputTokens:b.number().int().positive().optional()}).strict();const Hr=b.object({fetchedAt:b.string(),kind:b.literal(Rr),models:b.array(Br),providerAliases:b.record(b.string(),b.string()),version:b.literal(2)}).strict(),Ur=new Map([[`anthropic/claude-opus-4.7`,{contextWindowTokens:2e5,maxOutputTokens:32e3}],[`openai/gpt-5.4`,{contextWindowTokens:4e5,maxOutputTokens:128e3}],[`openai/gpt-5.4-mini`,{contextWindowTokens:4e5,maxOutputTokens:128e3}]]);function Wr(e){return S(e,`.ash`,`cache`,`model-catalog.json`)}function Gr(e){let t=null,n=null,r=null,i=async()=>(t??=qr(e),await t),a=async()=>{if(n!==null)throw n;if(r!==null)return await r;r=Kr(e).then(e=>(t=Promise.resolve(e),e));try{return await r}catch(e){throw n=e,e}},o=async()=>{let e=await i();if(e!==null&&Xr(e))return e;try{return await a()}catch{return e===null?null:e}};return{async getModelLimits(e){let t=Zr(e),n=await o();if(n!==null){let e=Jr(n.models,t);if(e)for(let t of e.providers){let e=Yr(t);if(e!==null)return e}}return Ur.get(t)??null},async getByProviderModelId(e,t){let n=await o();if(n===null)return null;let r=e.split(`.`)[0],i=n.providerAliases[r]??r,a=Zr(t);for(let e of n.models)for(let t of e.providers)if(t.provider===i&&Zr(t.providerModelId)===a){let n=Yr(t);if(n!==null)return{slug:e.slug,limits:n}}return null}}}async function Kr(e){let t=await fetch(`https://ai-gateway.vercel.sh/v1/models/catalog`);if(!t.ok)throw Error(`AI Gateway model catalog request failed with HTTP ${t.status} ${t.statusText}.`);let n=Vr.safeParse(await t.json());if(!n.success)throw Error(`AI Gateway model catalog response did not match the expected schema.`);let r={fetchedAt:new Date().toISOString(),kind:Rr,models:n.data.models,providerAliases:n.data.providerAliases,version:2};try{let t=Wr(e);await w(S(e,`.ash`,`cache`),{recursive:!0}),await T(t,`${JSON.stringify(r,null,2)}\n`,`utf8`)}catch{}return r}async function qr(e){try{let t=await ge(Wr(e),`utf8`),n=Hr.safeParse(JSON.parse(t));return n.success?n.data:null}catch(e){return e instanceof Error&&`code`in e&&typeof e.code==`string`&&e.code,null}}function Jr(e,t){return e.find(e=>e.slug===t)}function Yr(e){return e.contextWindowTokens===void 0||e.contextWindowTokens<=0?null:{contextWindowTokens:e.contextWindowTokens,...e.maxOutputTokens!==void 0&&e.maxOutputTokens>0&&{maxOutputTokens:e.maxOutputTokens}}}function Xr(e){let t=Date.parse(e.fetchedAt);return Number.isFinite(t)?Date.now()-t<=864e5:!1}function Zr(e){return e.endsWith(`-thinking`)?e.slice(0,-9):e}async function z(e){let t=i(await u(S(e.agentRoot,e.source.logicalPath)),e.source);try{return await o(t)}catch(t){throw Error(`Failed to execute the ${e.kind} export "${e.source.exportName??`default`}" from "${e.source.logicalPath}": ${m(t)}`)}}var Qr=class extends Error{agentId;constructor(e){super(`Agent "${e}" does not have an agent.ts config module. The "model" field is required.`),this.name=`MissingAgentConfigModuleError`,this.agentId=e}};async function $r(e,t){if(e.configModule===void 0)throw new Qr(e.agentId);let n=et(await z({agentRoot:e.agentRoot,kind:`agent config`,source:e.configModule}),`Expected the agent config export "${e.configModule.exportName??`default`}" from "${e.configModule.logicalPath}" to match the public Ash shape.`),r=await ei({modelCatalog:t.modelCatalog,purpose:`the primary compaction trigger model`,requireContextWindowTokens:!0,contextWindowTokens:n.modelContextWindowTokens,providerOptions:n.modelOptions?.providerOptions,source:e.configModule,value:n.model}),i={},a={compaction:i,metadata:n.metadata??{},model:r,name:e.agentId};return n.description!==void 0&&(a.description=n.description),n.build!==void 0&&(a.build={externalDependencies:n.build.externalDependencies===void 0?void 0:[...n.build.externalDependencies]}),a.source={exportName:e.configModule.exportName,sourceKind:`module`,logicalPath:e.configModule.logicalPath,sourceId:e.configModule.sourceId},n.compaction?.model!==void 0&&(i.model=await ei({modelCatalog:t.modelCatalog,purpose:`the compaction summary model`,requireContextWindowTokens:!0,contextWindowTokens:n.compaction.modelContextWindowTokens,providerOptions:n.modelOptions?.providerOptions,source:e.configModule,value:n.compaction.model})),n.compaction?.thresholdPercent!==void 0&&(i.thresholdPercent=n.compaction.thresholdPercent),a}async function ei(e){if(typeof e.value==`string`)return await ti({id:le(e.value),providerOptions:e.providerOptions===void 0?void 0:ee(e.providerOptions)},e);let t=e.source;if(t===void 0)throw Error(`Expected ${e.purpose} to provide a valid AI SDK language model reference.`);let n=e.value,r=n.specificationVersion;if(r!==`v2`&&r!==`v3`&&r!==`v4`||typeof n.provider!=`string`||typeof n.modelId!=`string`||typeof n.doGenerate!=`function`||typeof n.doStream!=`function`)throw Error(`Expected the authored agent config export "${t.exportName??`default`}" from "${t.logicalPath}" to provide a valid AI SDK language model.`);let i={id:le(n),source:{exportName:t.exportName,sourceKind:`module`,logicalPath:t.logicalPath,sourceId:t.sourceId},providerOptions:e.providerOptions===void 0?void 0:ee(e.providerOptions)};if(e.contextWindowTokens===void 0){let t=await e.modelCatalog.getByProviderModelId(n.provider,n.modelId);if(t)return{...i,id:t.slug,contextWindowTokens:t.limits.contextWindowTokens}}return await ti(i,e)}async function ti(e,t){if(t.contextWindowTokens!==void 0)return{...e,contextWindowTokens:t.contextWindowTokens};let n;try{n=await t.modelCatalog.getModelLimits(e.id)}catch(n){if(!t.requireContextWindowTokens)return e;throw Error(`Failed to load AI Gateway model metadata for ${t.purpose} "${e.id}". ${m(n)}`)}if(n===null){if(!t.requireContextWindowTokens)return e;throw Error(`Cannot compile agent compaction because ${t.purpose} "${e.id}" does not have known AI Gateway context window metadata.`)}return{...e,contextWindowTokens:n.contextWindowTokens}}function ni(e){return typeof e==`object`&&!!e&&e.__kind===`ash:channel`}function ri(e,t){if(!ni(e))throw Error(`${t} Use \`defineChannel({ routes, ... })\` (or a wrapper like \`slackChannel\` / \`ashChannel\`) — bare \`{ fetch, receive? }\` channel objects are no longer supported.`);return e}function ii(e){return typeof e==`object`&&!!e&&e.kind===`ash:disabled-channel`}async function ai(e,t){let n=await z({agentRoot:e,kind:`channel`,source:t}),r=j(t.logicalPath).replace(/^channels\//,``);if(ii(n))return{kind:`disabled`,name:r,logicalPath:t.logicalPath};let i=ri(n,`Expected the channel export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`);return i.routes.map(e=>({kind:`channel`,name:r,logicalPath:t.logicalPath,method:e.method.toUpperCase(),urlPath:e.path,sourceId:t.sourceId,sourceKind:`module`,exportName:t.exportName,adapterKind:oi(i.adapter)}))}function oi(e){if(typeof e!=`object`||!e)return;let t=e.kind;return typeof t==`string`&&t.length>0?t:void 0}async function si(e,t){let n=new Map;for(let r of t){let t=await z({agentRoot:e,kind:`channel`,source:r});if(ii(t))continue;let i=j(r.logicalPath).replace(/^channels\//,``);typeof t==`object`&&t&&(n.set(t,i),s(C(S(e,r.logicalPath)),t))}return n}function ci(e,t=`auth`){if(typeof e!=`object`||!e)return`The "${t}" field must be an object with a "getToken" method.`;let n=e;if(typeof n.getToken!=`function`)return`The "${t}.getToken" field must be a function returning Promise<{ token }>.`;let r=n.startAuthorization!==void 0,i=n.completeAuthorization!==void 0;if(!r&&!i&&n.principalType!==void 0&&n.principalType!==`app`&&n.principalType!==`user`)return`The "${t}.principalType" field must be "app" or "user".`;if(r!==i)return`The "${t}" field must provide either both "startAuthorization" and "completeAuthorization" (interactive OAuth) or neither (getToken-only). Got only "${r?`startAuthorization`:`completeAuthorization`}".`;if(r&&typeof n.startAuthorization!=`function`)return`The "${t}.startAuthorization" field must be a function when provided.`;if(i&&typeof n.completeAuthorization!=`function`)return`The "${t}.completeAuthorization" field must be a function when provided.`;if(r&&n.principalType!==`user`)return`Interactive authorization (startAuthorization + completeAuthorization) is restricted to "principalType": "user" in v1. See D10 of research/connections/connection-principal-model.md for the rationale.`}function li(e,t,n=`auth`){let r=ci(e,n);if(r!==void 0)throw Error(`${t} ${r}`);let i=e,a=ui(i.vercelConnect);if(i.startAuthorization!==void 0&&i.completeAuthorization!==void 0){let e={completeAuthorization:i.completeAuthorization,getToken:i.getToken,principalType:`user`,startAuthorization:i.startAuthorization};return a===void 0?e:{...e,vercelConnect:a}}let o={getToken:i.getToken,principalType:i.principalType??`app`};return a===void 0?o:{...o,vercelConnect:a}}function ui(e){if(typeof e!=`object`||!e)return;let t=e.connector;if(!(typeof t!=`string`||t.length===0))return{connector:t}}const di=[`approval`,`auth`,`description`,`headers`,`tools`,`url`],fi=[`completeAuthorization`,`getToken`,`principalType`,`startAuthorization`,`vercelConnect`];function pi(e,t){let r=n(e,t);a(r,di,t),mi(r,t),hi(r,t);let i=gi(r,t),o=_i(r,t),s=vi(r,t);if(i!==void 0&&o!==void 0&&typeof o!=`function`&&Object.keys(o).some(e=>e.toLowerCase()===`authorization`))throw Error(`${t} "headers" must not include an "Authorization" key when "auth" is also provided.`);let c={description:r.description,url:r.url};if(i!==void 0&&(c.auth=i),o!==void 0&&(c.headers=o),s!==void 0&&(c.tools=s),r.approval!==void 0){if(typeof r.approval!=`function`)throw Error(`${t} The "approval" field must be a function when provided.`);c.approval=r.approval}return c}function mi(e,t){if(typeof e.url!=`string`||!URL.canParse(e.url))throw Error(`${t} The "url" field must be a valid URL.`);let n=new URL(e.url);if(n.protocol!==`https:`&&n.protocol!==`http:`)throw Error(`${t} The "url" field must use the http or https protocol, got "${n.protocol}".`)}function hi(e,t){if(typeof e.description!=`string`||e.description.length===0)throw Error(`${t} The "description" field must be a non-empty string.`)}function gi(e,t){if(e.auth===void 0)return;let r=n(e.auth,`${t} The "auth" field must be an object with a "getToken" method.`);return a(r,fi,`${t} The "auth" field`),li(r,t)}function _i(e,t){if(e.headers===void 0)return;if(typeof e.headers==`function`)return e.headers;if(typeof e.headers!=`object`||e.headers===null||Array.isArray(e.headers))throw Error(`${t} The "headers" field must be a plain object or a function.`);let n=e.headers;for(let[e,r]of Object.entries(n)){let n=typeof r;if(n!==`string`&&n!==`function`&&n!==`object`||n===`object`&&(r===null||typeof r.then!=`function`))throw Error(`${t} The "headers.${e}" value must be a string, Promise, or function.`)}return n}function vi(e,t){if(e.tools===void 0)return;if(typeof e.tools!=`object`||e.tools===null||Array.isArray(e.tools))throw Error(`${t} The "tools" field must specify either "allow" or "block".`);let n=e.tools,r=`allow`in n,i=`block`in n;if(r&&i)throw Error(`${t} The "tools" field must specify either "allow" or "block", not both.`);if(!r&&!i)throw Error(`${t} The "tools" field must specify either "allow" or "block".`);return r?(yi(n.allow,`${t} The "tools.allow"`),{allow:n.allow}):(yi(n.block,`${t} The "tools.block"`),{block:n.block})}function yi(e,t){if(!Array.isArray(e))throw Error(`${t} field must be an array of strings.`);for(let n=0;n<e.length;n++)if(typeof e[n]!=`string`)throw Error(`${t}[${n}] must be a string.`)}async function bi(e,t){let n=pi(await z({agentRoot:e,kind:`connection`,source:t}),`Expected the connection export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`),r={connectionName:t.connectionName,description:n.description,exportName:t.exportName,logicalPath:t.logicalPath,sourceId:t.sourceId,sourceKind:`module`,url:n.url},i=xi(n.auth);return i!==void 0&&(r.vercelConnect=i),r}function xi(e){if(typeof e!=`object`||!e)return;let t=e.vercelConnect;if(typeof t!=`object`||!t)return;let n=t.connector;if(!(typeof n!=`string`||n.length===0))return{connector:n}}function Si(e){return{exportName:e.exportName,logicalPath:e.logicalPath,slug:j(e.logicalPath).replace(/^hooks\//,``),sourceId:e.sourceId,sourceKind:`module`}}function Ci(e,t){let r=n(e,t);a(r,[`backend`,`bootstrap`,`description`,`onSession`],t);let i={};if(r.backend!==void 0&&(i.backend=wi(r.backend,t)),r.description!==void 0){if(typeof r.description!=`string`)throw Error(`${t} The "description" field must be a string when set.`);i.description=r.description}return r.bootstrap!==void 0&&(i.bootstrap=l(r.bootstrap,t)),r.onSession!==void 0&&(i.onSession=l(r.onSession,t)),i}function wi(e,t){let r=n(e,`${t} The "backend" field must be a SandboxBackend value (use vercelBackend(), localBackend(), or your own factory).`);if(typeof r.name!=`string`||r.name.length===0)throw Error(`${t} The "backend" value must expose a non-empty string "name" identifier.`);if(typeof r.create!=`function`)throw Error(`${t} The "backend" value must expose a "create" function.`);if(r.prewarm!==void 0&&typeof r.prewarm!=`function`)throw Error(`${t} The "backend.prewarm" property must be a function when set.`);return r}async function Ti(e,t){return{description:Ci(await z({agentRoot:e,kind:`sandbox`,source:t}),`Expected the sandbox export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`).description,exportName:t.exportName,logicalPath:t.logicalPath,sourceId:t.sourceId,sourceKind:`module`}}async function Ei(e,t){let n=t.sourceKind===`markdown`?at(t.definition,`Expected the compiled instructions definition at "${t.logicalPath}" to match the public Ash shape.`):at(await z({agentRoot:e,kind:`instructions`,source:t}),`Expected the instructions export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`);return{name:j(t.logicalPath),logicalPath:t.logicalPath,markdown:n.markdown,sourceId:t.sourceId,sourceKind:t.sourceKind}}async function Di(e,t,n){let r=t.sourceKind===`markdown`?st(t.definition,`Expected the compiled schedule definition at "${t.logicalPath}" to match the public Ash shape.`):st(await z({agentRoot:e,kind:`schedule`,source:t}),`Expected the schedule export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`),i={cron:r.cron,logicalPath:t.logicalPath,markdown:r.markdown.trim(),name:ki(t.logicalPath),sourceId:t.sourceId,sourceKind:t.sourceKind};return r.channel!==void 0&&(i.channel=Oi({channel:r.channel,channelIdentityMap:n,logicalPath:t.logicalPath})),i}function Oi(e){let t=e.channel,n=t.__route??t,r=t.args??{},i=e.channelIdentityMap.get(n);if(!i&&typeof t.name==`string`&&(i=t.name),!i)throw Error(`Schedule at "${e.logicalPath}" references a channel that was not discovered in agent/channels/. Import a channel module or pass { name: "<channel-name>", args: { ... } } as the channel field.`);return{name:i,args:r}}function ki(e){return j(e).replace(/^schedules\//,``)}async function Ai(e,t){if(t.sourceKind===`skill-package`)return ji(t);let n=t.sourceKind===`markdown`?ot(t.definition,`Expected the compiled skill definition at "${t.logicalPath}" to match the public Ash shape.`):ot(await z({agentRoot:e,kind:`skill`,source:t}),`Expected the skill export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`);return{description:n.description,license:n.license,logicalPath:t.logicalPath,markdown:n.markdown,metadata:n.metadata===void 0?void 0:{...n.metadata},name:j(t.logicalPath).replace(/^skills\//,``),sourceId:t.sourceId,sourceKind:t.sourceKind}}function ji(e){return{assetsPath:e.assetsPath,description:e.description,license:e.license,logicalPath:e.logicalPath,markdown:e.markdown,metadata:e.metadata===void 0?void 0:{...e.metadata},name:e.name,referencesPath:e.referencesPath,rootPath:e.rootPath,scriptsPath:e.scriptsPath,skillId:e.skillId,skillFilePath:e.skillFilePath,sourceId:e.sourceId,sourceKind:`skill-package`}}async function Mi(e){let t=[],n=[];for(let r of e.subagents){let i=await Ni({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,parentNodeId:e.parentNodeId,source:r});t.push(i.node,...i.descendants.nodes),n.push({childNodeId:i.node.nodeId,parentNodeId:e.parentNodeId},...i.descendants.edges)}return{edges:n,nodes:t}}async function Ni(e){let t=pr(e.parentNodeId,e.source.sourceId),n=e.source.subagentId,r=await e.compileAgentNodeManifest({...e.source.manifest,appRoot:e.appRoot},e.context),i=r.config.description;if(!i)throw Error(`Local subagent "${e.source.logicalPath}" is missing a "description" field on its agent config. Add \`description\` to \`defineAgent({ ... })\` so the parent agent can decide when to delegate to this subagent.`);return{descendants:await Mi({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,parentNodeId:t,subagents:e.source.manifest.subagents}),node:{agent:r,description:i,entryPath:e.source.entryPath,logicalPath:e.source.logicalPath,name:n,nodeId:t,rootPath:e.source.rootPath,sourceId:e.source.sourceId,sourceKind:`module`}}}function Pi(e){return typeof e==`object`&&!!e&&e.kind===`ash:disabled-tool`}function Fi(e){return e&&typeof e==`object`&&`~standard`in e?e[`~standard`].jsonSchema.input({target:`draft-07`}):JSON.parse(JSON.stringify(e))}function Ii(e,t){if(Pi(e))return{kind:`disabled`};let i=n(e,t);a(i,[`description`,`execute`,`inputSchema`,`needsApproval`,`onCompact`,`retentionPolicy`],t);let o=i.inputSchema===void 0?null:Fi(i.inputSchema),s={description:r(i.description,t),execute:l(i.execute,t),inputSchema:o};if(i.onCompact!==void 0&&l(i.onCompact,t),i.needsApproval!==void 0&&l(i.needsApproval,t),i.retentionPolicy!==void 0){let e=i.retentionPolicy;if(e!==`auto`&&e!==`keep`&&typeof e!=`function`)throw Error(`${t} Expected \`retentionPolicy\` to be "auto", "keep", or a function.`)}return{kind:`tool`,definition:s}}async function Li(e,t){let n=Ii(await z({agentRoot:e,kind:`tool`,source:t}),`Expected the tool export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`),r=j(t.logicalPath).replace(/^tools\//,``).replaceAll(`/`,`-`);return n.kind===`disabled`?{kind:`disabled`,name:r}:{kind:`tool`,definition:{description:n.definition.description,exportName:t.exportName,inputSchema:n.definition.inputSchema??null,logicalPath:t.logicalPath,name:r,sourceId:t.sourceId,sourceKind:`module`}}}async function Ri(e){let t={modelCatalog:Gr(e.appRoot)},[n,r]=await Promise.all([zi(e,t),Mi({appRoot:e.appRoot,compileAgentNodeManifest:zi,context:t,parentNodeId:L,subagents:e.subagents})]);return mr({...n,subagentEdges:r.edges,subagents:r.nodes})}async function zi(e,t){let n=await Promise.all(e.tools.map(t=>Li(e.agentRoot,t))),r=[],i=[];for(let e of n)e.kind===`tool`?r.push(e.definition):i.push(e.name);let[a,o]=await Promise.all([Promise.all(e.channels.map(t=>ai(e.agentRoot,t))),si(e.agentRoot,e.channels)]),s=a.flat();return dr({agentRoot:e.agentRoot,appRoot:e.appRoot,channels:s,config:await $r(e,t),connections:await Promise.all(e.connections.map(t=>bi(e.agentRoot,t))),diagnosticsSummary:e.diagnosticsSummary,disabledFrameworkTools:i,hooks:e.hooks.map(e=>Si(e)),sandbox:e.sandbox===null?null:await Ti(e.agentRoot,e.sandbox),sandboxWorkspaces:e.sandboxWorkspaces.map(e=>({logicalPath:e.logicalPath,rootEntries:[...e.rootEntries],sourceId:e.sourceId,sourcePath:e.sourcePath})),schedules:await Promise.all(e.schedules.map(t=>Di(e.agentRoot,t,o))),skills:await Promise.all(e.skills.map(t=>Ai(e.agentRoot,t))),instructions:e.instructions===void 0?void 0:await Ei(e.agentRoot,e.instructions),tools:r})}const Bi=`workspace-resources`;async function Vi(e){let t=S(e.compileDirectoryPath,Bi);await ve(t,{force:!0,recursive:!0});let n=await Ui({nodeId:L,resourcesRoot:t,manifest:e.manifest}),r=await Promise.all(e.manifest.subagents.map(async e=>({...e,agent:await Ui({nodeId:e.nodeId,resourcesRoot:t,manifest:e.agent})})));return{...n,kind:e.manifest.kind,subagentEdges:e.manifest.subagentEdges,subagents:r,version:e.manifest.version}}function Hi(e,t){return{logicalPath:O(S(Bi,t)),rootEntries:fr({sandboxWorkspaces:e.sandboxWorkspaces,skills:e.skills})}}async function Ui(e){for(let t of e.manifest.sandboxWorkspaces)if(t.rootEntries.some(e=>e===`skills/`||e===`skills`))throw Error(`Sandbox workspace "${t.logicalPath}" cannot define "skills" because Ash manages that workspace entry.`);let t=S(e.resourcesRoot,e.nodeId);await w(t,{recursive:!0});for(let n of e.manifest.sandboxWorkspaces)await he(n.sourcePath,t,{recursive:!0});for(let n of e.manifest.skills)await Wi({nodeRoot:t,skill:n});return{...e.manifest,workspaceResourceRoot:Hi(e.manifest,e.nodeId)}}async function Wi(e){let t=S(e.nodeRoot,`skills`,e.skill.name);if(e.skill.sourceKind===`skill-package`){await he(e.skill.rootPath,t,{recursive:!0});return}let n=S(t,`SKILL.md`);await w(x(n),{recursive:!0}),await T(n,e.skill.markdown)}function Gi(e){let t=C(e),n=S(t,`.ash`,`discovery`),r=S(t,`.ash`,`compile`);return{appRoot:t,compiledManifestPath:S(r,`compiled-agent-manifest.json`),compileDirectoryPath:r,compileMetadataPath:S(r,`compile-metadata.json`),diagnosticsPath:S(n,`diagnostics.json`),discoveryManifestPath:S(n,`agent-discovery-manifest.json`),discoveryDirectoryPath:n,moduleMapPath:S(r,`module-map.mjs`)}}function Ki(e){return{diagnostics:[...e],kind:`ash-discovery-diagnostics`,summary:Le(e),version:1}}function qi(e){let t=v(),n=Yi(e.discoveryManifestJson),r=Yi(e.diagnosticsArtifactJson),i=Yi(e.moduleMapSource);return{compile:{moduleMap:{path:Zi(e.appRoot,e.paths.moduleMapPath),sha256:i}},discovery:{diagnostics:{path:Zi(e.appRoot,e.paths.diagnosticsPath),sha256:r},manifest:{path:Zi(e.appRoot,e.paths.discoveryManifestPath),sha256:n},sourceGraphHash:Yi(`${n}:${r}:${i}`),summary:e.diagnosticsSummary},generator:{name:t.name,version:t.version},kind:`ash-compile-metadata`,status:e.diagnosticsSummary.errors>0?`failed`:`ready`,version:5}}async function Ji(e){let t=Gi(e.appRoot),n=Ki(e.diagnostics),r=await Vi({compileDirectoryPath:t.compileDirectoryPath,manifest:await Ri(e.manifest)}),i=Xi(r),a=Xi(e.manifest),o=Xi(n),s=Dr({manifest:r,moduleMapPath:t.moduleMapPath}),c=qi({appRoot:e.appRoot,diagnosticsArtifactJson:o,diagnosticsSummary:n.summary,discoveryManifestJson:a,moduleMapSource:s,paths:t}),l=Xi(c);return await w(t.discoveryDirectoryPath,{recursive:!0}),await w(t.compileDirectoryPath,{recursive:!0}),await Promise.all([T(t.compiledManifestPath,i),T(t.diagnosticsPath,o),T(t.discoveryManifestPath,a),T(t.moduleMapPath,s),T(t.compileMetadataPath,l)]),{compiledManifest:r,diagnosticsArtifact:n,metadata:c,moduleMapSource:s,paths:t}}function Yi(e){return be(`sha256`).update(e).digest(`hex`)}function Xi(e){return`${JSON.stringify(e,null,2)}\n`}function Zi(e,t){return O(fe(C(e),t))}var Qi=class extends Error{result;constructor(e){super(ta({diagnostics:e.diagnostics,diagnosticsPath:e.paths.diagnosticsPath})),this.name=`CompileAgentError`,this.result=e}};async function $i(e={}){let t=e.source??I(),n=await Mn(e.startPath,{source:t}),r=await kn({...n,source:t}),i=await Ji({appRoot:n.appRoot,diagnostics:r.diagnostics,manifest:r.manifest}),a={diagnostics:r.diagnostics,manifest:i.compiledManifest,metadata:i.metadata,paths:i.paths,project:n};if(Re(r.diagnostics))throw new Qi(a);return ea(r.diagnostics),a}function ea(e){let t=e.filter(e=>e.severity===`warning`);if(t.length!==0)for(let e of t)console.warn(`Warning [${e.code}]: ${e.message}\n source: ${e.sourcePath}`)}function ta(e){let t=Le(e.diagnostics),n=[`Discovery failed with ${t.errors} error(s) and ${t.warnings} warning(s).`];if(e.diagnosticsPath!==void 0&&n.push(`Diagnostics artifact: ${e.diagnosticsPath}`),e.diagnostics.length===0)return n.join(`
8
8
  `);n.push(`Discovery diagnostics:`);for(let t of e.diagnostics)n.push(`- ${na(t.severity)}: ${t.message}`),n.push(` source: ${t.sourcePath}`);return n.join(`
9
9
  `)}function na(e){return e===`error`?`Error`:`Warning`}const ra=new Map;var B=class{name;codec;constructor(e,t={}){this.name=e,this.codec=t.codec,ra.set(e,this)}};const ia=Symbol.for(`experimental-ash.context-storage`),aa=globalThis;aa[ia]===void 0&&(aa[ia]=new Ce);const oa=aa[ia];function V(){let e=oa.getStore();if(e===void 0)throw Error(`No active Ash context. Call this function only from authored runtime code such as tools, steps, and model callbacks.`);return e}function sa(e){return{debug(t,n){pa(`debug`,e,t,n)},info(t,n){pa(`info`,e,t,n)},warn(t,n){pa(`warn`,e,t,n)},error(t,n){pa(`error`,e,t,n),ha(t,n)}}}function ca(){return crypto.randomUUID()}function la(e,t){let n={errorId:t??ca(),message:da(e)},r=ua(e);return r!==void 0&&(n.name=r),n.detail=ga(e),n}function ua(e){if(e instanceof Error)return e.name===`Error`?void 0:e.name;if(f(e)&&p(e.name)&&e.name!==`Error`)return e.name}function da(e){return f(e)&&!(e instanceof Error)&&typeof e.message==`string`?e.message:Ee(e)}function fa(e,t){let n=t instanceof Error?t.message:Ee(t),r=t instanceof Error?t.name:`Error`;e.setStatus({code:we.ERROR,message:n}),e.recordException({message:n,name:r,stack:ga(t)})}function pa(e,t,n,r){let i=e===`error`?console.error:e===`warn`?console.warn:console.log,a=`[ash:${t}] ${n}`;if(r===void 0){i(a);return}i(a,ma(r))}function ma(e){let t={};for(let[n,r]of Object.entries(e))if(r!==void 0){if(r instanceof Error){t[n]=la(r);continue}t[n]=r}return t}function ha(e,t){let n=Te.getActiveSpan();if(n===void 0)return;let r=t?.error;if(r instanceof Error){fa(n,r);return}n.addEvent(e,t?ma(t):void 0)}function ga(e){return _a(De(e,{breakLength:1/0,compact:!1,depth:10,maxStringLength:8192}),16384)}function _a(e,t){if(Buffer.byteLength(e,`utf8`)<=t)return e;let n=e.slice(0,t);for(;Buffer.byteLength(n,`utf8`)>t&&n.length>0;)n=n.slice(0,-1);return`${n}<…truncated>`}function va(e){if(e.message!==void 0)return{inputResponses:e.inputResponses,message:e.message};if(e.inputResponses!==void 0&&e.inputResponses.length>0)return{inputResponses:e.inputResponses}}function ya(e){return e.kind??`unknown`}const ba={kind:`http`},xa={kind:`schedule`};new B(`ash.auth`),new B(`ash.initiatorAuth`);const Sa=new B(`ash.sessionId`),Ca=new B(`ash.continuationToken`);new B(`ash.mode`),new B(`ash.parentSession`),new B(`ash.capabilities`),new B(`ash.sessionPrepared`);const wa=sa(`execution.subagent-adapter`),Ta=new Map;function Ea(e){return Ta.get(e)}function Da(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.callId==`string`&&t.callId.length>0&&typeof t.parentContinuationToken==`string`&&t.parentContinuationToken.length>0&&typeof t.parentSessionId==`string`&&typeof t.subagentName==`string`&&t.subagentName.length>0}const Oa={kind:`subagent`,async"input.requested"(e,t){let n=t.state;Da(n)&&await ka({hookPayload:{callId:n.callId,childContinuationToken:t.ctx.require(Ca),childSessionId:t.ctx.require(Sa),event:{requests:e.requests,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},kind:`subagent-input-request`,subagentName:n.subagentName},parentContinuationToken:n.parentContinuationToken})}};async function ka(e){"use step";let t=Ea(e.hookPayload.childContinuationToken);try{if(t!==void 0){t(e.hookPayload);return}await Se(e.parentContinuationToken,e.hookPayload)}catch(t){let n=ca();throw wa.warn(`failed to forward proxied HITL batch to parent`,{callId:e.hookPayload.callId,childContinuationToken:e.hookPayload.childContinuationToken,childSessionId:e.hookPayload.childSessionId,errorId:n,parentContinuationToken:e.parentContinuationToken,subagentName:e.hookPayload.subagentName,error:t}),t}}var H=class extends Error{registry;entryName;logicalPath;sourceId;constructor(e,t,n={}){super(t),this.name=`RuntimeRegistryError`,this.registry=e,n.entryName!==void 0&&(this.entryName=n.entryName),n.logicalPath!==void 0&&(this.logicalPath=n.logicalPath),n.sourceId!==void 0&&(this.sourceId=n.sourceId)}},Aa=class{registry;_entries=new Map;_reserved;constructor(e,t=[]){this.registry=e,this._reserved=new Set(t)}get size(){return this._entries.size}has(e){return this._entries.has(e)}get(e){return this._entries.get(e)??null}asMap(){return this._entries}register(e,t,n={}){if(this._entries.has(e))throw new H(this.registry,n.duplicateMessage??`Duplicate ${this.registry} name "${e}".`,{...n.location,entryName:e});if(this._reserved.has(e))throw new H(this.registry,n.reservedMessage??`${ja(this.registry)} "${e}" collides with another runtime-visible name.`,{...n.location,entryName:e});this._entries.set(e,t),this._reserved.add(e)}set(e,t){this._entries.set(e,t),this._reserved.add(e)}};function ja(e){return e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1)}const Ma=[ba,Oa,xa],Na=new Set([`kind`,`state`,`deliver`,`contextProviders`,`createAdapterContext`,`fetchFile`]);function Pa(e){let t=new Map,n=new Set;for(let e of Ma){let r=Ia(e);n.add(r),t.set(r,e)}for(let r of e.channels){if(r.adapter===void 0)continue;let e={logicalPath:r.logicalPath,sourceId:r.sourceId},i=r.adapter,a=Ia(i,e);if(n.has(a)){if(La(i))throw new H(`adapter`,`Channel adapter kind "${a}" is reserved by the framework. A route-declared adapter may share a framework kind only as a pass-through with no \`deliver\` hook, event handlers, \`attachments\` resolver, \`contextProviders\`, or \`createAdapterContext\` factory. Use a custom \`kind\` to add channel-specific behavior.`,{...e,entryName:a});continue}t.set(a,i)}return{adaptersByKind:t}}function Fa(e,t){let n=t,r=e.adaptersByKind.get(n.kind);if(r===void 0)throw Error(`Unknown adapter kind: "${n.kind}". Declare the adapter on the route that starts this session so the runtime can rehydrate it.`);return{...r,state:n.state}}function Ia(e,t){let n=ya(e);if(n===`unknown`)throw new H(`adapter`,"Adapters must declare a non-empty `kind` field.",{entryName:`unknown`,logicalPath:t?.logicalPath,sourceId:t?.sourceId});return n}function La(e){if(e.deliver!==void 0||e.fetchFile!==void 0||e.createAdapterContext!==void 0||e.contextProviders!==void 0&&e.contextProviders.length>0)return!0;for(let[t,n]of Object.entries(e))if(!Na.has(t)&&typeof n==`function`)return!0;return!1}function Ra(e,t={}){return t.moduleMapLoadMode!==void 0||t.moduleMapLoaderPath!==void 0?{appRoot:e,kind:`disk`,moduleMapLoaderPath:t.moduleMapLoaderPath,moduleMapLoadMode:t.moduleMapLoadMode}:{appRoot:e,kind:`disk`}}function za(e){return e.kind===`disk`?e.appRoot:void 0}function Ba(e){return e.kind===`disk`?e.moduleMapLoadMode===void 0?`disk:${e.appRoot}`:e.moduleMapLoaderPath===void 0?`disk:${e.appRoot}:${e.moduleMapLoadMode}`:`disk:${e.appRoot}:${e.moduleMapLoadMode}:${e.moduleMapLoaderPath}`:`bundled`}function U(e){let t=Va(e),n=`${t}/.ash/discovery`,r=`${t}/.ash/compile`;return{appRoot:t,compiledManifestPath:`${r}/compiled-agent-manifest.json`,compileDirectoryPath:r,compileMetadataPath:`${r}/compile-metadata.json`,diagnosticsPath:`${n}/diagnostics.json`,discoveryDirectoryPath:n,discoveryManifestPath:`${n}/agent-discovery-manifest.json`,moduleMapPath:`${r}/module-map.mjs`}}function Va(e){let t=e.replaceAll(`\\`,`/`);return t===`/`?t:t.replace(/\/+$/,``)}function Ha(e){return Oe(e,{prefix:void 0}).message}function Ua(e=`test-session`){return{bundleCache:new Map,bundleCacheKeyBySourceKey:new Map,compiledArtifacts:null,id:e}}const Wa=Symbol.for(`experimental-ash.runtime-session-storage`),Ga=Symbol.for(`experimental-ash.runtime-session-default`),W=globalThis;W[Wa]===void 0&&(W[Wa]=new Ce);const Ka=W[Wa];function qa(){return W[Ga]===void 0&&(W[Ga]=Ua(`process-default`)),W[Ga]}function Ja(){return Ka.getStore()??qa()}function Ya(){return Ja().compiledArtifacts}const Xa=b.object({path:b.string(),sha256:b.string()}).strict(),Za=b.object({compile:b.object({moduleMap:Xa}).strict(),discovery:b.object({diagnostics:Xa,manifest:Xa,sourceGraphHash:b.string(),summary:b.object({errors:b.number().finite(),warnings:b.number().finite()}).strict()}).strict(),generator:b.object({name:b.string(),version:b.string()}).strict(),kind:b.literal(`ash-compile-metadata`),status:b.union([b.literal(`failed`),b.literal(`ready`)]),version:b.literal(5)}).strict();var Qa=class extends Error{metadataPath;constructor(e,t){super(e),this.name=`LoadCompileMetadataError`,t!==void 0&&(this.metadataPath=t)}};async function $a(e){let t=e.metadataPath??(e.compiledArtifactsSource.kind===`disk`?U(e.compiledArtifactsSource.appRoot).compileMetadataPath:void 0);if(t!==void 0){let{readFile:e}=await import(`node:fs/promises`),n;try{n=JSON.parse(await e(t,`utf8`))}catch(e){throw new Qa(to(e),t)}return eo(n,t)}let n=Ya()?.metadata;return n===void 0?null:eo(n,`bundled compile metadata`)}function eo(e,t){let n=Za.safeParse(e);if(!n.success)throw new Qa(`Expected "${t}" to contain valid Ash compile metadata. ${Ha(n.error)}`,t);return n.data}function to(e){return e instanceof Error?e.message:`Unknown compile metadata load failure.`}async function no(e){let t=Ba(e),n=await ro(e);try{let r=(await $a({compiledArtifactsSource:e}))?.discovery.sourceGraphHash;return r===void 0||r.length===0?n===void 0?t:`${t}:mtime-${io(n)}`:n===void 0?`${t}:${r}`:`${t}:${r}:mtime-${io(n)}`}catch{return n===void 0?t:`${t}:mtime-${io(n)}`}}async function ro(e){if(e.kind!==`disk`)return;let{stat:t}=await import(`node:fs/promises`),{compileMetadataPath:n}=U(e.appRoot);try{return(await t(n)).mtimeMs}catch{return}}function io(e){return Math.floor(e).toString(36)}const ao=`__root__`;function oo(e,t){if(t===void 0||t===`__root__`)return e.root;let n=e.nodesByNodeId.get(t);if(n===void 0)throw Error(`Missing runtime agent node for node id "${t}".`);return n}const so=`bundled compiled manifest`;var co=class extends Error{manifestPath;constructor(e,t){super(e),this.name=`LoadCompiledManifestError`,t!==void 0&&(this.manifestPath=t)}};async function lo(e){let t=e.manifestPath??(e.compiledArtifactsSource.kind===`disk`?U(e.compiledArtifactsSource.appRoot).compiledManifestPath:void 0);if(t!==void 0){let{readFile:e}=await import(`node:fs/promises`),n;try{n=JSON.parse(await e(t,`utf8`))}catch(e){throw new co(fo(e),t)}return uo(n,t)}let n=Ya();if(n!==null)return uo(n.manifest,so);throw new co(`Compiled manifest is unavailable without an app root or bundled compiled artifacts.`,so)}function uo(e,t){let n=ur.safeParse(e);if(!n.success)throw new co(`Expected "${t}" to contain a valid compiled Ash agent manifest. ${Ha(n.error)}`,t);return n.data}function fo(e){return e instanceof Error?e.message:`Unknown manifest load failure.`}const po=`bundled compiled module map`;var mo=class extends Error{moduleMapPath;constructor(e,t){super(e),this.name=`LoadCompiledModuleMapError`,t!==void 0&&(this.moduleMapPath=t)}};async function ho(e){let t=e.moduleMapPath??(e.compiledArtifactsSource.kind===`disk`?U(e.compiledArtifactsSource.appRoot).moduleMapPath:void 0);if(t!==void 0){let e=vo(t);try{let n=await import(e);return go(n.moduleMap??n.default,t)}catch(e){throw new mo(_o(e),t)}}let n=Ya();if(n!==null)return go(n.moduleMap,po);throw new mo(`Compiled module map is unavailable without an app root or bundled compiled artifacts.`,po)}function go(e,t){let n=Er.safeParse(e);if(!n.success)throw new mo(`Expected "${t}" to export a valid compiled Ash module map. ${Ha(n.error)}`,t);return n.data}function _o(e){return e instanceof Error?e.message:`Unknown module-map load failure.`}function vo(e){let t=e.replaceAll(`\\`,`/`);return/^[A-Za-z]:\//.test(t)?`file:///${encodeURI(t)}`:t.startsWith(`/`)?`file://${encodeURI(t)}`:t}const G=`/workspace`;function yo(e){return e.length===0?null:[`Available skills`,`Listed skills are available in this run. Do not claim a listed skill is inaccessible unless activation or workspace inspection actually fails.`,`If the user names a skill or the request clearly matches one of the descriptions below, call load_skill before proceeding.`,`If multiple skills match, activate the minimal set that covers the task. After activation, follow the returned instructions instead of improvising around them.`,`If activation fails, say so briefly and continue with the best fallback. Packaged sibling files under a skill path can be inspected with bash or read_file when needed.`,...e.map(e=>bo(e))].join(`
10
10
  `)}function bo(e){return`- ${e.name}: ${e.description} (path: ${G}/skills/${e.name}/SKILL.md)`}function xo(e){if(e.rootEntries.length!==0)return[`Workspace`,`- You have access to authored files mounted at the workspace root for this run.`,`- The live workspace root visible to \`bash\` in this run is \`${G}\`.`,`- Root entries under ${G}/:`,...e.rootEntries.map(e=>` - ${e}`),`- Treat \`${G}\` as the workspace root for this run unless a \`bash\` call shows otherwise.`,"- For questions about workspace paths or file availability, verify with `bash` first using commands like `pwd`, `ls`, and `find`.","- Use the `bash` tool with `ls`, `find`, and `rg` to inspect deeper contents when needed.",`- Do not claim these files are unavailable unless a workspace or tool call actually fails.`].join(`
@@ -1,4 +1,4 @@
1
- import{E as e,S as t,T as n,_ as r,a as i,c as a,d as o,g as s,h as c,l,m as u,p as ee,s as te,u as d,x as f,y as p}from"./paths-BYaK6-t0.js";import{t as m}from"./authored-module-loader-Pt_g8xX2.js";import{t as h}from"./errors-DsO9xmQL.js";import{i as g,t as _}from"./package-DmsQgn4v.js";import{join as v,posix as y}from"node:path";import{mkdir as ne,readFile as re,readdir as ie,realpath as b,writeFile as x}from"node:fs/promises";import{createHash as S}from"node:crypto";import{existsSync as C}from"node:fs";function w(e){return e.dev?{appRoot:e.appRoot,dev:e.dev,moduleMapLoaderPath:g(`src/internal/authored-module-map-loader.ts`)}:{appRoot:e.appRoot,dev:e.dev}}const T=`#ash-channel/`;function E(e){let t=e.compileResult.manifest.channels,n=new Set,r=[],i=new Set,o=a();for(let e of t){if(e.kind===`disabled`){if(!o.has(e.name))throw Error(`agent/channels/${e.name}.ts exports disableRoute() but "${e.name}" is not a framework channel. Rename the file to one of: ${[...o].sort().join(`, `)}.`);i.add(e.name);continue}n.add(e.name),r.push({method:e.method,route:e.urlPath})}let s=l().filter(e=>!n.has(e.name)&&!i.has(e.name)).map(e=>({method:e.method,route:e.urlPath})),c=new Set,u=[];for(let e of[...s,...r]){let t=k(e);c.has(t)||(c.add(t),u.push(e))}return u}function D(e,t){for(let n of t.registrations)A(e,{artifactsConfig:t.artifactsConfig,method:n.method,route:n.route})}function O(e,t){return N(t.previous,t.next)?!1:(j(e),D(e,{artifactsConfig:t.artifactsConfig,registrations:t.next}),e.routing.sync(),!0)}function k(e){return`${e.method.toUpperCase()} ${e.route}`}function A(e,t){let r=k(t),i=`${T}${r}`,a=n(g(`src/internal/nitro/routes/channel-dispatch.ts`));e.options.handlers.push({handler:i,method:t.method,route:t.route}),e.options.virtual[i]=[`import { dispatchChannelRequest } from ${a};`,`const config = ${JSON.stringify(t.artifactsConfig)};`,`export default (event) => dispatchChannelRequest(event, ${JSON.stringify(r)}, config);`].join(`
1
+ import{E as e,S as t,T as n,_ as r,a as i,c as a,d as o,g as s,h as c,l,m as u,p as ee,s as te,u as d,x as f,y as p}from"./paths-Bkj-KERk.js";import{t as m}from"./authored-module-loader-Pt_g8xX2.js";import{t as h}from"./errors-DsO9xmQL.js";import{i as g,t as _}from"./package-DmsQgn4v.js";import{join as v,posix as y}from"node:path";import{mkdir as ne,readFile as re,readdir as ie,realpath as b,writeFile as x}from"node:fs/promises";import{createHash as S}from"node:crypto";import{existsSync as C}from"node:fs";function w(e){return e.dev?{appRoot:e.appRoot,dev:e.dev,moduleMapLoaderPath:g(`src/internal/authored-module-map-loader.ts`)}:{appRoot:e.appRoot,dev:e.dev}}const T=`#ash-channel/`;function E(e){let t=e.compileResult.manifest.channels,n=new Set,r=[],i=new Set,o=a();for(let e of t){if(e.kind===`disabled`){if(!o.has(e.name))throw Error(`agent/channels/${e.name}.ts exports disableRoute() but "${e.name}" is not a framework channel. Rename the file to one of: ${[...o].sort().join(`, `)}.`);i.add(e.name);continue}n.add(e.name),r.push({method:e.method,route:e.urlPath})}let s=l().filter(e=>!n.has(e.name)&&!i.has(e.name)).map(e=>({method:e.method,route:e.urlPath})),c=new Set,u=[];for(let e of[...s,...r]){let t=k(e);c.has(t)||(c.add(t),u.push(e))}return u}function D(e,t){for(let n of t.registrations)A(e,{artifactsConfig:t.artifactsConfig,method:n.method,route:n.route})}function O(e,t){return N(t.previous,t.next)?!1:(j(e),D(e,{artifactsConfig:t.artifactsConfig,registrations:t.next}),e.routing.sync(),!0)}function k(e){return`${e.method.toUpperCase()} ${e.route}`}function A(e,t){let r=k(t),i=`${T}${r}`,a=n(g(`src/internal/nitro/routes/channel-dispatch.ts`));e.options.handlers.push({handler:i,method:t.method,route:t.route}),e.options.virtual[i]=[`import { dispatchChannelRequest } from ${a};`,`const config = ${JSON.stringify(t.artifactsConfig)};`,`export default (event) => dispatchChannelRequest(event, ${JSON.stringify(r)}, config);`].join(`
2
2
  `)}function j(e){for(let t=e.options.handlers.length-1;t>=0;--t){let n=e.options.handlers[t];n!==void 0&&M(n)&&e.options.handlers.splice(t,1)}for(let t of Object.keys(e.options.virtual))t.startsWith(T)&&delete e.options.virtual[t]}function M(e){return e.handler.startsWith(T)}function N(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1){let r=e[n],i=t[n];if(r===void 0||i===void 0||r.method!==i.method||r.route!==i.route)return!1}return!0}const P=`ash.schedule.`;var F=class extends Error{scheduleId;sourceId;taskName;constructor(e,t={}){super(e),this.name=`ScheduleRegistrationError`,t.scheduleId!==void 0&&(this.scheduleId=t.scheduleId),t.sourceId!==void 0&&(this.sourceId=t.sourceId),t.taskName!==void 0&&(this.taskName=t.taskName)}};function I(e){let t=e.map(e=>({cron:e.cron,description:`Run Ash schedule "${e.name}" from "${e.logicalPath}".`,logicalPath:e.logicalPath,scheduleId:e.name,sourceId:e.sourceId,taskName:R(e.sourceId)})).sort((e,t)=>e.sourceId.localeCompare(t.sourceId));return L(t),t}function L(e){let t=new Map;for(let n of e){let e=t.get(n.scheduleId);if(e===void 0){t.set(n.scheduleId,n);continue}throw new F(`Duplicate authored schedule id "${n.scheduleId}" found in "${e.logicalPath}" and "${n.logicalPath}".`,{scheduleId:n.scheduleId,sourceId:n.sourceId,taskName:n.taskName})}}function R(e){return`${P}${Buffer.from(e,`utf8`).toString(`base64url`)}`}const z=`#ash-schedule-task/`;function B(e,t){if(t.registrations.length!==0){e.options.experimental.tasks=!0;for(let n of t.registrations)U(e,{artifactsConfig:t.artifactsConfig,dispatchModulePath:t.dispatchModulePath,registration:n})}}function V(e,t){let n=!G(t.previous,t.next);return H(e),B(e,{artifactsConfig:t.artifactsConfig,dispatchModulePath:t.dispatchModulePath,registrations:t.next}),n}function H(e){for(let t of Object.keys(e.options.tasks))t.startsWith(`ash.schedule.`)&&delete e.options.tasks[t];for(let t of Object.keys(e.options.virtual))t.startsWith(z)&&delete e.options.virtual[t];for(let[t,n]of Object.entries(e.options.scheduledTasks)){let r=W(n).filter(e=>!e.startsWith(P));if(r.length===0){delete e.options.scheduledTasks[t];continue}if(r.length===1){let[n]=r;n!==void 0&&(e.options.scheduledTasks[t]=n);continue}e.options.scheduledTasks[t]=r}}function U(e,t){let r=`${z}${t.registration.taskName}`,i=n(t.dispatchModulePath);e.options.tasks[t.registration.taskName]={description:t.registration.description,handler:r},e.options.virtual[r]=[`import { dispatchScheduleTask } from ${i};`,`const config = ${JSON.stringify(t.artifactsConfig)};`,`export default {`,` meta: { description: ${JSON.stringify(t.registration.description)} },`,` async run(event) {`,` return { result: await dispatchScheduleTask(event.name, config) };`,` },`,`};`].join(`
3
3
  `),ae(e,t.registration.cron,t.registration.taskName)}function ae(e,t,n){let r=e.options.scheduledTasks[t];if(r===void 0){e.options.scheduledTasks[t]=n;return}if(typeof r==`string`){e.options.scheduledTasks[t]=[r,n];return}r.includes(n)||r.push(n)}function W(e){return typeof e==`string`?[e]:[...e]}function G(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1){let r=e[n],i=t[n];if(r===void 0||i===void 0||r.cron!==i.cron||r.description!==i.description||r.logicalPath!==i.logicalPath||r.scheduleId!==i.scheduleId||r.sourceId!==i.sourceId||r.taskName!==i.taskName)return!1}return!0}async function K(e){return[...e.manifest.schedules].map(e=>{let t={cron:e.cron,logicalPath:e.logicalPath,markdown:e.markdown,name:e.name,sourceId:e.sourceId,sourceKind:e.sourceKind};return e.channel===void 0?t:{...t,channel:e.channel}})}async function q(e){return await K({manifest:await o({compiledArtifactsSource:e.compiledArtifactsSource})})}async function J(e){let t=v(e.outDir,`compiled-artifacts-bootstrap.mjs`),n=v(e.outDir,`compiled-artifacts-instrumentation.mjs`),r=se(e.compileResult.manifest.agentRoot);await ne(e.outDir,{recursive:!0}),await x(t,await le({compileResult:e.compileResult,installModulePath:g(`src/runtime/loaders/bundled-artifacts.ts`),moduleMapPath:t,metadata:e.compileResult.metadata})),r!==void 0&&await x(n,ue({agentName:e.compileResult.manifest.config.name,instrumentationPath:r,registerConfigPath:g(`src/harness/instrumentation-config.ts`)}));let i={bootstrapPath:t};return r!==void 0&&(i.instrumentationPluginPath=n,i.instrumentationSourcePath=r),i}const oe=[`.ts`,`.mts`,`.js`,`.mjs`];function se(e){for(let t of oe){let n=v(e,`instrumentation${t}`);if(C(n))return n}}function ce(e){return e.replace(/^export const moduleMap = /m,`const moduleMap = `).replace(/\nexport default moduleMap;\n?$/,`
4
4
  `)}async function le(e){let r=ce(t({importSpecifierStyle:`absolute`,manifest:e.compileResult.manifest,moduleMapPath:e.moduleMapPath})).trim();return[`// Generated by Ash. Do not edit by hand.`,`import { installBundledCompiledArtifacts } from ${n(e.installModulePath)};`,``,r,``,`const metadata = ${JSON.stringify(e.metadata,null,2)};`,``,`const manifest = ${JSON.stringify(e.compileResult.manifest,null,2)};`,``,`export function installCompiledArtifactsBootstrap() {`,` installBundledCompiledArtifacts({`,` manifest,`,` metadata,`,` moduleMap,`,` });`,`}`,``,`installCompiledArtifactsBootstrap();`,``,`// Default export satisfies the Nitro plugin contract so this file`,`// can be used directly as a Nitro plugin without a separate wrapper.`,`export default function installCompiledArtifactsPlugin() {`,` // Already installed on import above.`,`}`,``,`export async function __ashInstallCompiledArtifactsStep() {`,` "use step";`,` return null;`,`}`,``].join(`
@@ -1,2 +1,2 @@
1
- import{D as e,b as t,t as n,v as r,y as i}from"../../chunks/paths-BYaK6-t0.js";import{d as a,f as o,h as s}from"../../chunks/types-MZUhN0Zy.js";import{createCliTheme as c,renderCliBanner as l,renderCliSection as u}from"../ui/output.js";async function d(e){let t=await f(e);return{application:n(t?.project.appRoot??e),compiledState:t,messaging:{createSessionRoutePath:o,continueSessionRoutePattern:a,streamRoutePattern:s}}}async function f(n){try{return await i({startPath:n})}catch(n){if(n instanceof r)return n.result;if(n instanceof e||n instanceof t)return null;throw n}}function p(e,t){return`${e} ${t}${e===1?``:`s`}`}function m(e,t){return`${`${e} error${e===1?``:`s`}`}, ${`${t} warning${t===1?``:`s`}`}`}function h(e){switch(e){case`ready`:return`success`;case`failed`:return`danger`;default:return`warning`}}async function g(e,t){let n=await d(t),r=n.compiledState,i=n.application,a=c(),o=[{label:`App Root`,value:i.appRoot}],s=[{label:`Workflow Build`,value:i.workflowBuildDir},{label:`Output`,value:i.outputDir}],f=[];r===null?o.push({label:`Compile`,tone:`warning`,value:`unavailable`}):(o.push({label:`Agent Root`,value:r.project.agentRoot},{label:`Layout`,value:r.project.layout},{label:`Compile`,tone:h(r.metadata.status),value:r.metadata.status},{label:`Diagnostics`,tone:r.metadata.discovery.summary.errors>0?`danger`:r.metadata.discovery.summary.warnings>0?`warning`:`success`,value:m(r.metadata.discovery.summary.errors,r.metadata.discovery.summary.warnings)},{label:`Instructions`,value:r.manifest.instructions?.logicalPath??`none`},{label:`Skills`,value:p(r.manifest.skills.length,`skill`)}),s.unshift({label:`Compiled Manifest`,value:r.paths.compiledManifestPath},{label:`Discovery Manifest`,value:r.paths.discoveryManifestPath},{label:`Diagnostics`,value:r.paths.diagnosticsPath},{label:`Module Map`,value:r.paths.moduleMapPath},{label:`Metadata`,value:r.paths.compileMetadataPath}),f.push(r.manifest.instructions===void 0?{label:`Instructions`,value:`No instructions prompt discovered.`}:{label:`Instructions`,value:r.manifest.instructions.logicalPath})),e.log([l(a,{subtitle:`Resolved application paths and the active message contract.`,title:`Ash Info`}),``,u(a,{rows:o,title:`Application`}),``,u(a,{rows:s,title:`Artifacts`}),...r===null?[]:[``,u(a,{rows:f,title:`Instructions`})],``,u(a,{rows:[{label:`Workflow ID`,value:i.workflowId},{label:`Source Dir`,value:i.workflowSourceDir},{label:`Create`,tone:`info`,value:`POST ${n.messaging.createSessionRoutePath}`},{label:`Continue`,tone:`info`,value:`POST ${n.messaging.continueSessionRoutePattern}`},{label:`Stream`,tone:`info`,value:`GET ${n.messaging.streamRoutePattern}`}],title:`Messaging`})].join(`
1
+ import{D as e,b as t,t as n,v as r,y as i}from"../../chunks/paths-Bkj-KERk.js";import{d as a,f as o,h as s}from"../../chunks/types-MZUhN0Zy.js";import{createCliTheme as c,renderCliBanner as l,renderCliSection as u}from"../ui/output.js";async function d(e){let t=await f(e);return{application:n(t?.project.appRoot??e),compiledState:t,messaging:{createSessionRoutePath:o,continueSessionRoutePattern:a,streamRoutePattern:s}}}async function f(n){try{return await i({startPath:n})}catch(n){if(n instanceof r)return n.result;if(n instanceof e||n instanceof t)return null;throw n}}function p(e,t){return`${e} ${t}${e===1?``:`s`}`}function m(e,t){return`${`${e} error${e===1?``:`s`}`}, ${`${t} warning${t===1?``:`s`}`}`}function h(e){switch(e){case`ready`:return`success`;case`failed`:return`danger`;default:return`warning`}}async function g(e,t){let n=await d(t),r=n.compiledState,i=n.application,a=c(),o=[{label:`App Root`,value:i.appRoot}],s=[{label:`Workflow Build`,value:i.workflowBuildDir},{label:`Output`,value:i.outputDir}],f=[];r===null?o.push({label:`Compile`,tone:`warning`,value:`unavailable`}):(o.push({label:`Agent Root`,value:r.project.agentRoot},{label:`Layout`,value:r.project.layout},{label:`Compile`,tone:h(r.metadata.status),value:r.metadata.status},{label:`Diagnostics`,tone:r.metadata.discovery.summary.errors>0?`danger`:r.metadata.discovery.summary.warnings>0?`warning`:`success`,value:m(r.metadata.discovery.summary.errors,r.metadata.discovery.summary.warnings)},{label:`Instructions`,value:r.manifest.instructions?.logicalPath??`none`},{label:`Skills`,value:p(r.manifest.skills.length,`skill`)}),s.unshift({label:`Compiled Manifest`,value:r.paths.compiledManifestPath},{label:`Discovery Manifest`,value:r.paths.discoveryManifestPath},{label:`Diagnostics`,value:r.paths.diagnosticsPath},{label:`Module Map`,value:r.paths.moduleMapPath},{label:`Metadata`,value:r.paths.compileMetadataPath}),f.push(r.manifest.instructions===void 0?{label:`Instructions`,value:`No instructions prompt discovered.`}:{label:`Instructions`,value:r.manifest.instructions.logicalPath})),e.log([l(a,{subtitle:`Resolved application paths and the active message contract.`,title:`Ash Info`}),``,u(a,{rows:o,title:`Application`}),``,u(a,{rows:s,title:`Artifacts`}),...r===null?[]:[``,u(a,{rows:f,title:`Instructions`})],``,u(a,{rows:[{label:`Workflow ID`,value:i.workflowId},{label:`Source Dir`,value:i.workflowSourceDir},{label:`Create`,tone:`info`,value:`POST ${n.messaging.createSessionRoutePath}`},{label:`Continue`,tone:`info`,value:`POST ${n.messaging.continueSessionRoutePattern}`},{label:`Stream`,tone:`info`,value:`GET ${n.messaging.streamRoutePattern}`}],title:`Messaging`})].join(`
2
2
  `))}export{g as printApplicationInfo};
@@ -1,3 +1,3 @@
1
- import{t as e}from"../chunks/package-DmsQgn4v.js";import{createCliTheme as t,renderCliTaggedLine as n}from"./ui/output.js";import{i as r,n as i,r as a,t as o}from"../chunks/url-BVRhVE2O.js";import{resolve as s}from"node:path";async function c(){return(await import(`../chunks/host-D_hajFPO.js`).then(e=>e.t)).buildHost}async function l(){return(await import(`./commands/info.js`)).printApplicationInfo}async function u(){return(await import(`./dev/repl.js`)).runDevelopmentRepl}async function d(){return(await import(`../evals/cli/eval.js`)).runEvalCommand}async function f(){return(await import(`../chunks/host-D_hajFPO.js`).then(e=>e.t)).startHost}function p(e=process.cwd()){return s(e)}function m(e){return`Ash (v${e})`}function h(e){return e.name()===`info`||e.name()===`dev`}async function g(e){await new Promise((t,n)=>{let r=!1,i=()=>{process.off(`SIGINT`,a),process.off(`SIGTERM`,a)},a=()=>{r||(r=!0,i(),e.close().then(t,n))};process.once(`SIGINT`,a),process.once(`SIGTERM`,a)})}function _(e){if(!/^-?\d+$/.test(e))throw new r(`Expected a numeric port, received "${e}".`);let t=Number(e);if(!Number.isInteger(t))throw new r(`Expected a numeric port, received "${e}".`);if(t<0||t>65535)throw new r(`Expected a port between 0 and 65535, received "${e}".`);return t}function v(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function y(e){let t=e[1];return e[0]!==`dev`||e.length!==2||t===void 0||t.startsWith(`-`)?[...e]:[`dev`,`--url`,t]}function b(e){if(e.url){if(e.host!==void 0)throw new r(`The --host option cannot be used with --url.`);if(e.port!==void 0)throw new r(`The --port option cannot be used with --url.`);if(e.repl===!1)throw new r(`The --no-repl option cannot be used with --url.`);return e.url}}function x(r,a){let s=p(),y=e().version,x=new i,S=t();return x.name(`ash`).description(`Build and run an Ash application.`).version(y).showHelpAfterError().exitOverride().hook(`preAction`,(e,t)=>{h(t)&&r.log(m(y))}).configureOutput({writeErr:e=>{r.error(e.trimEnd())},writeOut:e=>{r.log(e.trimEnd())}}),x.command(`build`).description(`Build the current Ash application.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:e}=await import(`./dev/environment.js`);e(s);let t=await(a.buildHost??await c())(s);r.log(n(S,{message:`built output at ${t}`,tag:`build`,tone:`success`}))}),x.command(`dev`).description(`Start the Ash development server or connect the REPL to an existing URL.`).option(`--host <host>`,`Host interface to bind`).option(`--no-repl`,`Start the server without the interactive REPL`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,_).option(`--schedules`,`Run scheduled tasks during development (off by default)`).option(`-u, --url <url>`,`Connect the REPL to an existing server URL`,o).addHelpText(`after`,`
1
+ import{t as e}from"../chunks/package-DmsQgn4v.js";import{createCliTheme as t,renderCliTaggedLine as n}from"./ui/output.js";import{i as r,n as i,r as a,t as o}from"../chunks/url-BVRhVE2O.js";import{resolve as s}from"node:path";async function c(){return(await import(`../chunks/host-T9Qm64N8.js`).then(e=>e.t)).buildHost}async function l(){return(await import(`./commands/info.js`)).printApplicationInfo}async function u(){return(await import(`./dev/repl.js`)).runDevelopmentRepl}async function d(){return(await import(`../evals/cli/eval.js`)).runEvalCommand}async function f(){return(await import(`../chunks/host-T9Qm64N8.js`).then(e=>e.t)).startHost}function p(e=process.cwd()){return s(e)}function m(e){return`Ash (v${e})`}function h(e){return e.name()===`info`||e.name()===`dev`}async function g(e){await new Promise((t,n)=>{let r=!1,i=()=>{process.off(`SIGINT`,a),process.off(`SIGTERM`,a)},a=()=>{r||(r=!0,i(),e.close().then(t,n))};process.once(`SIGINT`,a),process.once(`SIGTERM`,a)})}function _(e){if(!/^-?\d+$/.test(e))throw new r(`Expected a numeric port, received "${e}".`);let t=Number(e);if(!Number.isInteger(t))throw new r(`Expected a numeric port, received "${e}".`);if(t<0||t>65535)throw new r(`Expected a port between 0 and 65535, received "${e}".`);return t}function v(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function y(e){let t=e[1];return e[0]!==`dev`||e.length!==2||t===void 0||t.startsWith(`-`)?[...e]:[`dev`,`--url`,t]}function b(e){if(e.url){if(e.host!==void 0)throw new r(`The --host option cannot be used with --url.`);if(e.port!==void 0)throw new r(`The --port option cannot be used with --url.`);if(e.repl===!1)throw new r(`The --no-repl option cannot be used with --url.`);return e.url}}function x(r,a){let s=p(),y=e().version,x=new i,S=t();return x.name(`ash`).description(`Build and run an Ash application.`).version(y).showHelpAfterError().exitOverride().hook(`preAction`,(e,t)=>{h(t)&&r.log(m(y))}).configureOutput({writeErr:e=>{r.error(e.trimEnd())},writeOut:e=>{r.log(e.trimEnd())}}),x.command(`build`).description(`Build the current Ash application.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:e}=await import(`./dev/environment.js`);e(s);let t=await(a.buildHost??await c())(s);r.log(n(S,{message:`built output at ${t}`,tag:`build`,tone:`success`}))}),x.command(`dev`).description(`Start the Ash development server or connect the REPL to an existing URL.`).option(`--host <host>`,`Host interface to bind`).option(`--no-repl`,`Start the server without the interactive REPL`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,_).option(`--schedules`,`Run scheduled tasks during development (off by default)`).option(`-u, --url <url>`,`Connect the REPL to an existing server URL`,o).addHelpText(`after`,`
2
2
  You can also pass a bare URL as the only argument, for example: ash dev https://example.com
3
3
  `).action(async e=>{let t=b(e),{loadDevelopmentEnvironmentFiles:i}=await import(`./dev/environment.js`);if(i(s),t){if(r.log(n(S,{message:`REPL connecting to ${t}`,tag:`dev`,tone:`info`})),!v()){r.log(n(S,{message:`Interactive REPL disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`}));return}r.log(``),await(a.runDevelopmentRepl??await u())({serverUrl:t});return}let o=await(a.startHost??await f())(s,{host:e.host,port:e.port,schedules:e.schedules===!0}),c=!1,l=async()=>{c||(c=!0,await o.close())};try{if(r.log(n(S,{message:`server listening at ${o.url}`,tag:`dev`,tone:`success`})),e.repl===!1)return await g({close:l});if(!v())return r.log(n(S,{message:`Interactive REPL disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`})),await g({close:l});r.log(``),await(a.runDevelopmentRepl??await u())({serverUrl:o.url})}finally{await l()}}),x.command(`info`).description(`Print resolved application information.`).action(async()=>{await(a.printApplicationInfo??await l())(r,s)}),x.command(`eval`).description(`Run eval suites against an Ash agent.`).option(`--suite <id...>`,`Suite IDs to run (repeatable)`).option(`--all`,`Run all discovered suites`).option(`--url <url>`,`Remote agent URL (skip local host startup)`).option(`--timeout <ms>`,`Per-case timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent case executions per suite`).option(`--json`,`Output results as JSON`).option(`--list-suites`,`List discovered suites and exit`).option(`--skip-report`,`Skip suite-defined reporters (e.g. Braintrust)`).action(async e=>{await(a.runEvalCommand??await d())(e,r)}),x}async function S(e=process.argv.slice(2),t=console,n={}){let r=x(t,n),i=e.length===0?[`info`]:y(e);try{await r.parseAsync(i,{from:`user`})}catch(e){if(e instanceof a){if(e.exitCode===0)return;throw Error(e.message)}throw e}}export{S as runCli};
@@ -1 +1 @@
1
- import{n as e}from"../../chunks/paths-BYaK6-t0.js";import{loadDevelopmentEnvironmentFiles as t}from"../../cli/dev/environment.js";import{a as n,n as r,t as i}from"../../chunks/client-BeZ_W7vl.js";import{n as a}from"../../chunks/host-D_hajFPO.js";import{discoverAndImportSuites as o,discoverSuiteFiles as s,importSuiteFile as c}from"../runner/discover.js";import{executeSuite as l}from"../runner/execute-suite.js";import{ConsoleReporter as u}from"../runner/reporters/console.js";var d=n();function f(e,t){e.command(`eval`).description(`Run eval suites against an Ash agent.`).option(`--suite <id...>`,`Suite IDs to run (repeatable)`).option(`--all`,`Run all discovered suites`).option(`--url <url>`,`Remote agent URL (skip local host startup)`).option(`--timeout <ms>`,`Per-case timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent case executions per suite`).option(`--json`,`Output results as JSON`).option(`--list-suites`,`List discovered suites and exit`).option(`--skip-report`,`Skip suite-defined reporters (e.g. Braintrust)`).action(async e=>{await p(e,t)})}async function p(n,r){let i=e();if(t(i),n.listSuites){await y(i,r);return}let s=n.suite,c=await o(i,s);if(c.length===0){s&&s.length>0?r.error(`No suites found matching: ${s.join(`, `)}`):r.error(`No eval suites found. Create suite files under evals/ with the *.eval.ts extension.`),process.exitCode=1;return}let u,d;n.url?d={kind:`remote`,url:n.url}:(u=await a(i,{host:`127.0.0.1`,port:0}),d={kind:`local`,url:u.url});let f=m(d);try{let e=[];for(let t of c){let r=_(t,n),a=v(r,{json:n.json===!0,skipReport:n.skipReport===!0}),o=await l({suite:r,target:d,reporters:a,appRoot:i,client:f});e.push(o)}n.json&&r.log(JSON.stringify(e,null,2)),e.some(e=>e.errored>0)&&(process.exitCode=1)}finally{u&&await u.close()}process.exit(process.exitCode??0)}function m(e){if(e.kind===`local`)return new i({host:e.url});let t={},n=process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();return n&&(t[r]=n),new i({auth:h(),headers:Object.keys(t).length>0?t:void 0,host:e.url})}function h(){let e=process.env.ASH_EVAL_AUTH_TOKEN?.trim();return e?{bearer:e}:{bearer:g}}async function g(){try{let e=(await(0,d.getVercelOidcToken)()).trim();if(e.length>0)return e}catch{}return process.env.VERCEL_OIDC_TOKEN?.trim()??``}function _(e,t){let n=t.maxConcurrency?Number.parseInt(t.maxConcurrency,10):void 0,r=t.timeout?Number.parseInt(t.timeout,10):void 0;if(n===void 0&&r===void 0)return e;let i={...e};return n!==void 0&&(i.maxConcurrency=n),r!==void 0&&(i.timeoutMs=r),i}function v(e,t){let n=t.json?[]:[new u];return!t.skipReport&&e.reporters&&n.push(...e.reporters),n}async function y(e,t){let n=await s(e);if(n.length===0){t.log(`No eval suites found.`);return}t.log(`Found ${n.length} eval suite file(s):\n`);for(let r of n){let n=await c(e,r);t.log(` ${n.id}${n.description?` - ${n.description}`:``}`)}}export{f as registerEvalCommand,p as runEvalCommand};
1
+ import{n as e}from"../../chunks/paths-Bkj-KERk.js";import{loadDevelopmentEnvironmentFiles as t}from"../../cli/dev/environment.js";import{a as n,n as r,t as i}from"../../chunks/client-BeZ_W7vl.js";import{n as a}from"../../chunks/host-T9Qm64N8.js";import{discoverAndImportSuites as o,discoverSuiteFiles as s,importSuiteFile as c}from"../runner/discover.js";import{executeSuite as l}from"../runner/execute-suite.js";import{ConsoleReporter as u}from"../runner/reporters/console.js";var d=n();function f(e,t){e.command(`eval`).description(`Run eval suites against an Ash agent.`).option(`--suite <id...>`,`Suite IDs to run (repeatable)`).option(`--all`,`Run all discovered suites`).option(`--url <url>`,`Remote agent URL (skip local host startup)`).option(`--timeout <ms>`,`Per-case timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent case executions per suite`).option(`--json`,`Output results as JSON`).option(`--list-suites`,`List discovered suites and exit`).option(`--skip-report`,`Skip suite-defined reporters (e.g. Braintrust)`).action(async e=>{await p(e,t)})}async function p(n,r){let i=e();if(t(i),n.listSuites){await y(i,r);return}let s=n.suite,c=await o(i,s);if(c.length===0){s&&s.length>0?r.error(`No suites found matching: ${s.join(`, `)}`):r.error(`No eval suites found. Create suite files under evals/ with the *.eval.ts extension.`),process.exitCode=1;return}let u,d;n.url?d={kind:`remote`,url:n.url}:(u=await a(i,{host:`127.0.0.1`,port:0}),d={kind:`local`,url:u.url});let f=m(d);try{let e=[];for(let t of c){let r=_(t,n),a=v(r,{json:n.json===!0,skipReport:n.skipReport===!0}),o=await l({suite:r,target:d,reporters:a,appRoot:i,client:f});e.push(o)}n.json&&r.log(JSON.stringify(e,null,2)),e.some(e=>e.errored>0)&&(process.exitCode=1)}finally{u&&await u.close()}process.exit(process.exitCode??0)}function m(e){if(e.kind===`local`)return new i({host:e.url});let t={},n=process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();return n&&(t[r]=n),new i({auth:h(),headers:Object.keys(t).length>0?t:void 0,host:e.url})}function h(){let e=process.env.ASH_EVAL_AUTH_TOKEN?.trim();return e?{bearer:e}:{bearer:g}}async function g(){try{let e=(await(0,d.getVercelOidcToken)()).trim();if(e.length>0)return e}catch{}return process.env.VERCEL_OIDC_TOKEN?.trim()??``}function _(e,t){let n=t.maxConcurrency?Number.parseInt(t.maxConcurrency,10):void 0,r=t.timeout?Number.parseInt(t.timeout,10):void 0;if(n===void 0&&r===void 0)return e;let i={...e};return n!==void 0&&(i.maxConcurrency=n),r!==void 0&&(i.timeoutMs=r),i}function v(e,t){let n=t.json?[]:[new u];return!t.skipReport&&e.reporters&&n.push(...e.reporters),n}async function y(e,t){let n=await s(e);if(n.length===0){t.log(`No eval suites found.`);return}t.log(`Found ${n.length} eval suite file(s):\n`);for(let r of n){let n=await c(e,r);t.log(` ${n.id}${n.description?` - ${n.description}`:``}`)}}export{f as registerEvalCommand,p as runEvalCommand};
@@ -6,7 +6,7 @@ import { ASH_PACKAGE_NAME } from "#package-name.js";
6
6
  let cachedPackageInfo;
7
7
  // The package build stamps the published version into `dist` so bundled
8
8
  // deployments can still report package metadata without resolving package.json.
9
- const BUNDLED_FALLBACK_PACKAGE_VERSION = "0.13.0";
9
+ const BUNDLED_FALLBACK_PACKAGE_VERSION = "0.14.1";
10
10
  const BUNDLED_FALLBACK_PACKAGE_VERSION_PLACEHOLDER = "__ASH_PACKAGE_VERSION_PLACEHOLDER__";
11
11
  const WORKFLOW_MODULE_ALIASES = {
12
12
  "workflow/api": "src/compiled/@workflow/core/runtime.js",
@@ -12,7 +12,7 @@ export function normalizeToolDefinition(value, message) {
12
12
  return { kind: "disabled" };
13
13
  }
14
14
  const record = expectObjectRecord(value, message);
15
- expectOnlyKnownKeys(record, ["description", "execute", "inputSchema", "needsApproval", "onCompact"], message);
15
+ expectOnlyKnownKeys(record, ["description", "execute", "inputSchema", "needsApproval", "onCompact", "retentionPolicy"], message);
16
16
  const inputSchema = record.inputSchema === undefined ? null : normalizeJsonSchemaDefinition(record.inputSchema);
17
17
  const definition = {
18
18
  description: expectString(record.description, message),
@@ -20,10 +20,11 @@ export function normalizeToolDefinition(value, message) {
20
20
  inputSchema,
21
21
  };
22
22
  /*
23
- * The compiler runs at build time and only validates that `onCompact` and
24
- * `needsApproval`, when present, are functions. The actual references are
25
- * captured later by `resolve-agent.ts` when it materializes the live module
26
- * export and attaches them to the ResolvedToolDefinition.
23
+ * The compiler runs at build time and only validates that optional hooks
24
+ * (`onCompact`, `needsApproval`, `retentionPolicy`), when present, have the
25
+ * expected shape. The live references are captured later by
26
+ * `resolve-agent.ts` when it materializes the module export and attaches
27
+ * them to the ResolvedToolDefinition.
27
28
  */
28
29
  if (record.onCompact !== undefined) {
29
30
  expectFunction(record.onCompact, message);
@@ -31,6 +32,12 @@ export function normalizeToolDefinition(value, message) {
31
32
  if (record.needsApproval !== undefined) {
32
33
  expectFunction(record.needsApproval, message);
33
34
  }
35
+ if (record.retentionPolicy !== undefined) {
36
+ const policy = record.retentionPolicy;
37
+ if (policy !== "auto" && policy !== "keep" && typeof policy !== "function") {
38
+ throw new Error(`${message} Expected \`retentionPolicy\` to be "auto", "keep", or a function.`);
39
+ }
40
+ }
34
41
  return {
35
42
  kind: "tool",
36
43
  definition,
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Minimal Twilio REST API wrapper used by the Twilio channel.
3
+ *
4
+ * Requests use Twilio's normal `application/x-www-form-urlencoded`
5
+ * body encoding and HTTP Basic auth. No Twilio SDK dependency is
6
+ * required or exposed through Ash public APIs.
7
+ */
8
+ import { type TwilioAuthToken } from "#public/channels/twilio/verify.js";
9
+ /** Twilio Account SID, materialized directly or from an async secret provider. */
10
+ export type TwilioAccountSid = string | (() => string | Promise<string>);
11
+ /** Fetch implementation override used by tests or non-standard runtimes. */
12
+ export type TwilioFetch = typeof fetch;
13
+ /** Credentials required for Twilio REST API calls and webhook verification. */
14
+ export interface TwilioCredentials {
15
+ readonly accountSid?: TwilioAccountSid;
16
+ readonly authToken?: TwilioAuthToken;
17
+ }
18
+ /** Shared Twilio REST API options. */
19
+ export interface TwilioApiOptions {
20
+ readonly credentials?: TwilioCredentials;
21
+ readonly apiBaseUrl?: string;
22
+ readonly fetch?: TwilioFetch;
23
+ }
24
+ /** Raw Twilio REST API response body. */
25
+ export interface TwilioApiResponse {
26
+ readonly status: number;
27
+ readonly ok: boolean;
28
+ readonly body: unknown;
29
+ }
30
+ /** Parameters for creating an outbound Twilio message. */
31
+ export interface TwilioSendMessageInput extends TwilioApiOptions {
32
+ readonly to: string;
33
+ readonly body: string;
34
+ readonly from?: string;
35
+ readonly messagingServiceSid?: string;
36
+ readonly statusCallbackUrl?: string;
37
+ }
38
+ /** Parameters for updating a live Twilio call with new TwiML. */
39
+ export interface TwilioUpdateCallInput extends TwilioApiOptions {
40
+ readonly callSid: string;
41
+ readonly twiml: string;
42
+ }
43
+ /** Resolves a Twilio Account SID, falling back to `TWILIO_ACCOUNT_SID`. */
44
+ export declare function resolveTwilioAccountSid(accountSid?: TwilioAccountSid): Promise<string>;
45
+ /**
46
+ * Calls Twilio's REST API with Basic auth and form-encoded body fields.
47
+ *
48
+ * `path` is relative to `https://api.twilio.com` by default and may be
49
+ * pointed elsewhere through `apiBaseUrl` for tests or proxies.
50
+ */
51
+ export declare function callTwilioApi(input: {
52
+ readonly credentials?: TwilioCredentials;
53
+ readonly apiBaseUrl?: string;
54
+ readonly fetch?: TwilioFetch;
55
+ readonly path: string;
56
+ readonly body: Readonly<Record<string, string | number | boolean | undefined | null>>;
57
+ }): Promise<TwilioApiResponse>;
58
+ /** Sends an outbound SMS/MMS-style message via Twilio's Messages resource. */
59
+ export declare function sendTwilioMessage(input: TwilioSendMessageInput): Promise<TwilioApiResponse>;
60
+ /** Updates a live Twilio call by posting replacement TwiML to the Calls resource. */
61
+ export declare function updateTwilioCall(input: TwilioUpdateCallInput): Promise<TwilioApiResponse>;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Minimal Twilio REST API wrapper used by the Twilio channel.
3
+ *
4
+ * Requests use Twilio's normal `application/x-www-form-urlencoded`
5
+ * body encoding and HTTP Basic auth. No Twilio SDK dependency is
6
+ * required or exposed through Ash public APIs.
7
+ */
8
+ import { resolveTwilioAuthToken } from "#public/channels/twilio/verify.js";
9
+ /** Resolves a Twilio Account SID, falling back to `TWILIO_ACCOUNT_SID`. */
10
+ export async function resolveTwilioAccountSid(accountSid) {
11
+ const source = accountSid ?? process.env.TWILIO_ACCOUNT_SID;
12
+ if (!source)
13
+ throw new Error("TWILIO_ACCOUNT_SID is required.");
14
+ return typeof source === "function" ? await source() : source;
15
+ }
16
+ /**
17
+ * Calls Twilio's REST API with Basic auth and form-encoded body fields.
18
+ *
19
+ * `path` is relative to `https://api.twilio.com` by default and may be
20
+ * pointed elsewhere through `apiBaseUrl` for tests or proxies.
21
+ */
22
+ export async function callTwilioApi(input) {
23
+ const accountSid = await resolveTwilioAccountSid(input.credentials?.accountSid);
24
+ const authToken = await resolveTwilioAuthToken(input.credentials?.authToken);
25
+ const apiFetch = input.fetch ?? fetch;
26
+ const url = `${input.apiBaseUrl ?? "https://api.twilio.com"}${input.path}`;
27
+ const body = encodeForm(input.body);
28
+ const response = await apiFetch(url, {
29
+ method: "POST",
30
+ headers: {
31
+ authorization: `Basic ${Buffer.from(`${accountSid}:${authToken}`).toString("base64")}`,
32
+ "content-type": "application/x-www-form-urlencoded;charset=UTF-8",
33
+ },
34
+ body,
35
+ });
36
+ return {
37
+ status: response.status,
38
+ ok: response.ok,
39
+ body: await parseResponseBody(response),
40
+ };
41
+ }
42
+ /** Sends an outbound SMS/MMS-style message via Twilio's Messages resource. */
43
+ export async function sendTwilioMessage(input) {
44
+ if (!input.from && !input.messagingServiceSid) {
45
+ throw new Error("twilioChannel: sending a message requires from or messagingServiceSid.");
46
+ }
47
+ const accountSid = await resolveTwilioAccountSid(input.credentials?.accountSid);
48
+ return callTwilioApi({
49
+ apiBaseUrl: input.apiBaseUrl,
50
+ credentials: input.credentials,
51
+ fetch: input.fetch,
52
+ path: `/2010-04-01/Accounts/${encodeURIComponent(accountSid)}/Messages.json`,
53
+ body: {
54
+ Body: input.body,
55
+ From: input.from,
56
+ MessagingServiceSid: input.messagingServiceSid,
57
+ StatusCallback: input.statusCallbackUrl,
58
+ To: input.to,
59
+ },
60
+ });
61
+ }
62
+ /** Updates a live Twilio call by posting replacement TwiML to the Calls resource. */
63
+ export async function updateTwilioCall(input) {
64
+ const accountSid = await resolveTwilioAccountSid(input.credentials?.accountSid);
65
+ return callTwilioApi({
66
+ apiBaseUrl: input.apiBaseUrl,
67
+ credentials: input.credentials,
68
+ fetch: input.fetch,
69
+ path: `/2010-04-01/Accounts/${encodeURIComponent(accountSid)}/Calls/${encodeURIComponent(input.callSid)}.json`,
70
+ body: { Twiml: input.twiml },
71
+ });
72
+ }
73
+ function encodeForm(body) {
74
+ const params = new URLSearchParams();
75
+ for (const [key, value] of Object.entries(body)) {
76
+ if (value === undefined || value === null)
77
+ continue;
78
+ params.set(key, String(value));
79
+ }
80
+ return params;
81
+ }
82
+ async function parseResponseBody(response) {
83
+ const text = await response.text();
84
+ if (!text)
85
+ return null;
86
+ try {
87
+ return JSON.parse(text);
88
+ }
89
+ catch {
90
+ return text;
91
+ }
92
+ }
@@ -0,0 +1,17 @@
1
+ import type { SessionAuthContext } from "#channel/types.js";
2
+ import type { TwilioTextMessage, TwilioVoiceCall, TwilioVoiceTranscription } from "#public/channels/twilio/inbound.js";
3
+ import type { TwilioChannelEvents, TwilioContext, TwilioInboundResult, TwilioVoiceResult } from "#public/channels/twilio/twilioChannel.js";
4
+ /** Default phone-number auth projection for Twilio webhook actors. */
5
+ export declare function defaultTwilioAuth(input: {
6
+ readonly from: string;
7
+ readonly to?: string;
8
+ readonly channel: "text" | "voice";
9
+ }): SessionAuthContext;
10
+ /** Default inbound text hook: dispatch with Twilio phone-number auth. */
11
+ export declare function defaultOnText(_ctx: TwilioContext, message: TwilioTextMessage): TwilioInboundResult;
12
+ /** Default inbound voice hook: accept the call with configured voice defaults. */
13
+ export declare function defaultOnVoice(_ctx: TwilioContext, _call: TwilioVoiceCall): TwilioVoiceResult;
14
+ /** Default inbound voice hook: dispatch with Twilio phone-number auth. */
15
+ export declare function defaultOnVoiceTranscription(_ctx: TwilioContext, transcription: TwilioVoiceTranscription): TwilioInboundResult;
16
+ /** Built-in Twilio event handlers for text delivery and terminal errors. */
17
+ export declare const defaultEvents: TwilioChannelEvents;
@@ -0,0 +1,69 @@
1
+ import { extractErrorId, formatErrorHint } from "#internal/logging.js";
2
+ /** Default phone-number auth projection for Twilio webhook actors. */
3
+ export function defaultTwilioAuth(input) {
4
+ const attributes = {
5
+ channel: input.channel,
6
+ from: input.from,
7
+ };
8
+ if (input.to !== undefined)
9
+ attributes.to = input.to;
10
+ return {
11
+ attributes,
12
+ authenticator: "twilio-webhook",
13
+ issuer: "twilio",
14
+ principalId: `twilio:${input.from}`,
15
+ principalType: "user",
16
+ };
17
+ }
18
+ /** Default inbound text hook: dispatch with Twilio phone-number auth. */
19
+ export function defaultOnText(_ctx, message) {
20
+ return {
21
+ auth: defaultTwilioAuth({
22
+ channel: "text",
23
+ from: message.from,
24
+ to: message.to,
25
+ }),
26
+ };
27
+ }
28
+ /** Default inbound voice hook: accept the call with configured voice defaults. */
29
+ export function defaultOnVoice(_ctx, _call) {
30
+ return {};
31
+ }
32
+ /** Default inbound voice hook: dispatch with Twilio phone-number auth. */
33
+ export function defaultOnVoiceTranscription(_ctx, transcription) {
34
+ return {
35
+ auth: defaultTwilioAuth({
36
+ channel: "voice",
37
+ from: transcription.from,
38
+ to: transcription.to,
39
+ }),
40
+ };
41
+ }
42
+ /** Built-in Twilio event handlers for text delivery and terminal errors. */
43
+ export const defaultEvents = {
44
+ async "message.completed"(event, ctx) {
45
+ if (event.finishReason === "tool-calls" || !event.message)
46
+ return;
47
+ await ctx.twilio.sendMessage(event.message);
48
+ },
49
+ async "turn.failed"(event, ctx) {
50
+ const hint = formatErrorHint(event);
51
+ const errorId = extractErrorId(event.details);
52
+ await ctx.twilio.sendMessage([
53
+ `I hit an error while handling your request${hint}.`,
54
+ "",
55
+ "Please try again, rephrase, or reach out if it keeps failing.",
56
+ ...(errorId ? ["", `Error id: ${errorId}`] : []),
57
+ ].join("\n"));
58
+ },
59
+ async "session.failed"(event, ctx) {
60
+ const hint = formatErrorHint(event);
61
+ const errorId = extractErrorId(event.details);
62
+ await ctx.twilio.sendMessage([
63
+ `This session could not recover from an error${hint}.`,
64
+ "",
65
+ "Start a new message to continue.",
66
+ ...(errorId ? ["", `Error id: ${errorId}`] : []),
67
+ ].join("\n"));
68
+ },
69
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Twilio inbound webhook parsing and prompt shaping.
3
+ *
4
+ * The channel owns these small data shapes instead of exposing raw
5
+ * Twilio webhook payloads as the public API surface.
6
+ */
7
+ import type { UserContent } from "ai";
8
+ /** Channel-owned representation of one inbound Twilio text message. */
9
+ export interface TwilioTextMessage {
10
+ readonly from: string;
11
+ readonly to: string | undefined;
12
+ readonly body: string;
13
+ readonly messageSid: string | undefined;
14
+ readonly accountSid: string | undefined;
15
+ readonly raw: URLSearchParams;
16
+ }
17
+ /** Channel-owned representation of one inbound Twilio voice call. */
18
+ export interface TwilioVoiceCall {
19
+ readonly from: string;
20
+ readonly to: string | undefined;
21
+ readonly callSid: string | undefined;
22
+ readonly accountSid: string | undefined;
23
+ readonly raw: URLSearchParams;
24
+ }
25
+ /** Channel-owned representation of one inbound Twilio voice transcription. */
26
+ export interface TwilioVoiceTranscription {
27
+ readonly from: string;
28
+ readonly to: string | undefined;
29
+ readonly callSid: string | undefined;
30
+ readonly text: string;
31
+ readonly confidence: number | undefined;
32
+ readonly transcriptionSid: string | undefined;
33
+ readonly raw: URLSearchParams;
34
+ }
35
+ /** Inbound identity and response guidance rendered into the model-visible `<twilio_context>` block. */
36
+ export interface TwilioInboundContext {
37
+ readonly from: string;
38
+ readonly to?: string;
39
+ readonly messageSid?: string;
40
+ readonly callSid?: string;
41
+ readonly channel: "text" | "voice";
42
+ }
43
+ /** Parses Twilio's incoming-message webhook fields. */
44
+ export declare function parseTwilioTextMessage(params: URLSearchParams): TwilioTextMessage | null;
45
+ /** Parses Twilio's incoming-call webhook fields. */
46
+ export declare function parseTwilioVoiceCall(params: URLSearchParams): TwilioVoiceCall | null;
47
+ /**
48
+ * Parses Twilio voice transcription fields.
49
+ *
50
+ * Supports `<Gather input="speech">` (`SpeechResult`), recording
51
+ * transcription callbacks (`TranscriptionText`), and real-time
52
+ * transcription callbacks (`TranscriptionData` JSON). Real-time partial
53
+ * results are ignored until Twilio marks them final.
54
+ */
55
+ export declare function parseTwilioVoiceTranscription(params: URLSearchParams): TwilioVoiceTranscription | null;
56
+ /** Renders a deterministic `<twilio_context>` block for the model. */
57
+ export declare function formatTwilioContextBlock(context: TwilioInboundContext): string;
58
+ /** Prepends a `<twilio_context>` block to the inbound turn message. */
59
+ export declare function prependTwilioContext(message: string | UserContent, context: TwilioInboundContext): string | UserContent;