experimental-ash 0.16.2 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/dist/docs/public/channels/README.md +71 -0
- package/dist/docs/public/schedules.md +35 -0
- package/dist/src/channel/cross-channel-receive.d.ts +61 -0
- package/dist/src/channel/cross-channel-receive.js +50 -0
- package/dist/src/channel/receive-args.d.ts +17 -0
- package/dist/src/channel/receive-args.js +1 -0
- package/dist/src/channel/routes.d.ts +9 -0
- package/dist/src/channel/schedule.js +8 -15
- package/dist/src/chunks/{dev-authored-source-watcher-D2Lz_4ud.js → dev-authored-source-watcher-B5J6JK7p.js} +1 -1
- package/dist/src/chunks/{host-B2D2qXsD.js → host-ByUKG--q.js} +2 -2
- package/dist/src/chunks/{paths-BYA-Yank.js → paths-CFoo44rU.js} +3 -3
- package/dist/src/chunks/{prewarm-C4x0CPRP.js → prewarm-BLFoNX7E.js} +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/run.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +8 -1
- package/dist/src/evals/cli/eval.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +2 -2
- package/dist/src/execution/sandbox/bindings/vercel.js +8 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +3 -0
- package/dist/src/public/channels/ash.d.ts +2 -2
- package/dist/src/public/channels/slack/attachments.d.ts +3 -0
- package/dist/src/public/channels/slack/attachments.js +6 -1
- package/dist/src/public/channels/slack/index.d.ts +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +24 -4
- package/dist/src/public/channels/slack/slackChannel.js +26 -4
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +2 -1
- package/dist/src/public/channels/upload-policy.d.ts +23 -16
- package/dist/src/public/channels/upload-policy.js +26 -9
- package/dist/src/public/definitions/sandbox.d.ts +3 -3
- package/dist/src/public/definitions/schedule.d.ts +2 -16
- package/dist/src/public/sandbox/backends/vercel.d.ts +5 -5
- package/dist/src/public/sandbox/backends/vercel.js +3 -3
- package/dist/src/public/sandbox/index.d.ts +2 -2
- package/dist/src/public/sandbox/vercel-sandbox.d.ts +13 -0
- package/dist/src/runtime/resolve-channel.js +1 -0
- package/dist/src/runtime/types.d.ts +8 -0
- package/dist/src/shared/sandbox-backend.d.ts +7 -7
- package/dist/src/shared/sandbox-definition.d.ts +7 -12
- package/package.json +1 -1
|
@@ -10,7 +10,7 @@ import{i as e}from"./chunk-8L7ocgPr.js";import{t}from"./gray-matter-BxS7ZG-J.js"
|
|
|
10
10
|
`)}function So(e){return`- ${e.name}: ${e.description} (path: ${G}/skills/${e.name}/SKILL.md)`}function Co(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(`
|
|
11
11
|
`)}function wo(e){return e instanceof Error&&e.name===`ConnectionAuthorizationRequiredError`}function To(e){return e instanceof Error&&e.name===`ConnectionAuthorizationFailedError`}function Eo(e){return e?.startAuthorization!==void 0}const Do=Object.freeze({__ashPlaceholder:`connection-authorization`}),Oo=new B(`ash.pendingConnectionToolCalls`);function ko(e,t){if(t.length===0)return e??[];let n=new Set,r=e??[];for(let e of r)n.add(e.toolCallId);let i=[...r];for(let e of t)n.has(e.toolCallId)||(n.add(e.toolCallId),i.push(e));return i}function Ao(e,t){return`${e}__${t}`}const jo=la(`framework.connection-search`),Mo=new B(`ash.connectionRegistry`),No=new B(`ash.pendingConnectionAuthorizations`),Po=new B(`ash.discoveredConnectionTools`),Fo={description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. linear__list_issues) in your next response.`,execute:async(e,t)=>{let n=typeof t==`object`&&t&&`toolCallId`in t?t.toolCallId:void 0;return Io(e,{toolCallId:typeof n==`string`?n:void 0})},inputSchema:{additionalProperties:!1,properties:{connection:{description:`Optional: limit search to a specific connection name.`,type:`string`},limit:{description:`Max results to return. Default 10.`,type:`number`},keywords:{description:`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`,type:`string`}},required:[`keywords`],type:`object`},logicalPath:`ash:framework/connection-search`,name:`connection_search`,onCompact({ctx:e}){return e.set(Po,{byConnection:{}}),e.set(No,[]),e.set(Oo,[]),{}},sourceId:`ash:connection-search-tool`,sourceKind:`module`};async function Io(e,t){let n=V(),r=n.get(Mo);if(r===void 0)return[];let i=e.limit??10,a=Lo(e.keywords),o=[],s=[],c=e.connection!==void 0&&e.connection!==``?r.getConnections().filter(t=>t.connectionName===e.connection):r.getConnections(),l={...n.get(Po)?.byConnection},u=[];for(let e of c){let t;try{t=await r.getClient(e.connectionName).getToolMetadata()}catch(t){if(wo(t)){u.push({connectionName:e.connectionName,description:e.description}),s.push({connection:e.connectionName,description:e.description,needsAuthorization:!0});continue}if(To(t)){jo.warn(`connection authorization failed`,{connection:e.connectionName,reason:t.reason,retryable:t.retryable,error:t}),s.push({connection:e.connectionName,description:e.description,error:`Authorization failed for ${e.connectionName}: ${t.message}`});continue}let n=t instanceof Error?t.message:`unknown error`;jo.warn(`failed to load connection tools`,{connection:e.connectionName,error:t instanceof Error?t:Error(n)}),s.push({connection:e.connectionName,description:e.description,error:`Failed to load tools for "${e.connectionName}": ${n}`});continue}l[e.connectionName]=t;for(let n of t){let t=Ro(a,n);t>0&&o.push({item:{connection:e.connectionName,description:n.description,inputSchema:n.inputSchema,qualifiedName:Ao(e.connectionName,n.name),tool:n.name},score:t})}}n.set(Po,{byConnection:l});let d=[];if(u.length>0){for(let e of u)Bo(n,e);d=u.map(e=>e.connectionName).filter(e=>zo(r,e))}if(d.length>0&&t?.toolCallId!==void 0){let r=n.get(Oo);return n.set(Oo,ko(r,[{args:e,connectionNames:d,kind:`connection-discover`,toolCallId:t.toolCallId,toolName:`connection_search`}])),Do}o.sort((e,t)=>t.score-e.score);let f=o.slice(0,i).map(e=>e.item);return f.length>0?[...f,...s]:c.map(e=>s.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}function Lo(e){return e.toLowerCase().split(/[\s_\-./]+/).filter(e=>e.length>1)}function Ro(e,t){let n=Lo(t.name),r=Lo(t.description),i=0;for(let t of e){for(let e of n)(e.includes(t)||t.includes(e))&&(i+=3);for(let e of r)(e.includes(t)||t.includes(e))&&(i+=1)}return i}function zo(e,t){return e===void 0?!1:Eo(e.getConnections().find(e=>e.connectionName===t)?.authorization)}function Bo(e,t){let n=e.get(No)??[];n.some(e=>e.connectionName===t.connectionName)||e.set(No,[...n,t])}const Vo=Fo.name;function Ho(e){return[`## Connections`,``,`You have direct access to the following external services through connected MCP servers.`,`When the user's request relates to any of these services, use them instead of web search or general knowledge.`,``,`Available connections:`,...e.map(e=>`- ${e.connectionName}: ${e.description}`),``,`Use ${Vo} to discover specific tools within a connection. Discovered tools become directly callable by their qualified name (e.g. linear__list_issues) in your next response.`].join(`
|
|
12
12
|
`)}function Uo(e){return[...Wo(e.instructions),...Go(e.workspaceSpec),...e.toolsAvailable?[`Tool execution
|
|
13
|
-
A single tool or subagent call runs as one serial action. If you call multiple independent tools or subagents in one response, Ash treats that batch as parallel work. Only batch work that is independent and does not rely on another call in the same response.`]:[],...Ko(e.connections),...qo(e.skills)]}function Wo(e){if(e===void 0)return[];let t=e.markdown.trim();return t.length===0?[]:[`Instructions (${e.name})\n${t}`]}function Go(e){if(e===void 0)return[];let t=Co(e);return t===void 0?[]:[t]}function Ko(e){return!e||e.length===0?[]:[Ho(e)]}function qo(e){if(!e||e.length===0)return[];let t=xo(e);return t===null?[]:[t]}function Jo(e){let t=e.agent,n=Yo(t);return{id:t.config.name,instructions:Uo({connections:t.connections,instructions:t.instructions,skills:t.skills,toolsAvailable:e.tools.length>0,workspaceSpec:t.workspaceSpec}),compactionModel:t.config.compaction?.model,model:t.config.model,nodeId:e.nodeId,turnMetadata:n,tools:[...e.tools],workspaceSpec:t.workspaceSpec}}function Yo(e){let t={};return Object.keys(e.config.metadata).length>0&&(t.configMetadata={...e.config.metadata}),e.instructions!==void 0&&(t.instructionsName=e.instructions.name),e.skills.length>0&&(t.skillNames=e.skills.map(e=>e.name)),Object.keys(t).length>0?t:void 0}const Xo=new Set([`aud`,`exp`,`iat`,`iss`,`jti`,`nbf`,`sub`]);function Zo(e){let t={};for(let[n,r]of Object.entries(e)){if(typeof r==`string`){t[n]=r;continue}Array.isArray(r)&&r.every(e=>typeof e==`string`)&&(t[n]=Object.freeze([...r]))}return Object.freeze(t)}function Qo(e){let t=Zo(e);return Object.freeze(Object.fromEntries(Object.entries(t).filter(([e])=>!Xo.has(e))))}function $o(e,t){let n=Zo(e);if(t.subjects!==void 0){let n=typeof e.sub==`string`?e.sub:null;if(n===null||!t.subjects.some(e=>ts(e,n)))return!1}return t.claims===void 0?!0:Object.entries(t.claims).every(([e,t])=>{let r=n[e];return r===void 0?!1:typeof r==`string`?t.includes(r):r.some(e=>t.includes(e))})}function es(e){let t=typeof e.payload.iss==`string`?e.payload.iss:void 0,n=typeof e.payload.sub==`string`?e.payload.sub:void 0;if(t===void 0||n===void 0)throw Error(`Expected verified JWT payloads to include string iss and sub claims.`);let r=Zo(e.payload);return{attributes:Qo(e.payload),authenticator:e.authenticator,claims:r,issuer:t,principalId:`${t}:${n}`,principalType:e.principalType,subject:n}}function ts(e,t){if(!e.includes(`*`))return e===t;let n=e.replaceAll(/[.+?^${}()|[\]\\]/g,`\\$&`).replaceAll(`*`,`.*`);return RegExp(`^${n}$`).test(t)}const ns=b.object({issuer:b.string().optional(),jwks_uri:b.string().url()}).passthrough(),rs=new Map,is=new Map;async function as(e){let t;try{t=await os(e.strategy)}catch(e){return{kind:`misconfigured`,message:`Failed to load OIDC discovery metadata. ${e instanceof Error?e.message:`Unknown discovery failure.`}`}}try{let n=await je(e.token,t,{audience:[...e.strategy.audiences],clockTolerance:e.strategy.clockSkewSeconds,issuer:e.strategy.issuer});if(typeof n.payload.sub!=`string`||n.payload.sub.length===0)return{kind:`not-authenticated`};let r=e.strategy.acceptCurrentVercelProject&&cs({issuer:e.strategy.issuer,payload:n.payload}),i=r&&ls({payload:n.payload});return!r&&!$o(n.payload,e.strategy)?{kind:`caller-not-allowed`}:{kind:`authenticated`,principal:es({authenticator:`oidc`,payload:n.payload,principalType:i?`runtime`:`service`})}}catch{return{kind:`not-authenticated`}}}async function os(e){let t=await ss(e.discoveryUrl),n=is.get(t.jwks_uri);if(n!==void 0)return n;let r=ke(new URL(t.jwks_uri));return is.set(t.jwks_uri,r),r}async function ss(e){let t=rs.get(e);if(t!==void 0)return await t;let n=fetch(e,{headers:{accept:`application/json`}}).then(async e=>{if(!e.ok)throw Error(`Discovery route returned HTTP ${e.status}.`);return ns.parse(await e.json())}).catch(t=>{throw rs.delete(e),t});return rs.set(e,n),await n}function cs(e){if(!e.issuer.startsWith(`https://oidc.vercel.com`))return!1;let t=process.env.VERCEL_PROJECT_ID?.trim();return t===void 0||t.length===0?!1:typeof e.payload.project_id==`string`&&e.payload.project_id===t}function ls(e){let t=(process.env.VERCEL_TARGET_ENV?.trim()??process.env.VERCEL_ENV?.trim())?.trim();return t===void 0||t.length===0?!1:typeof e.payload.environment==`string`&&e.payload.environment===t}function us(e){return{attributes:e.attributes,authenticator:e.authenticator,issuer:e.issuer,principalId:e.principalId,principalType:e.principalType,subject:e.subject}}const K=la(`auth.vercel-oidc`);async function ds(e,t){return e===null||e.length===0?{kind:`not-authenticated`}:await as({strategy:{acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e})}function fs(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function ps(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,ms(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function ms(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${hs(t)}"`).join(`, `);return`${e.scheme} ${t}`}function hs(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}function gs(){return()=>void 0}async function _s(e,t={}){if(e===null||e.length===0)return K.debug(`Rejected request without a bearer token.`),{ok:!1};let n=ys(e);if(n===null)return K.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!n.issuer.startsWith(`https://oidc.vercel.com/`))return K.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:n.issuer}),{ok:!1};if(n.audiences.length===0)return K.debug(`Rejected token with no audience claim.`,{issuer:n.issuer}),{ok:!1};let r=await ds(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,issuer:n.issuer,subjects:t.subjects??[]});return r.kind===`authenticated`?(K.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:r.principal.principalType,subject:r.principal.subject}),{ok:!0,sessionAuth:us(r.principal)}):(K.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:r.kind,subjectsConfigured:(t.subjects??[]).length>0,...r.kind===`misconfigured`?{detail:r.message}:{}}),{ok:!1})}function vs(e={}){return async t=>{let n=await _s(fs(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function ys(e){let t;try{t=Ae(e)}catch{return null}return typeof t.iss!=`string`||t.iss.length===0?null:{audiences:typeof t.aud==`string`?[t.aud]:Array.isArray(t.aud)?t.aud.filter(e=>typeof e==`string`):[],issuer:t.iss}}function bs(e){return Number.isFinite(e)&&Number.isInteger(e)&&e>=0}function xs(e){if(e.protocol!==`ash-attachment:`)throw Error(`AttachmentRef URL must use scheme "ash-attachment:". Got: "${e.protocol}".`);let t=e.searchParams.get(`v`);if(t!==`1`)throw Error(`AttachmentRef wire format version must be "1". Got: ${t===null?`missing`:JSON.stringify(t)}.`);let n=e.searchParams.get(`p`);if(n===null||n===``)throw Error(`AttachmentRef URL is missing the required "p" payload query param.`);let r;try{let e=Buffer.from(n,`base64url`).toString(`utf8`);r=JSON.parse(e)}catch(e){throw Error(`AttachmentRef payload is not valid base64url-encoded JSON: ${m(e)}`)}if(typeof r!=`object`||!r||Array.isArray(r))throw Error(`AttachmentRef payload must decode to a JSON object.`);let i=r;if(!(`params`in i))throw Error(`AttachmentRef payload is missing the required "params" field.`);let a=i.params;if(!(`size`in i))return{params:a};let o=i.size;if(typeof o!=`number`||!bs(o))throw Error(`AttachmentRef payload "size" must be a non-negative integer. Got: ${JSON.stringify(o)}.`);return{params:a,size:o}}function Ss(e){return e instanceof URL&&e.protocol===`ash-attachment:`}function Cs(e){return typeof Buffer<`u`&&Buffer.isBuffer(e)||e instanceof Uint8Array||e instanceof ArrayBuffer?e.byteLength:typeof e==`string`?ws(e):Ss(e)?xs(e).size??null:e instanceof URL&&e.protocol===`data:`?ws(e.href):null}function ws(e){if(e.startsWith(`data:`)){let t=e.indexOf(`,`);if(t===-1)return null;let n=e.slice(5,t),r=e.slice(t+1);if(n.endsWith(`;base64`))return Ts(r);try{return Buffer.byteLength(decodeURIComponent(r),`utf8`)}catch{return Buffer.byteLength(r,`utf8`)}}return/^https?:\/\//.test(e)?null:Ts(e)}function Ts(e){let t=e.trimEnd();if(t.length===0)return 0;let n=0;return t.endsWith(`==`)?n=2:t.endsWith(`=`)&&(n=1),Math.max(0,Math.floor(t.length*3/4)-n)}const Es=Object.freeze({allowedMediaTypes:`*`,maxBytes:25*1024*1024});function Ds(e,t=Es){if(e===void 0)return t;let n=e.maxBytes??t.maxBytes,r=e.allowedMediaTypes??t.allowedMediaTypes;if(n<0||!Number.isFinite(n))throw RangeError(`UploadPolicy.maxBytes must be a non-negative finite number. Received: ${String(n)}.`);return{allowedMediaTypes:r,maxBytes:n}}function Os(e,t){if(t.allowedMediaTypes===`*`)return!0;let n=e.toLowerCase();for(let e of t.allowedMediaTypes){let t=e.toLowerCase();if(t===n)return!0;if(t.endsWith(`/*`)){let e=t.slice(0,-1);if(n.startsWith(e))return!0}}return!1}function ks(e,t){if(!Os(e.mediaType,t)){let n={allowedMediaTypes:t.allowedMediaTypes===`*`?[]:[...t.allowedMediaTypes],kind:`disallowed-media-type`,mediaType:e.mediaType};return e.filename===void 0?n:{...n,filename:e.filename}}let n=Cs(e.data);if(n!==null&&n>t.maxBytes){let r={byteLength:n,kind:`too-large`,limit:t.maxBytes,mediaType:e.mediaType};return e.filename===void 0?r:{...r,filename:e.filename}}return null}function As(e,t){if(typeof e==`string`)return[];let n=[];for(let r of e){if(r.type!==`file`)continue;let e=ks(r,t);e!==null&&n.push(e)}return n}function js(e){let t=e.filename??e.mediaType;if(e.kind===`too-large`)return`${t} (${e.byteLength} bytes) exceeds the ${e.limit}-byte upload limit.`;let n=e.allowedMediaTypes.length>0?` Allowed: ${e.allowedMediaTypes.join(`, `)}.`:``;return`${t} has media type "${e.mediaType}" which is not allowed by this route.${n}`}function Ms(e,t){return{method:`POST`,path:e,handler:t}}function Ns(e,t){return{method:`GET`,path:e,handler:t}}function Ps(e){let t=Fs(e);return{__kind:`ash:channel`,routes:e.routes,adapter:t,receive:e.receive}}function Fs(e){let t=e.state!=null,n=e.context!=null,r=e.fetchFile!==void 0,i=t||n,a={},o=!1,s=[`turn.started`,`actions.requested`,`action.result`,`message.completed`,`message.appended`,`input.requested`,`turn.failed`,`turn.completed`,`session.failed`,`session.completed`,`session.waiting`,`connection.authorization_required`,`connection.authorization_pending`,`connection.authorization_completed`],c=e.events;for(let e of s){let t=c?.[e];t&&(o=!0,a[e]=(e,n)=>t(e,n))}return!i&&!o&&!r?{kind:e.kindHint??`http`}:{kind:e.kindHint??`defineChannel`,state:t?{...e.state}:{},fetchFile:e.fetchFile,createAdapterContext(t){let r=t.state;return{...n?e.context(r):{},state:r,ctx:t.ctx,session:{id:``,continuationToken:``,auth:null,initiatorAuth:null,setContinuationToken(e){}}}},deliver(e){return ba(e)},...a}}function Is(e){let t=Ds(e.uploadPolicy);return Ps({routes:[Ms(`/ash/v1/session`,async(n,{send:r})=>{let i=await Ls(e.auth,n);if(i instanceof Response)return i;let a=i,o;try{o=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof o!=`object`||!o)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let s=Rs(o);if(s instanceof Response)return s;let c=Hs(s,t);if(c!==null)return c;let l=`ash:${crypto.randomUUID()}`,u=await r(s.message,{auth:a,continuationToken:l});return Response.json({continuationToken:u.continuationToken,ok:!0,sessionId:u.id},{headers:{"cache-control":`no-store`,[y]:u.id},status:202})}),Ms(`/ash/v1/session/:sessionId`,async(n,{send:r,getSession:i,params:a})=>{let o=await Ls(e.auth,n);if(o instanceof Response)return o;let s=o,c=a.sessionId;if(!c)return Response.json({error:`Missing session id.`,ok:!1},{status:400});try{i(c)}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}let l;try{l=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof l!=`object`||!l)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let u=zs(l);if(u instanceof Response)return u;let d=Hs(u,t);if(d!==null)return d;let f=await r({inputResponses:u.inputResponses,message:u.message},{auth:s,continuationToken:u.continuationToken});return Response.json({ok:!0,sessionId:f.id},{headers:{"cache-control":`no-store`,[y]:f.id},status:200})}),Ns(`/ash/v1/session/:sessionId/stream`,async(t,{getSession:n,params:r})=>{let i=await Ls(e.auth,t);if(i instanceof Response)return i;let a=r.sessionId;if(!a)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let o=Ws(t);if(o instanceof Response)return o;try{let e=Gs(await n(a).getEventStream({startIndex:o}));return new Response(e,{headers:{"cache-control":`no-store`,"content-type":ie,[y]:a,[re]:te,[ae]:`14`}})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}})]})}async function Ls(e,t){let n=await e(t);return n===null?ps({challenges:[{scheme:`Bearer`}]}):n??null}function Rs(e){let t=Bs(e.message);return t instanceof Response?t:t===void 0?Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400}):{message:t}}function zs(e){let t=typeof e.continuationToken==`string`&&e.continuationToken.length>0?e.continuationToken:void 0;if(t===void 0)return Response.json({error:`Missing or empty 'continuationToken' field.`,ok:!1},{status:400});let n=Bs(e.message);if(n instanceof Response)return n;let r=Us(e.inputResponses);return r instanceof Response?r:n===void 0&&r===void 0?Response.json({error:`Expected a non-empty 'message', a non-empty 'inputResponses' array, or both.`,ok:!1},{status:400}):{message:n,continuationToken:t,inputResponses:r}}function Bs(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=Vs(n);if(e instanceof Response)return e;t.push(e)}return t}function Vs(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function Hs(e,t){if(!e.message)return null;let n=As(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:js(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function Us(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(ne);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function Ws(e){let t=new URL(e.url).searchParams.get(`startIndex`);if(t===null)return;let n=Number.parseInt(t,10);return!Number.isSafeInteger(n)||n<0?Response.json({error:`Expected startIndex to be a non-negative integer.`,ok:!1},{status:400}):n}function Gs(e){let t=new TextEncoder;return e.pipeThrough(new TransformStream({transform(e,n){n.enqueue(t.encode(`${JSON.stringify(e)}\n`))}}))}function Ks(){return new Response(`<!doctype html>
|
|
13
|
+
A single tool or subagent call runs as one serial action. If you call multiple independent tools or subagents in one response, Ash treats that batch as parallel work. Only batch work that is independent and does not rely on another call in the same response.`]:[],...Ko(e.connections),...qo(e.skills)]}function Wo(e){if(e===void 0)return[];let t=e.markdown.trim();return t.length===0?[]:[`Instructions (${e.name})\n${t}`]}function Go(e){if(e===void 0)return[];let t=Co(e);return t===void 0?[]:[t]}function Ko(e){return!e||e.length===0?[]:[Ho(e)]}function qo(e){if(!e||e.length===0)return[];let t=xo(e);return t===null?[]:[t]}function Jo(e){let t=e.agent,n=Yo(t);return{id:t.config.name,instructions:Uo({connections:t.connections,instructions:t.instructions,skills:t.skills,toolsAvailable:e.tools.length>0,workspaceSpec:t.workspaceSpec}),compactionModel:t.config.compaction?.model,model:t.config.model,nodeId:e.nodeId,turnMetadata:n,tools:[...e.tools],workspaceSpec:t.workspaceSpec}}function Yo(e){let t={};return Object.keys(e.config.metadata).length>0&&(t.configMetadata={...e.config.metadata}),e.instructions!==void 0&&(t.instructionsName=e.instructions.name),e.skills.length>0&&(t.skillNames=e.skills.map(e=>e.name)),Object.keys(t).length>0?t:void 0}const Xo=new Set([`aud`,`exp`,`iat`,`iss`,`jti`,`nbf`,`sub`]);function Zo(e){let t={};for(let[n,r]of Object.entries(e)){if(typeof r==`string`){t[n]=r;continue}Array.isArray(r)&&r.every(e=>typeof e==`string`)&&(t[n]=Object.freeze([...r]))}return Object.freeze(t)}function Qo(e){let t=Zo(e);return Object.freeze(Object.fromEntries(Object.entries(t).filter(([e])=>!Xo.has(e))))}function $o(e,t){let n=Zo(e);if(t.subjects!==void 0){let n=typeof e.sub==`string`?e.sub:null;if(n===null||!t.subjects.some(e=>ts(e,n)))return!1}return t.claims===void 0?!0:Object.entries(t.claims).every(([e,t])=>{let r=n[e];return r===void 0?!1:typeof r==`string`?t.includes(r):r.some(e=>t.includes(e))})}function es(e){let t=typeof e.payload.iss==`string`?e.payload.iss:void 0,n=typeof e.payload.sub==`string`?e.payload.sub:void 0;if(t===void 0||n===void 0)throw Error(`Expected verified JWT payloads to include string iss and sub claims.`);let r=Zo(e.payload);return{attributes:Qo(e.payload),authenticator:e.authenticator,claims:r,issuer:t,principalId:`${t}:${n}`,principalType:e.principalType,subject:n}}function ts(e,t){if(!e.includes(`*`))return e===t;let n=e.replaceAll(/[.+?^${}()|[\]\\]/g,`\\$&`).replaceAll(`*`,`.*`);return RegExp(`^${n}$`).test(t)}const ns=b.object({issuer:b.string().optional(),jwks_uri:b.string().url()}).passthrough(),rs=new Map,is=new Map;async function as(e){let t;try{t=await os(e.strategy)}catch(e){return{kind:`misconfigured`,message:`Failed to load OIDC discovery metadata. ${e instanceof Error?e.message:`Unknown discovery failure.`}`}}try{let n=await je(e.token,t,{audience:[...e.strategy.audiences],clockTolerance:e.strategy.clockSkewSeconds,issuer:e.strategy.issuer});if(typeof n.payload.sub!=`string`||n.payload.sub.length===0)return{kind:`not-authenticated`};let r=e.strategy.acceptCurrentVercelProject&&cs({issuer:e.strategy.issuer,payload:n.payload}),i=r&&ls({payload:n.payload});return!r&&!$o(n.payload,e.strategy)?{kind:`caller-not-allowed`}:{kind:`authenticated`,principal:es({authenticator:`oidc`,payload:n.payload,principalType:i?`runtime`:`service`})}}catch{return{kind:`not-authenticated`}}}async function os(e){let t=await ss(e.discoveryUrl),n=is.get(t.jwks_uri);if(n!==void 0)return n;let r=ke(new URL(t.jwks_uri));return is.set(t.jwks_uri,r),r}async function ss(e){let t=rs.get(e);if(t!==void 0)return await t;let n=fetch(e,{headers:{accept:`application/json`}}).then(async e=>{if(!e.ok)throw Error(`Discovery route returned HTTP ${e.status}.`);return ns.parse(await e.json())}).catch(t=>{throw rs.delete(e),t});return rs.set(e,n),await n}function cs(e){if(!e.issuer.startsWith(`https://oidc.vercel.com`))return!1;let t=process.env.VERCEL_PROJECT_ID?.trim();return t===void 0||t.length===0?!1:typeof e.payload.project_id==`string`&&e.payload.project_id===t}function ls(e){let t=(process.env.VERCEL_TARGET_ENV?.trim()??process.env.VERCEL_ENV?.trim())?.trim();return t===void 0||t.length===0?!1:typeof e.payload.environment==`string`&&e.payload.environment===t}function us(e){return{attributes:e.attributes,authenticator:e.authenticator,issuer:e.issuer,principalId:e.principalId,principalType:e.principalType,subject:e.subject}}const K=la(`auth.vercel-oidc`);async function ds(e,t){return e===null||e.length===0?{kind:`not-authenticated`}:await as({strategy:{acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e})}function fs(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function ps(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,ms(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function ms(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${hs(t)}"`).join(`, `);return`${e.scheme} ${t}`}function hs(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}function gs(){return()=>void 0}async function _s(e,t={}){if(e===null||e.length===0)return K.debug(`Rejected request without a bearer token.`),{ok:!1};let n=ys(e);if(n===null)return K.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!n.issuer.startsWith(`https://oidc.vercel.com/`))return K.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:n.issuer}),{ok:!1};if(n.audiences.length===0)return K.debug(`Rejected token with no audience claim.`,{issuer:n.issuer}),{ok:!1};let r=await ds(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,issuer:n.issuer,subjects:t.subjects??[]});return r.kind===`authenticated`?(K.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:r.principal.principalType,subject:r.principal.subject}),{ok:!0,sessionAuth:us(r.principal)}):(K.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:r.kind,subjectsConfigured:(t.subjects??[]).length>0,...r.kind===`misconfigured`?{detail:r.message}:{}}),{ok:!1})}function vs(e={}){return async t=>{let n=await _s(fs(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function ys(e){let t;try{t=Ae(e)}catch{return null}return typeof t.iss!=`string`||t.iss.length===0?null:{audiences:typeof t.aud==`string`?[t.aud]:Array.isArray(t.aud)?t.aud.filter(e=>typeof e==`string`):[],issuer:t.iss}}function bs(e){return Number.isFinite(e)&&Number.isInteger(e)&&e>=0}function xs(e){if(e.protocol!==`ash-attachment:`)throw Error(`AttachmentRef URL must use scheme "ash-attachment:". Got: "${e.protocol}".`);let t=e.searchParams.get(`v`);if(t!==`1`)throw Error(`AttachmentRef wire format version must be "1". Got: ${t===null?`missing`:JSON.stringify(t)}.`);let n=e.searchParams.get(`p`);if(n===null||n===``)throw Error(`AttachmentRef URL is missing the required "p" payload query param.`);let r;try{let e=Buffer.from(n,`base64url`).toString(`utf8`);r=JSON.parse(e)}catch(e){throw Error(`AttachmentRef payload is not valid base64url-encoded JSON: ${m(e)}`)}if(typeof r!=`object`||!r||Array.isArray(r))throw Error(`AttachmentRef payload must decode to a JSON object.`);let i=r;if(!(`params`in i))throw Error(`AttachmentRef payload is missing the required "params" field.`);let a=i.params;if(!(`size`in i))return{params:a};let o=i.size;if(typeof o!=`number`||!bs(o))throw Error(`AttachmentRef payload "size" must be a non-negative integer. Got: ${JSON.stringify(o)}.`);return{params:a,size:o}}function Ss(e){return e instanceof URL&&e.protocol===`ash-attachment:`}function Cs(e){return typeof Buffer<`u`&&Buffer.isBuffer(e)||e instanceof Uint8Array||e instanceof ArrayBuffer?e.byteLength:typeof e==`string`?ws(e):Ss(e)?xs(e).size??null:e instanceof URL&&e.protocol===`data:`?ws(e.href):null}function ws(e){if(e.startsWith(`data:`)){let t=e.indexOf(`,`);if(t===-1)return null;let n=e.slice(5,t),r=e.slice(t+1);if(n.endsWith(`;base64`))return Ts(r);try{return Buffer.byteLength(decodeURIComponent(r),`utf8`)}catch{return Buffer.byteLength(r,`utf8`)}}return/^https?:\/\//.test(e)?null:Ts(e)}function Ts(e){let t=e.trimEnd();if(t.length===0)return 0;let n=0;return t.endsWith(`==`)?n=2:t.endsWith(`=`)&&(n=1),Math.max(0,Math.floor(t.length*3/4)-n)}const Es=Object.freeze({allowedMediaTypes:`*`,maxBytes:25*1024*1024});function Ds(e,t=Es){if(e===`disabled`)return`disabled`;if(e===void 0)return t;let n=e.maxBytes??t.maxBytes,r=e.allowedMediaTypes??t.allowedMediaTypes;if(n<0||!Number.isFinite(n))throw RangeError(`UploadPolicy.maxBytes must be a non-negative finite number. Received: ${String(n)}.`);return{allowedMediaTypes:r,maxBytes:n}}function Os(e,t){if(t===`disabled`)return!1;if(t.allowedMediaTypes===`*`)return!0;let n=e.toLowerCase();for(let e of t.allowedMediaTypes){let t=e.toLowerCase();if(t===n)return!0;if(t.endsWith(`/*`)){let e=t.slice(0,-1);if(n.startsWith(e))return!0}}return!1}function ks(e,t){if(t===`disabled`||!Os(e.mediaType,t)){let n={allowedMediaTypes:t===`disabled`||t.allowedMediaTypes===`*`?[]:[...t.allowedMediaTypes],kind:`disallowed-media-type`,mediaType:e.mediaType};return e.filename===void 0?n:{...n,filename:e.filename}}let n=Cs(e.data);if(n!==null&&n>t.maxBytes){let r={byteLength:n,kind:`too-large`,limit:t.maxBytes,mediaType:e.mediaType};return e.filename===void 0?r:{...r,filename:e.filename}}return null}function As(e,t){if(typeof e==`string`)return[];let n=[];for(let r of e){if(r.type!==`file`)continue;let e=ks(r,t);e!==null&&n.push(e)}return n}function js(e){let t=e.filename??e.mediaType;if(e.kind===`too-large`)return`${t} (${e.byteLength} bytes) exceeds the ${e.limit}-byte upload limit.`;let n=e.allowedMediaTypes.length>0?` Allowed: ${e.allowedMediaTypes.join(`, `)}.`:``;return`${t} has media type "${e.mediaType}" which is not allowed by this route.${n}`}function Ms(e,t){return{method:`POST`,path:e,handler:t}}function Ns(e,t){return{method:`GET`,path:e,handler:t}}function Ps(e){let t=Fs(e);return{__kind:`ash:channel`,routes:e.routes,adapter:t,receive:e.receive}}function Fs(e){let t=e.state!=null,n=e.context!=null,r=e.fetchFile!==void 0,i=t||n,a={},o=!1,s=[`turn.started`,`actions.requested`,`action.result`,`message.completed`,`message.appended`,`input.requested`,`turn.failed`,`turn.completed`,`session.failed`,`session.completed`,`session.waiting`,`connection.authorization_required`,`connection.authorization_pending`,`connection.authorization_completed`],c=e.events;for(let e of s){let t=c?.[e];t&&(o=!0,a[e]=(e,n)=>t(e,n))}return!i&&!o&&!r?{kind:e.kindHint??`http`}:{kind:e.kindHint??`defineChannel`,state:t?{...e.state}:{},fetchFile:e.fetchFile,createAdapterContext(t){let r=t.state;return{...n?e.context(r):{},state:r,ctx:t.ctx,session:{id:``,continuationToken:``,auth:null,initiatorAuth:null,setContinuationToken(e){}}}},deliver(e){return ba(e)},...a}}function Is(e){let t=Ds(e.uploadPolicy);return Ps({routes:[Ms(`/ash/v1/session`,async(n,{send:r})=>{let i=await Ls(e.auth,n);if(i instanceof Response)return i;let a=i,o;try{o=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof o!=`object`||!o)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let s=Rs(o);if(s instanceof Response)return s;let c=Hs(s,t);if(c!==null)return c;let l=`ash:${crypto.randomUUID()}`,u=await r(s.message,{auth:a,continuationToken:l});return Response.json({continuationToken:u.continuationToken,ok:!0,sessionId:u.id},{headers:{"cache-control":`no-store`,[y]:u.id},status:202})}),Ms(`/ash/v1/session/:sessionId`,async(n,{send:r,getSession:i,params:a})=>{let o=await Ls(e.auth,n);if(o instanceof Response)return o;let s=o,c=a.sessionId;if(!c)return Response.json({error:`Missing session id.`,ok:!1},{status:400});try{i(c)}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}let l;try{l=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof l!=`object`||!l)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let u=zs(l);if(u instanceof Response)return u;let d=Hs(u,t);if(d!==null)return d;let f=await r({inputResponses:u.inputResponses,message:u.message},{auth:s,continuationToken:u.continuationToken});return Response.json({ok:!0,sessionId:f.id},{headers:{"cache-control":`no-store`,[y]:f.id},status:200})}),Ns(`/ash/v1/session/:sessionId/stream`,async(t,{getSession:n,params:r})=>{let i=await Ls(e.auth,t);if(i instanceof Response)return i;let a=r.sessionId;if(!a)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let o=Ws(t);if(o instanceof Response)return o;try{let e=Gs(await n(a).getEventStream({startIndex:o}));return new Response(e,{headers:{"cache-control":`no-store`,"content-type":ie,[y]:a,[re]:te,[ae]:`14`}})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}})]})}async function Ls(e,t){let n=await e(t);return n===null?ps({challenges:[{scheme:`Bearer`}]}):n??null}function Rs(e){let t=Bs(e.message);return t instanceof Response?t:t===void 0?Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400}):{message:t}}function zs(e){let t=typeof e.continuationToken==`string`&&e.continuationToken.length>0?e.continuationToken:void 0;if(t===void 0)return Response.json({error:`Missing or empty 'continuationToken' field.`,ok:!1},{status:400});let n=Bs(e.message);if(n instanceof Response)return n;let r=Us(e.inputResponses);return r instanceof Response?r:n===void 0&&r===void 0?Response.json({error:`Expected a non-empty 'message', a non-empty 'inputResponses' array, or both.`,ok:!1},{status:400}):{message:n,continuationToken:t,inputResponses:r}}function Bs(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=Vs(n);if(e instanceof Response)return e;t.push(e)}return t}function Vs(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function Hs(e,t){if(!e.message)return null;let n=As(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:js(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function Us(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(ne);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function Ws(e){let t=new URL(e.url).searchParams.get(`startIndex`);if(t===null)return;let n=Number.parseInt(t,10);return!Number.isSafeInteger(n)||n<0?Response.json({error:`Expected startIndex to be a non-negative integer.`,ok:!1},{status:400}):n}function Gs(e){let t=new TextEncoder;return e.pipeThrough(new TransformStream({transform(e,n){n.enqueue(t.encode(`${JSON.stringify(e)}\n`))}}))}function Ks(){return new Response(`<!doctype html>
|
|
14
14
|
<html lang="en">
|
|
15
15
|
<head>
|
|
16
16
|
<meta charset="utf-8" />
|
|
@@ -83,6 +83,6 @@ A single tool or subagent call runs as one serial action. If you call multiple i
|
|
|
83
83
|
|
|
84
84
|
`).trim(),t}const al={"&":`&`,">":`>`,"<":`<`," ":` `,""":`"`,"'":`'`,"'":`'`,"/":`/`},ol=new RegExp(Object.keys(al).join(`|`),`gi`);function sl(e){return e.replace(ol,e=>al[e.toLowerCase()]??e)}const cl=5*1024*1024;async function ll(e){let{url:t,format:n=`markdown`,timeout:r}=e;if(!t.startsWith(`http://`)&&!t.startsWith(`https://`))throw Error(`URL must start with http:// or https://`);let i=Math.min(r===void 0?3e4:r*1e3,12e4),a=AbortSignal.timeout(i),o=ul(n),s=await fetch(t,{headers:o,signal:a}),c=s.status===403&&s.headers.get(`cf-mitigated`)===`challenge`?await fetch(t,{headers:{...o,"User-Agent":g},signal:a}):s;if(!c.ok)throw Error(`Request failed with status code: ${c.status}`);let l=c.headers.get(`content-length`);if(l!==null&&parseInt(l,10)>cl)throw Error(`Response too large (exceeds 5 MB limit).`);let u=await c.arrayBuffer();if(u.byteLength>cl)throw Error(`Response too large (exceeds 5 MB limit).`);let d=c.headers.get(`content-type`)??``,f=d.includes(`text/html`),p=new TextDecoder().decode(u),m;m=n===`markdown`&&f?rl(p):n===`text`&&f?il(p):p;let{output:h,truncated:_}=cc(m);return{content:h,contentType:d,truncated:_,url:t}}function ul(e){let t;return t=e===`markdown`?`text/markdown;q=1.0, text/x-markdown;q=0.9, text/plain;q=0.8, text/html;q=0.7, */*;q=0.1`:e===`text`?`text/plain;q=1.0, text/markdown;q=0.9, text/html;q=0.8, */*;q=0.1`:`text/html;q=1.0, application/xhtml+xml;q=0.9, text/plain;q=0.8, text/markdown;q=0.7, */*;q=0.1`,{Accept:t,"Accept-Language":`en-US,en;q=0.9`,"User-Agent":`Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36`}}async function dl(e){return ll(e)}const fl={description:[`Fetch a webpage and return its content in the requested format. Use this to retrieve and analyze content from URLs.`,``,`Usage notes:`,`- The URL must be a fully-formed valid URL starting with http:// or https://`,`- HTML responses are automatically converted to markdown or plain text based on the requested format`,`- Format options: "markdown" (default), "text", or "html"`,`- Default timeout is 30 seconds (max 120 seconds)`,`- Maximum response size is 5 MB; content is further capped at the shared tool-output budget (50 KB / 2000 lines)`,`- This tool is read-only and does not modify any files`].join(`
|
|
85
85
|
`),execute:dl,inputSchema:{additionalProperties:!1,properties:{format:{description:`The format to return the content in (text, markdown, or html). HTML responses are automatically converted to the requested format. Defaults to "markdown".`,enum:[`markdown`,`text`,`html`],type:`string`},timeout:{description:`Optional timeout in seconds. Defaults to 30, max 120.`,type:`number`},url:{description:`The fully-formed URL to fetch content from. Must start with http:// or https://.`,type:`string`}},required:[`url`],type:`object`},logicalPath:`ash:framework/web-fetch`,name:`web_fetch`,sourceId:`ash:web-fetch-tool`,sourceKind:`module`},pl={description:`Search the web for real-time information. Use this to find up-to-date information about current events, recent developments, or topics that may have changed since the knowledge cutoff.`,inputSchema:null,logicalPath:`ash:framework/web-search`,name:`web_search`,sourceId:`ash:web-search-tool`,sourceKind:`module`};async function ml(e){let{filePath:t,content:n}=e;sc(t);let r=await q(),i=V(),a=J(t),o=vc(a),s=await r.readTextFile(t);if(s===null)return await r.writeTextFile(t,n),bc(i,o,yc({content:n,filePath:a})),{existed:!1,path:a};let c=i.ensure(_c,()=>({byTarget:{}})).byTarget[o];if(c===void 0)throw Error(`You must read file ${t} before overwriting it. Use the read_file tool first.`);let l=yc({content:s,filePath:a});if(l.contentHash!==c.contentHash||l.byteLength!==c.byteLength)throw Error(`File ${t} has been modified since it was last read. Please read the file again before modifying it.`);return await r.writeTextFile(t,n),bc(i,o,yc({content:n,filePath:a})),{existed:!0,path:a}}const hl={additionalProperties:!1,properties:{content:{description:`Complete replacement file contents.`,type:`string`},filePath:{description:`The absolute path to the file to write (must be absolute, not relative).`,type:`string`}},required:[`filePath`,`content`],type:`object`};async function gl(e){return ml(e)}const _l=[oc,gc,Mc,Bc,Wc,{description:[`Writes a file to the local filesystem.`,``,`Usage:`,`- This tool will overwrite the existing file if there is one at the provided path.`,`- If this is an existing file, you MUST use the read_file tool first to read the file's contents. This tool will fail if you did not read the file first.`,`- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.`,`- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.`,`- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.`].join(`
|
|
86
|
-
`),execute:gl,inputSchema:hl,logicalPath:`ash:framework/write-file`,name:`write_file`,sourceId:`ash:write-file-tool`,sourceKind:`module`},nl,fl,pl,Zc,Fo],vl=new Map([[Fo,e=>e.hasConnections]]);function yl(e){return _l.filter(t=>{let n=vl.get(t);return n===void 0||n(e)})}function bl(){return new Set(_l.map(e=>e.name))}function xl(e){let t=[],n=[],r=new Map,i=[];for(let a of e){let e=a.lifecycle.session;e!==void 0&&t.push({slug:a.slug,handler:e});let o=a.lifecycle.turn;o!==void 0&&n.push({slug:a.slug,handler:o});for(let[e,t]of Object.entries(a.events)){let n={slug:a.slug,handler:t,eventType:e};if(e===`*`)i.push(n);else{let t=r.get(e)??[];t.push(n),r.set(e,t)}}}return{session:t,turn:n,streamEventsByType:r,streamEventsWildcard:i}}var X=class extends Error{logicalPath;sourceId;constructor(e,t={}){super(e),this.name=`ResolveAgentError`,t.logicalPath!==void 0&&(this.logicalPath=t.logicalPath),t.sourceId!==void 0&&(this.sourceId=t.sourceId)}};function Sl(e){return{exportName:e.exportName,logicalPath:e.logicalPath,sourceId:e.sourceId,sourceKind:`module`}}async function Z(e){let t=e.nodeId??`__root__`,r=e.moduleMap.nodes[t]?.modules[e.definition.sourceId];if(r===void 0)throw new X(`Missing compiled module namespace for ${e.kindLabel} source "${e.definition.sourceId}" in node "${t}".`,{logicalPath:e.definition.logicalPath,sourceId:e.definition.sourceId});return await o(i(n(r,`Missing compiled module namespace for ${e.kindLabel} source "${e.definition.sourceId}" in node "${t}".`),{exportName:e.definition.exportName,logicalPath:e.definition.logicalPath}))}async function Cl(e,t,n){try{let r=ri(await Z({definition:e,kindLabel:`channel`,moduleMap:t,nodeId:n}),`Expected the channel export "${e.exportName??`default`}" from "${e.logicalPath}" to match the public Ash shape.`),i=Sl({exportName:e.exportName,logicalPath:e.logicalPath,sourceId:e.sourceId}),a=r.routes.find(t=>t.method.toUpperCase()===e.method.toUpperCase()&&t.path===e.urlPath),o=r.adapter;return o&&o.kind!==`http`&&(o.kind=`channel:${e.name}`),{name:e.name,method:e.method,urlPath:e.urlPath,fetch:async(e,t)=>a?a.handler(e,t):Response.json({error:`No matching route handler.`,ok:!1},{status:404}),handler:a?.handler,receive:r.receive,adapter:o,...i}}catch(t){throw t instanceof X?t:new X(`Failed to attach the channel definition from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}async function wl(e,t,r){try{let i=n(await Z({definition:e,kindLabel:`connection`,moduleMap:t,nodeId:r}),`Expected the connection export "${e.exportName??`default`}" from "${e.logicalPath}" to return an object.`),a=i.auth!==void 0,o=i.headers!==void 0,s={connectionName:e.connectionName,description:e.description,exportName:e.exportName,logicalPath:e.logicalPath,sourceId:e.sourceId,sourceKind:`module`,url:e.url};if(a)try{s.authorization=li(i.auth,`Connection "${e.connectionName}" at "${e.logicalPath}":`)}catch(t){throw new X(m(t),{logicalPath:e.logicalPath,sourceId:e.sourceId})}return o&&(s.headers=i.headers),i.tools!==void 0&&(s.tools=i.tools),typeof i.approval==`function`&&(s.approval=i.approval),s}catch(t){throw t instanceof X?t:new X(`Failed to resolve connection "${e.connectionName}" from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}async function Tl(e,t,r){try{let i=n(await Z({definition:e,kindLabel:`hook`,moduleMap:t,nodeId:r}),Q(e,`to return an object`)),a={},o={},s=i.lifecycle;if(s!==void 0){let t=n(s,Q(e,"to expose `lifecycle` as an object"));for(let n of[`session`,`turn`]){let r=t[n];r!==void 0&&(a[n]=l(r,Q(e,`to provide a function for "lifecycle.${n}"`)))}}let c=i.events;if(c!==void 0){let t=n(c,Q(e,"to expose `events` as an object"));for(let[n,r]of Object.entries(t))r!==void 0&&(o[n]=l(r,Q(e,`to provide a function for "events.${n}"`)))}return{events:o,exportName:e.exportName,lifecycle:a,logicalPath:e.logicalPath,slug:e.slug,sourceId:e.sourceId,sourceKind:`module`}}catch(t){throw t instanceof X?t:new X(`Failed to attach hook handlers from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function Q(e,t){return`Expected the hook export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}var El=class e extends Error{backendName;templateKey;constructor(e){super(`Sandbox template "${e.templateKey}" is not provisioned for backend "${e.backendName}". Run \`ash build\` or invoke \`prewarmAppSandboxes()\` before serving traffic.`),this.name=`SandboxTemplateNotProvisionedError`,this.backendName=e.backendName,this.templateKey=e.templateKey}static is(t){return t instanceof e}};async function Dl(e){let t=[];for await(let n of e)t.push(n);return Buffer.concat(t)}function Ol(e){return new ReadableStream({start(t){t.enqueue(e),t.close()}})}function $(e){return{id:e.id,async readFile(t){return await e.readFile(e.resolvePath(t))},async readBinaryFile(t){let n=await e.readFile(e.resolvePath(t));return n===null?null:await Dl(n)},async readTextFile(t,n){kl(n);let r=await e.readFile(e.resolvePath(t));return r===null?null:jl(Ml(await Dl(r),n?.encoding??`utf-8`),n)},resolvePath(t){return e.resolvePath(t)},async runCommand(t,n){return await e.runCommand(t,n)},async writeFile(t,n){await e.writeFile(e.resolvePath(t),n)},async writeBinaryFile(t,n){await e.writeFile(e.resolvePath(t),Ol(n))},async writeTextFile(t,n,r){let i=Nl(n,r?.encoding??`utf-8`);await e.writeFile(e.resolvePath(t),Ol(i))}}}function kl(e){if(e===void 0)return;let{startLine:t,endLine:n}=e;if(t!==void 0&&(!Number.isInteger(t)||t<1))throw Error(`startLine must be a positive integer (1-based).`);if(n!==void 0&&(!Number.isInteger(n)||n<1))throw Error(`endLine must be a positive integer (1-based).`);if(t!==void 0&&n!==void 0&&t>n)throw Error(`startLine must not be greater than endLine.`)}function Al(e){let t=[],n=0;for(let r=0;r<e.length;r++)e[r]===`\r`?r+1<e.length&&e[r+1]===`
|
|
86
|
+
`),execute:gl,inputSchema:hl,logicalPath:`ash:framework/write-file`,name:`write_file`,sourceId:`ash:write-file-tool`,sourceKind:`module`},nl,fl,pl,Zc,Fo],vl=new Map([[Fo,e=>e.hasConnections]]);function yl(e){return _l.filter(t=>{let n=vl.get(t);return n===void 0||n(e)})}function bl(){return new Set(_l.map(e=>e.name))}function xl(e){let t=[],n=[],r=new Map,i=[];for(let a of e){let e=a.lifecycle.session;e!==void 0&&t.push({slug:a.slug,handler:e});let o=a.lifecycle.turn;o!==void 0&&n.push({slug:a.slug,handler:o});for(let[e,t]of Object.entries(a.events)){let n={slug:a.slug,handler:t,eventType:e};if(e===`*`)i.push(n);else{let t=r.get(e)??[];t.push(n),r.set(e,t)}}}return{session:t,turn:n,streamEventsByType:r,streamEventsWildcard:i}}var X=class extends Error{logicalPath;sourceId;constructor(e,t={}){super(e),this.name=`ResolveAgentError`,t.logicalPath!==void 0&&(this.logicalPath=t.logicalPath),t.sourceId!==void 0&&(this.sourceId=t.sourceId)}};function Sl(e){return{exportName:e.exportName,logicalPath:e.logicalPath,sourceId:e.sourceId,sourceKind:`module`}}async function Z(e){let t=e.nodeId??`__root__`,r=e.moduleMap.nodes[t]?.modules[e.definition.sourceId];if(r===void 0)throw new X(`Missing compiled module namespace for ${e.kindLabel} source "${e.definition.sourceId}" in node "${t}".`,{logicalPath:e.definition.logicalPath,sourceId:e.definition.sourceId});return await o(i(n(r,`Missing compiled module namespace for ${e.kindLabel} source "${e.definition.sourceId}" in node "${t}".`),{exportName:e.definition.exportName,logicalPath:e.definition.logicalPath}))}async function Cl(e,t,n){try{let r=ri(await Z({definition:e,kindLabel:`channel`,moduleMap:t,nodeId:n}),`Expected the channel export "${e.exportName??`default`}" from "${e.logicalPath}" to match the public Ash shape.`),i=Sl({exportName:e.exportName,logicalPath:e.logicalPath,sourceId:e.sourceId}),a=r.routes.find(t=>t.method.toUpperCase()===e.method.toUpperCase()&&t.path===e.urlPath),o=r.adapter;return o&&o.kind!==`http`&&(o.kind=`channel:${e.name}`),{name:e.name,method:e.method,urlPath:e.urlPath,fetch:async(e,t)=>a?a.handler(e,t):Response.json({error:`No matching route handler.`,ok:!1},{status:404}),handler:a?.handler,receive:r.receive,definition:r,adapter:o,...i}}catch(t){throw t instanceof X?t:new X(`Failed to attach the channel definition from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}async function wl(e,t,r){try{let i=n(await Z({definition:e,kindLabel:`connection`,moduleMap:t,nodeId:r}),`Expected the connection export "${e.exportName??`default`}" from "${e.logicalPath}" to return an object.`),a=i.auth!==void 0,o=i.headers!==void 0,s={connectionName:e.connectionName,description:e.description,exportName:e.exportName,logicalPath:e.logicalPath,sourceId:e.sourceId,sourceKind:`module`,url:e.url};if(a)try{s.authorization=li(i.auth,`Connection "${e.connectionName}" at "${e.logicalPath}":`)}catch(t){throw new X(m(t),{logicalPath:e.logicalPath,sourceId:e.sourceId})}return o&&(s.headers=i.headers),i.tools!==void 0&&(s.tools=i.tools),typeof i.approval==`function`&&(s.approval=i.approval),s}catch(t){throw t instanceof X?t:new X(`Failed to resolve connection "${e.connectionName}" from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}async function Tl(e,t,r){try{let i=n(await Z({definition:e,kindLabel:`hook`,moduleMap:t,nodeId:r}),Q(e,`to return an object`)),a={},o={},s=i.lifecycle;if(s!==void 0){let t=n(s,Q(e,"to expose `lifecycle` as an object"));for(let n of[`session`,`turn`]){let r=t[n];r!==void 0&&(a[n]=l(r,Q(e,`to provide a function for "lifecycle.${n}"`)))}}let c=i.events;if(c!==void 0){let t=n(c,Q(e,"to expose `events` as an object"));for(let[n,r]of Object.entries(t))r!==void 0&&(o[n]=l(r,Q(e,`to provide a function for "events.${n}"`)))}return{events:o,exportName:e.exportName,lifecycle:a,logicalPath:e.logicalPath,slug:e.slug,sourceId:e.sourceId,sourceKind:`module`}}catch(t){throw t instanceof X?t:new X(`Failed to attach hook handlers from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function Q(e,t){return`Expected the hook export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}var El=class e extends Error{backendName;templateKey;constructor(e){super(`Sandbox template "${e.templateKey}" is not provisioned for backend "${e.backendName}". Run \`ash build\` or invoke \`prewarmAppSandboxes()\` before serving traffic.`),this.name=`SandboxTemplateNotProvisionedError`,this.backendName=e.backendName,this.templateKey=e.templateKey}static is(t){return t instanceof e}};async function Dl(e){let t=[];for await(let n of e)t.push(n);return Buffer.concat(t)}function Ol(e){return new ReadableStream({start(t){t.enqueue(e),t.close()}})}function $(e){return{id:e.id,async readFile(t){return await e.readFile(e.resolvePath(t))},async readBinaryFile(t){let n=await e.readFile(e.resolvePath(t));return n===null?null:await Dl(n)},async readTextFile(t,n){kl(n);let r=await e.readFile(e.resolvePath(t));return r===null?null:jl(Ml(await Dl(r),n?.encoding??`utf-8`),n)},resolvePath(t){return e.resolvePath(t)},async runCommand(t,n){return await e.runCommand(t,n)},async writeFile(t,n){await e.writeFile(e.resolvePath(t),n)},async writeBinaryFile(t,n){await e.writeFile(e.resolvePath(t),Ol(n))},async writeTextFile(t,n,r){let i=Nl(n,r?.encoding??`utf-8`);await e.writeFile(e.resolvePath(t),Ol(i))}}}function kl(e){if(e===void 0)return;let{startLine:t,endLine:n}=e;if(t!==void 0&&(!Number.isInteger(t)||t<1))throw Error(`startLine must be a positive integer (1-based).`);if(n!==void 0&&(!Number.isInteger(n)||n<1))throw Error(`endLine must be a positive integer (1-based).`);if(t!==void 0&&n!==void 0&&t>n)throw Error(`startLine must not be greater than endLine.`)}function Al(e){let t=[],n=0;for(let r=0;r<e.length;r++)e[r]===`\r`?r+1<e.length&&e[r+1]===`
|
|
87
87
|
`?(t.push(e.slice(n,r+2)),n=r+2,r++):(t.push(e.slice(n,r+1)),n=r+1):e[r]===`
|
|
88
|
-
`&&(t.push(e.slice(n,r+1)),n=r+1);return n<e.length&&t.push(e.slice(n)),t}function jl(e,t){if(t?.startLine===void 0&&t?.endLine===void 0)return e;let n=Al(e),r=n.length,i=t?.startLine??1,a=Math.min(t?.endLine??r,r);return i>r?``:n.slice(i-1,a).join(``)}function Ml(e,t){return t===`utf-8`||t===`utf8`?new TextDecoder(`utf-8`,{fatal:!0}).decode(e):e.toString(t)}function Nl(e,t){return t===`utf-8`||t===`utf8`?Buffer.from(new TextEncoder().encode(e)):Buffer.from(e,t)}function Pl(){return{name:`local`,async prewarm(e){let t=Bl(dd(e.runtimeContext.appRoot),e.templateKey);if(await Jl(t))return;let n=await Fl({sessionKey:e.templateKey,snapshotPath:t}),r=$(Ll(n));try{e.bootstrap!==void 0&&await e.bootstrap({use:async()=>r});for(let t of e.seedFiles)typeof t.content==`string`?await r.writeTextFile(t.path,t.content):await r.writeBinaryFile(t.path,t.content);if(await n.captureSnapshot()===null)throw Error(`Failed to capture local sandbox template state for "${e.templateKey}".`)}finally{await n.dispose()}},async create(e){let t=dd(e.runtimeContext.appRoot),n=await Kl(Bl(t,e.templateKey));if(n===null)throw new El({backendName:`local`,templateKey:e.templateKey});let r=Yl(e.existingMetadata)??Vl(t,e.sessionKey);return await Jl(r)||await ql(r,n),Il(await Fl({sessionKey:e.sessionKey,snapshotPath:r}))}}}async function Fl(e){let{Bash:t,InMemoryFs:n}=await import(`#compiled/just-bash/index.js`),r=await Kl(e.snapshotPath),i=new n(Hl(r));await Ul(i),await Wl(i,r?.entries??[]);let a=new t({cwd:G,env:r?.env,fs:i,network:{dangerouslyAllowFullInternetAccess:!0}});return{async captureSnapshot(){let t=await Gl({filesystem:i,sandbox:a});return await ql(e.snapshotPath,t),{snapshotPath:e.snapshotPath}},async dispose(){await a.dispose?.()},async executeCommand(e,t){if(t?.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let n=t?.workingDirectory===void 0?e:`( cd ${Y(t.workingDirectory)} && ${e} )`,r=a.exec(n),i=t?.abortSignal?await Rl(r,t.abortSignal):await r;return{exitCode:i.exitCode,stderr:i.stderr,stdout:i.stdout}},async readFileBytes(e){let t;try{t=await i.readFileBuffer(e)}catch{return null}return Buffer.from(t)},async readFileText(e){let t;try{t=await i.readFileBuffer(e)}catch{return null}return new TextDecoder(`utf-8`,{fatal:!0}).decode(t)},sessionKey:e.sessionKey,snapshotPath:e.snapshotPath,async writeFiles(e){for(let t of e){let e=x(t.path);await i.mkdir(e,{recursive:!0}),await i.writeFile(t.path,t.content)}}}}function Il(e){let t=$(Ll(e));return{session:t,useSessionFn:async()=>t,async captureState(){return{backendName:`local`,metadata:await e.captureSnapshot()??{},sessionKey:e.sessionKey}},async dispose(){await e.dispose()}}}function Ll(e){return{id:e.sessionKey,async readFile(t){let n=await e.readFileBytes(t);return n===null?null:Ol(n)},resolvePath:zl,runCommand:(t,n)=>e.executeCommand(t,n),async writeFile(t,n){let r=await Dl(n);await e.writeFiles([{path:t,content:r}])}}}async function Rl(e,t){return await new Promise((n,r)=>{let i=()=>{r(new DOMException(`The operation was aborted.`,`AbortError`))};if(t.aborted){i();return}t.addEventListener(`abort`,i,{once:!0}),e.then(e=>{t.removeEventListener(`abort`,i),n(e)},e=>{t.removeEventListener(`abort`,i),r(e)})})}function zl(e){return e.startsWith(`/`)?e:`${G}/${e}`}function Bl(e,t){return S(e,`local`,`templates`,`${t}.json`)}function Vl(e,t){return S(e,`local`,`sessions`,`${t}.json`)}function Hl(e){let t={};for(let n of e?.entries??[])n.kind===`file`&&(t[n.path]=Buffer.from(n.contentBase64,`base64`));return t}async function Ul(e){await e.mkdir(G,{recursive:!0})}async function Wl(e,t){let n=t.filter(e=>e.kind===`directory`).map(e=>e.path).sort((e,t)=>e.localeCompare(t));for(let t of n)t!==`/workspace`&&await e.mkdir(t,{recursive:!0})}async function Gl(e){let t=[],n=e.filesystem.getAllPaths().sort((e,t)=>e.localeCompare(t));for(let r of n){let n=await e.filesystem.stat(r);if(n.isSymbolicLink)continue;if(n.isDirectory){t.push({kind:`directory`,path:r});continue}if(!n.isFile)continue;let i=await e.filesystem.readFileBuffer(r);t.push({contentBase64:Buffer.from(i).toString(`base64`),kind:`file`,path:r})}return{entries:t,env:{...e.sandbox.getEnv()},version:1}}async function Kl(e){if(!await Jl(e))return null;let t=JSON.parse(await ge(e,`utf8`));return t.version===1?t:null}async function ql(e,t){await w(x(e),{recursive:!0}),await T(e,`${JSON.stringify(t,null,2)}\n`)}async function Jl(e){try{return await me(e),!0}catch{return!1}}function Yl(e){let t=e?.snapshotPath;return typeof t==`string`?t:void 0}function Xl(){return Pl()}function Zl(e={}){let t=e.loadSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox/index.js`)),n={timeout:hu},r=new Map;return{name:`vercel`,async create(e){let i=du(n.tags,e.tags),a;try{a=await Ql({loadSandboxModule:t,prewarmedTemplates:r,templateKey:e.templateKey})}catch(t){throw El.is(t)?t:Error(`Failed to read sandbox template "${e.templateKey}": ${mu(t)}`,{cause:t})}let o;try{o=await eu({createOptions:n,existingMetadata:e.existingMetadata,sandboxModule:await t(),sessionKey:e.sessionKey,snapshotId:a.snapshotId,tags:i})}catch(t){throw Error(`Failed to create sandbox session "${e.sessionKey}": ${mu(t)}`,{cause:t})}return tu(o,e.sessionKey)},async prewarm(e){let i;try{i=await $l({bootstrap:e.bootstrap,createOptions:n,loadSandboxModule:t,seedFiles:e.seedFiles,templateKey:e.templateKey})}catch(t){throw Error(`Failed to prewarm Vercel sandbox template "${e.templateKey}": ${mu(t)}. Run \`vercel login\` and \`vercel link\` so the SDK can authenticate, or set VERCEL_TOKEN.`,{cause:t})}r.set(e.templateKey,i)}}}async function Ql(e){let t=e.prewarmedTemplates.get(e.templateKey);if(t!==void 0)return t;let n=await cu(await e.loadSandboxModule(),e.templateKey);if(n===null||typeof n.currentSnapshotId!=`string`)throw new El({backendName:`vercel`,templateKey:e.templateKey});return{sandboxName:n.name,snapshotId:n.currentSnapshotId,templateKey:e.templateKey}}async function $l(e){let t=await e.loadSandboxModule(),n=await cu(t,e.templateKey),r=du(e.createOptions.tags,e.tags);if(n===null){let i={...e.createOptions,name:e.templateKey,persistent:!1};r!==void 0&&(i.tags=r),n=await t.Sandbox.create(i)}else await fu(n,r);if(typeof n.currentSnapshotId==`string`&&n.currentSnapshotId.length>0)return{sandboxName:n.name,snapshotId:n.currentSnapshotId,templateKey:e.templateKey};await au(n,e.createOptions);let i=$(ru(n,e.templateKey));e.bootstrap!==void 0&&await e.bootstrap({use:async()=>i});for(let t of e.seedFiles)typeof t.content==`string`?await i.writeTextFile(t.path,t.content):await i.writeBinaryFile(t.path,t.content);let a=await n.snapshot();return{sandboxName:n.name,snapshotId:a.snapshotId,templateKey:e.templateKey}}async function eu(e){let t=uu(e.existingMetadata)??e.sessionKey,n=await cu(e.sandboxModule,t);if(n!==null)return await fu(n,e.tags),n;let r={...e.createOptions,name:t,persistent:!0,source:{snapshotId:e.snapshotId,type:`snapshot`}};return e.tags!==void 0&&(r.tags=e.tags),await e.sandboxModule.Sandbox.create(r)}function tu(e,t){return{session:$(ru(e,t)),useSessionFn:async n=>(n!==void 0&&await e.update(n),nu(e,t)),async captureState(){return{backendName:`vercel`,metadata:{sandboxName:e.name},sessionKey:t}},async dispose(){}}}function nu(e,t){return{...$(ru(e,t)),get name(){return e.name},get persistent(){return e.persistent},get status(){return e.status},get networkPolicy(){return e.networkPolicy},get tags(){return e.tags},async update(t){await e.update(t)},async stop(t){await e.stop(t)},async snapshot(t){return await e.snapshot(t)},domain(t){return e.domain(t)}}}function ru(e,t){return{id:t,async readFile(t){return await e.readFile({path:t})??null},resolvePath:iu,async runCommand(t,n){let r=await e.runCommand({args:[`-lc`,t],cmd:`bash`,cwd:n?.workingDirectory??`/workspace`,signal:n?.abortSignal}),[i,a]=await Promise.all([r.stdout(),r.stderr()]);return{exitCode:r.exitCode,stderr:a,stdout:i}},async writeFile(t,n){let r=await Dl(n);await e.writeFiles([{content:r,path:t}])}}}function iu(e){return e.startsWith(`/`)?e:`${G}/${e}`}async function au(e,t){await ou(e,{failureMessage:`Failed to initialize Vercel sandbox workspace.`,script:`mkdir -p ${G} && chown ${su}:${su} ${G}`}),t.networkPolicy!==`deny-all`&&await ou(e,{failureMessage:`Failed to install ripgrep in Vercel sandbox.`,script:`command -v rg >/dev/null 2>&1 || { dnf install -y spal-release && dnf install -y ripgrep; }`})}async function ou(e,t){let n=await e.runCommand({args:[`-lc`,t.script],cmd:`bash`,sudo:!0});if(n.exitCode!==0){let e=await n.stderr();throw Error(`${t.failureMessage} ${e}`.trim())}}const su=`vercel-sandbox`;async function cu(e,t){try{return await e.Sandbox.get({name:t})}catch(e){if(lu(e))return null;throw Error(`Failed to look up Vercel sandbox "${t}": ${mu(e)}`,{cause:e})}}function lu(e){return e instanceof Error?(e.response?.status??e.cause?.response?.status)===404:!1}function uu(e){let t=e?.sandboxName;return typeof t==`string`?t:void 0}function du(e,t){let n={};if(e!==void 0)for(let[t,r]of Object.entries(e))n[t]=r;if(t!==void 0)for(let[e,r]of Object.entries(t))n[e]=r;let r=Object.keys(n).length;if(r!==0){if(r>gu)throw Error(`Vercel Sandbox supports at most ${gu} tags. Ash reserves "agent", "channel", and "sessionId"; remove or consolidate custom tags passed to vercelBackend().`);return n}}async function fu(e,t){t===void 0||pu(e.tags,t)||await e.update({tags:t})}function pu(e,t){let n=e??{},r=Object.entries(n),i=Object.entries(t);return r.length===i.length?i.every(([e,t])=>n[e]===t):!1}function mu(e){return e instanceof Error?e.message:String(e)}const hu=1800*1e3,gu=5;function _u(){return Zl()}function vu(){let e;function t(){return e===void 0&&(e=process.env.VERCEL?_u():Xl()),e}return{get name(){return t().name},create(e){return t().create(e)},async prewarm(e){await t().prewarm(e)}}}async function yu(e,t,r){try{let i=n(await Z({definition:e,kindLabel:`sandbox`,moduleMap:t,nodeId:r}),`Expected the sandbox export "${e.exportName??`default`}" from "${e.logicalPath}" to return an object.`);return{backend:bu(i.backend,e.logicalPath),bootstrap:i.bootstrap,description:e.description,exportName:e.exportName,logicalPath:e.logicalPath,onSession:i.onSession,sourceId:e.sourceId,sourceKind:`module`}}catch(t){throw t instanceof X?t:new X(`Failed to attach the sandbox lifecycle handlers from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function bu(e,t){if(e===void 0)return vu();if(typeof e!=`object`||!e)throw new X(`Sandbox "${t}" exposed a non-object "backend" field. Use vercelBackend(), localBackend(), or another factory that returns a SandboxBackend value.`,{logicalPath:t});let n=e;if(typeof n.name!=`string`||n.name.length===0)throw new X(`Sandbox "${t}" backend is missing a non-empty string "name" identifier.`,{logicalPath:t});if(typeof n.create!=`function`)throw new X(`Sandbox "${t}" backend is missing a "create" function.`,{logicalPath:t});return n}async function xu(e,t,r){try{let i=n(await Z({definition:e,kindLabel:`tool`,moduleMap:t,nodeId:r}),wu(e,`to return an object`)),a=l(i.execute,wu(e,`to provide an execute function`));return{description:e.description,execute:a,exportName:e.exportName,inputSchema:e.inputSchema,logicalPath:e.logicalPath,name:e.name,sourceId:e.sourceId,sourceKind:`module`,...Su(i,e)}}catch(t){throw t instanceof X?t:new X(`Failed to attach the tool execute function from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function Su(e,t){let n={};e.onCompact!==void 0&&(n.onCompact=l(e.onCompact,wu(t,`to provide an onCompact function`))),e.needsApproval!==void 0&&(n.needsApproval=l(e.needsApproval,wu(t,`to provide a needsApproval function`)));let r=Cu(e,t);return r!==void 0&&(n.retentionPolicy=r),e.inputSchema!==void 0&&Tu(e.inputSchema)&&(n.inputStandardSchema=e.inputSchema),n}function Cu(e,t){let n=e.retentionPolicy;if(n!==void 0){if(n===`auto`||n===`keep`||typeof n==`function`)return n;throw new X(wu(t,`to set retentionPolicy to "auto", "keep", or a function`),{logicalPath:t.logicalPath,sourceId:t.sourceId})}}function wu(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}function Tu(e){return typeof e==`object`&&!!e&&`~standard`in e&&typeof e[`~standard`]==`object`}async function Eu(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),n=[],r=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){r.push(t.name);continue}n.push(await Cl(t,e.moduleMap,e.nodeId))}let i=await Promise.all(e.manifest.tools.map(t=>xu(t,e.moduleMap,e.nodeId))),a=await Promise.all(e.manifest.hooks.map(t=>Tl(t,e.moduleMap,e.nodeId))),o=await Promise.all(e.manifest.connections.map(t=>wl(t,e.moduleMap,e.nodeId))),s=e.manifest.sandbox===null?null:await yu(e.manifest.sandbox,e.moduleMap,e.nodeId),c=Du(e.manifest.instructions),l=e.manifest.workspaceResourceRoot,u={channels:n,config:Ou(e.manifest),connections:o,disabledFrameworkChannels:r,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],hooks:a,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:s,workspaceResourceRoot:l,skills:t,tools:i,workspaceSpec:{rootEntries:[...l.rootEntries]}};return c===void 0?u:{...u,instructions:c}}function Du(e){if(e!==void 0)return{name:e.name,logicalPath:e.logicalPath,markdown:e.markdown,sourceId:e.sourceId,sourceKind:e.sourceKind}}function Ou(e){let t={metadata:{...e.config.metadata},model:e.config.model.source===void 0?{id:e.config.model.id,contextWindowTokens:e.config.model.contextWindowTokens,providerOptions:e.config.model.providerOptions}:{contextWindowTokens:e.config.model.contextWindowTokens,id:e.config.model.id,providerOptions:e.config.model.providerOptions,source:{exportName:e.config.model.source.exportName,sourceKind:`module`,logicalPath:e.config.model.source.logicalPath,sourceId:e.config.model.source.sourceId}},name:e.config.name};if(e.config.compaction!==void 0){let n={};e.config.compaction.model!==void 0&&(n.model=e.config.compaction.model.source===void 0?{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions}:{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions,source:{exportName:e.config.compaction.model.source.exportName,sourceKind:`module`,logicalPath:e.config.compaction.model.source.logicalPath,sourceId:e.config.compaction.model.source.sourceId}}),e.config.compaction.thresholdPercent!==void 0&&(n.thresholdPercent=e.config.compaction.thresholdPercent),t.compaction=n}return e.config.source!==void 0&&(t.source=Sl(e.config.source)),t}function ku(e){return{sandbox:{definition:e.authoredSandbox??Au(),workspaceResourceRoot:e.workspaceResourceRoot}}}function Au(){return{backend:vu(),logicalPath:`ash:framework/default-sandbox`,sourceId:`ash:default-sandbox`,sourceKind:`module`}}const ju=`load_skill`,Mu=Object.freeze({type:`object`,properties:Object.freeze({message:Object.freeze({type:`string`,description:`The message to send to the subagent. Provide all context the subagent needs to complete the task; the subagent does not see the parent's history.`})}),required:Object.freeze([`message`]),additionalProperties:!1});function Nu(e){let t=[],n=new Ma(`subagent`,e.reservedToolNames??[]),r=new Map;for(let i of e.subagents){let e={logicalPath:i.logicalPath,sourceId:i.sourceId};if(r.has(i.nodeId))throw new H(`subagent`,`Found multiple runtime subagents mapped to node id "${i.nodeId}".`,{...e,entryName:i.name});let a=Pu(i),o={definition:i,prepared:a};n.register(i.name,o,{location:e,duplicateMessage:`Found multiple subagents named "${i.name}". Subagent names must be unique at runtime.`,reservedMessage:`Subagent "${i.name}" collides with another runtime-visible tool name.`}),t.push(a),r.set(i.nodeId,o)}return{preparedTools:t,subagentsByName:n.asMap(),subagentsByNodeId:r}}function Pu(e){return{description:e.description,inputSchema:Mu,kind:`subagent`,logicalPath:e.logicalPath,name:e.name,nodeId:e.nodeId,sourceId:e.sourceId}}async function Fu(e,t={}){let n=[],r=new Ma(`tool`,t.reservedToolNames??[]);for(let t of e.tools){let e=await Iu(t);r.register(t.name,{definition:t,prepared:e},{location:{logicalPath:t.logicalPath,sourceId:t.sourceId},duplicateMessage:`Found multiple authored tools named "${t.name}". Tool names must be unique at runtime.`,reservedMessage:`Tool "${t.name}" collides with another runtime-visible tool name.`}),n.push(e)}return{preparedTools:n,toolsByName:r.asMap()}}async function Iu(e){return{description:e.description,inputSchema:await Lu(e),kind:`authored-tool`,logicalPath:e.logicalPath,name:e.name,sourceId:e.sourceId}}async function Lu(e){return e.inputSchema}var Ru=class extends Error{logicalPath;nodeId;sourceId;constructor(e,t={}){super(e),this.name=`ResolveRuntimeAgentGraphError`,t.logicalPath!==void 0&&(this.logicalPath=t.logicalPath),t.nodeId!==void 0&&(this.nodeId=t.nodeId),t.sourceId!==void 0&&(this.sourceId=t.sourceId)}};async function zu(e){let t=new Map,n=Uu(e.manifest),r=new Map(e.manifest.subagents.map(e=>[e.nodeId,e]));return{nodesByNodeId:t,root:await Bu({childNodeIdsByParentNodeId:n,manifest:e.manifest,moduleMap:e.moduleMap,nodeId:L,nodesByNodeId:t,subagentNodesById:r})}}async function Bu(e){let t=Wu(e.nodeId);if(e.nodesByNodeId.has(t))throw new Ru(`Found multiple runtime agent nodes for node id "${t}".`,{nodeId:t,sourceId:e.sourceId});let n=await Eu({manifest:e.manifest,moduleMap:e.moduleMap,nodeId:e.nodeId}),r=n.connections.length>0,i=yl({hasConnections:r}),a=r?Ku(i,n.connections):i,o=new Set(a.map(e=>e.name)),s=bl(),c=new Set(n.tools.map(e=>e.name));for(let r of n.disabledFrameworkTools)if(!s.has(r))throw new Ru(`agent/tools/${r}.ts exports disableTool() but "${r}" is not a framework tool. Rename the file to one of: ${[...s].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let l=new Set(n.disabledFrameworkTools),u=await Fu({tools:[...a.filter(e=>!c.has(e.name)&&!l.has(e.name)),...n.tools]},{reservedToolNames:o.has(`load_skill`)||c.has(`load_skill`)?[]:[ju]}),d=new Set(n.channels.map(e=>e.name)),f=tc();for(let r of n.disabledFrameworkChannels)if(!f.has(r))throw new Ru(`agent/channels/${r}.ts exports disableRoute() but "${r}" is not a framework channel. Rename the file to one of: ${[...f].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let p=new Set(n.disabledFrameworkChannels),m=[...ec().filter(e=>!d.has(e.name)&&!p.has(e.name)),...n.channels],h=ku({authoredSandbox:n.sandbox,workspaceResourceRoot:n.workspaceResourceRoot}),g=Nu({reservedToolNames:[ju,...u.preparedTools.map(e=>e.name)],subagents:await Vu({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,parentNodeId:e.nodeId,subagentNodesById:e.subagentNodesById})}),_={agent:n,channels:m,hookRegistry:xl(n.hooks),nodeId:t,sandboxRegistry:h,sourceId:e.sourceId,subagentRegistry:g,toolRegistry:u,turnAgent:Jo({agent:n,nodeId:t,tools:[...u.preparedTools,...g.preparedTools]})};return e.nodesByNodeId.set(t,_),_}async function Vu(e){let t=[],n=e.childNodeIdsByParentNodeId.get(e.parentNodeId)??[];for(let r of n){let n=e.subagentNodesById.get(r);if(n===void 0)throw new Ru(`Missing compiled subagent node "${r}" while resolving runtime subagents.`,{nodeId:Wu(e.parentNodeId),sourceId:r});t.push(await Hu({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,sourceRef:n,subagentNodesById:e.subagentNodesById}))}return t}async function Hu(e){let t={description:e.sourceRef.description,logicalPath:e.sourceRef.logicalPath,name:e.sourceRef.name,nodeId:Wu(e.sourceRef.nodeId),sourceId:e.sourceRef.sourceId,sourceKind:`module`};return await Bu({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.sourceRef.agent,moduleMap:e.moduleMap,nodeId:e.sourceRef.nodeId,nodesByNodeId:e.nodesByNodeId,sourceId:e.sourceRef.sourceId,subagentNodesById:e.subagentNodesById}),t}function Uu(e){let t=new Map;for(let n of e.subagentEdges){let e=t.get(n.parentNodeId);if(e===void 0){t.set(n.parentNodeId,[n.childNodeId]);continue}e.push(n.childNodeId)}return t}function Wu(e){return e===`__root__`?so:e}const Gu=Fo.name;function Ku(e,t){let n=t.map(e=>e.connectionName).join(`, `);return e.map(e=>e.name===Gu?{...e,description:`${e.description} Available connections: ${n}.`}:e)}const qu=process.env.ASH_DISABLE_AGENT_CACHE===`1`;async function Ju(e){let[t,n]=await Promise.all([fo({compiledArtifactsSource:e}),Yu(e)]),r=await zu({manifest:t,moduleMap:n}),i=r.root;return{adapterRegistry:Ia({channels:ed(r)}),compiledArtifactsSource:e,graph:r,hookRegistry:i.hookRegistry,moduleMap:n,resolvedAgent:i.agent,subagentRegistry:i.subagentRegistry,toolRegistry:i.toolRegistry,turnAgent:i.turnAgent}}async function Yu(e){return e.kind===`disk`&&e.moduleMapLoadMode===`authored-source`?await Xu(e):await _o({compiledArtifactsSource:e})}async function Xu(e){if(e.moduleMapLoaderPath===void 0)throw Error(`Authored-source module map loading requires "moduleMapLoaderPath" in the compiled artifacts source.`);return await(await import(xe(e.moduleMapLoaderPath).href)).loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:e})}async function Zu(e){if(qu)return Ju(e);let t=Xa(),n=Ha(e),r=await io(e),i=t.bundleCacheKeyBySourceKey.get(n);i!==void 0&&i!==r&&t.bundleCache.delete(i),t.bundleCacheKeyBySourceKey.set(n,r);let a=t.bundleCache.get(r);if(a!==void 0)return a;let o=Ju(e).catch(e=>{throw t.bundleCache.delete(r),t.bundleCacheKeyBySourceKey.get(n)===r&&t.bundleCacheKeyBySourceKey.delete(n),e});return t.bundleCache.set(r,o),o}async function Qu(e){let t=await Zu(e.compiledArtifactsSource);if(e.nodeId===void 0)return t;let n=co(t.graph,e.nodeId);return{adapterRegistry:t.adapterRegistry,compiledArtifactsSource:t.compiledArtifactsSource,graph:{nodesByNodeId:t.graph.nodesByNodeId,root:n},hookRegistry:n.hookRegistry,moduleMap:t.moduleMap,nodeId:e.nodeId,resolvedAgent:n.agent,subagentRegistry:n.subagentRegistry,toolRegistry:n.toolRegistry,turnAgent:n.turnAgent}}function $u(){let e=Xa();e.bundleCache.clear(),e.bundleCacheKeyBySourceKey.clear()}function ed(e){let t=new Map;for(let n of e.nodesByNodeId.values())for(let e of n.channels)t.set(`${e.sourceId}:${e.name}`,e);return[...t.values()]}new B(`ash.channel`,{codec:{serialize(e){return{kind:xa(e),state:e.state?{...e.state}:{}}},deserialize(e,t){let n=t.get(td);if(n===void 0)throw Error(`Cannot deserialize "ash.channel" before "ash.bundle". The runtime bundle must be present in context.`);return La(n.adapterRegistry,e)}}});const td=new B(`ash.bundle`,{codec:{serialize:e=>({nodeId:e.nodeId,source:e.compiledArtifactsSource}),deserialize:e=>{let{source:t,nodeId:n}=e;return Qu({compiledArtifactsSource:t,nodeId:n})}}});new B(`ash.session`);const nd=new B(`ash.sandbox`),rd=v(),id={workflowId:`workflow//${rd.name}@${rd.version}//workflowEntry`};function ad(e=process.cwd()){return C(e)}function od(e){return be(`sha256`).update(e).update(`\0`).update(id.workflowId).digest(`hex`).slice(0,12)}function sd(){return!!process.env.VERCEL}function cd(e,t=`all`){let n=S(e,`.ash`,`nitro`);return t===`all`?n:S(n,t)}function ld(e,t){return S(e,`.ash`,`nitro-output`,t)}function ud(e){return S(h(),`.ash`,`workflow-cache`,od(e))}function dd(e){return S(e,`.ash`,`sandbox-cache`)}function fd(e){return sd()?S(e,`.vercel`,`output`):S(e,`.output`)}function pd(e){return{appRoot:e,outputDir:fd(e),workflowId:id.workflowId,workflowBuildDir:ud(e),workflowSourceDir:_(`src/execution`)}}export{Sr as C,jn as D,L as E,Dr as S,Cr as T,Ha as _,ud as a,Qr as b,tc as c,fo as d,so as f,Va as g,Ba as h,ld as i,ec as l,U as m,ad as n,$u as o,to as p,cd as r,zu as s,pd as t,G as u,Qi as v,wr as w,kr as x,$i as y};
|
|
88
|
+
`&&(t.push(e.slice(n,r+1)),n=r+1);return n<e.length&&t.push(e.slice(n)),t}function jl(e,t){if(t?.startLine===void 0&&t?.endLine===void 0)return e;let n=Al(e),r=n.length,i=t?.startLine??1,a=Math.min(t?.endLine??r,r);return i>r?``:n.slice(i-1,a).join(``)}function Ml(e,t){return t===`utf-8`||t===`utf8`?new TextDecoder(`utf-8`,{fatal:!0}).decode(e):e.toString(t)}function Nl(e,t){return t===`utf-8`||t===`utf8`?Buffer.from(new TextEncoder().encode(e)):Buffer.from(e,t)}function Pl(){return{name:`local`,async prewarm(e){let t=Bl(dd(e.runtimeContext.appRoot),e.templateKey);if(await Jl(t))return;let n=await Fl({sessionKey:e.templateKey,snapshotPath:t}),r=$(Ll(n));try{e.bootstrap!==void 0&&await e.bootstrap({use:async()=>r});for(let t of e.seedFiles)typeof t.content==`string`?await r.writeTextFile(t.path,t.content):await r.writeBinaryFile(t.path,t.content);if(await n.captureSnapshot()===null)throw Error(`Failed to capture local sandbox template state for "${e.templateKey}".`)}finally{await n.dispose()}},async create(e){let t=dd(e.runtimeContext.appRoot),n=await Kl(Bl(t,e.templateKey));if(n===null)throw new El({backendName:`local`,templateKey:e.templateKey});let r=Yl(e.existingMetadata)??Vl(t,e.sessionKey);return await Jl(r)||await ql(r,n),Il(await Fl({sessionKey:e.sessionKey,snapshotPath:r}))}}}async function Fl(e){let{Bash:t,InMemoryFs:n}=await import(`#compiled/just-bash/index.js`),r=await Kl(e.snapshotPath),i=new n(Hl(r));await Ul(i),await Wl(i,r?.entries??[]);let a=new t({cwd:G,env:r?.env,fs:i,network:{dangerouslyAllowFullInternetAccess:!0}});return{async captureSnapshot(){let t=await Gl({filesystem:i,sandbox:a});return await ql(e.snapshotPath,t),{snapshotPath:e.snapshotPath}},async dispose(){await a.dispose?.()},async executeCommand(e,t){if(t?.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let n=t?.workingDirectory===void 0?e:`( cd ${Y(t.workingDirectory)} && ${e} )`,r=a.exec(n),i=t?.abortSignal?await Rl(r,t.abortSignal):await r;return{exitCode:i.exitCode,stderr:i.stderr,stdout:i.stdout}},async readFileBytes(e){let t;try{t=await i.readFileBuffer(e)}catch{return null}return Buffer.from(t)},async readFileText(e){let t;try{t=await i.readFileBuffer(e)}catch{return null}return new TextDecoder(`utf-8`,{fatal:!0}).decode(t)},sessionKey:e.sessionKey,snapshotPath:e.snapshotPath,async writeFiles(e){for(let t of e){let e=x(t.path);await i.mkdir(e,{recursive:!0}),await i.writeFile(t.path,t.content)}}}}function Il(e){let t=$(Ll(e));return{session:t,useSessionFn:async()=>t,async captureState(){return{backendName:`local`,metadata:await e.captureSnapshot()??{},sessionKey:e.sessionKey}},async dispose(){await e.dispose()}}}function Ll(e){return{id:e.sessionKey,async readFile(t){let n=await e.readFileBytes(t);return n===null?null:Ol(n)},resolvePath:zl,runCommand:(t,n)=>e.executeCommand(t,n),async writeFile(t,n){let r=await Dl(n);await e.writeFiles([{path:t,content:r}])}}}async function Rl(e,t){return await new Promise((n,r)=>{let i=()=>{r(new DOMException(`The operation was aborted.`,`AbortError`))};if(t.aborted){i();return}t.addEventListener(`abort`,i,{once:!0}),e.then(e=>{t.removeEventListener(`abort`,i),n(e)},e=>{t.removeEventListener(`abort`,i),r(e)})})}function zl(e){return e.startsWith(`/`)?e:`${G}/${e}`}function Bl(e,t){return S(e,`local`,`templates`,`${t}.json`)}function Vl(e,t){return S(e,`local`,`sessions`,`${t}.json`)}function Hl(e){let t={};for(let n of e?.entries??[])n.kind===`file`&&(t[n.path]=Buffer.from(n.contentBase64,`base64`));return t}async function Ul(e){await e.mkdir(G,{recursive:!0})}async function Wl(e,t){let n=t.filter(e=>e.kind===`directory`).map(e=>e.path).sort((e,t)=>e.localeCompare(t));for(let t of n)t!==`/workspace`&&await e.mkdir(t,{recursive:!0})}async function Gl(e){let t=[],n=e.filesystem.getAllPaths().sort((e,t)=>e.localeCompare(t));for(let r of n){let n=await e.filesystem.stat(r);if(n.isSymbolicLink)continue;if(n.isDirectory){t.push({kind:`directory`,path:r});continue}if(!n.isFile)continue;let i=await e.filesystem.readFileBuffer(r);t.push({contentBase64:Buffer.from(i).toString(`base64`),kind:`file`,path:r})}return{entries:t,env:{...e.sandbox.getEnv()},version:1}}async function Kl(e){if(!await Jl(e))return null;let t=JSON.parse(await ge(e,`utf8`));return t.version===1?t:null}async function ql(e,t){await w(x(e),{recursive:!0}),await T(e,`${JSON.stringify(t,null,2)}\n`)}async function Jl(e){try{return await me(e),!0}catch{return!1}}function Yl(e){let t=e?.snapshotPath;return typeof t==`string`?t:void 0}function Xl(){return Pl()}function Zl(e={}){let t=e.loadSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox/index.js`)),n={timeout:hu},r=new Map;return{name:`vercel`,async create(e){let i=du(n.tags,e.tags),a;try{a=await Ql({loadSandboxModule:t,prewarmedTemplates:r,templateKey:e.templateKey})}catch(t){throw El.is(t)?t:Error(`Failed to read sandbox template "${e.templateKey}": ${mu(t)}`,{cause:t})}let o;try{o=await eu({createOptions:n,existingMetadata:e.existingMetadata,sandboxModule:await t(),sessionKey:e.sessionKey,snapshotId:a.snapshotId,tags:i})}catch(t){throw Error(`Failed to create sandbox session "${e.sessionKey}": ${mu(t)}`,{cause:t})}return tu(o,e.sessionKey)},async prewarm(e){let i;try{i=await $l({bootstrap:e.bootstrap,createOptions:n,loadSandboxModule:t,seedFiles:e.seedFiles,templateKey:e.templateKey})}catch(t){throw Error(`Failed to prewarm Vercel sandbox template "${e.templateKey}": ${mu(t)}. Run \`vercel login\` and \`vercel link\` so the SDK can authenticate, or set VERCEL_TOKEN.`,{cause:t})}r.set(e.templateKey,i)}}}async function Ql(e){let t=e.prewarmedTemplates.get(e.templateKey);if(t!==void 0)return t;let n=await cu(await e.loadSandboxModule(),e.templateKey);if(n===null||typeof n.currentSnapshotId!=`string`)throw new El({backendName:`vercel`,templateKey:e.templateKey});return{sandboxName:n.name,snapshotId:n.currentSnapshotId,templateKey:e.templateKey}}async function $l(e){let t=await e.loadSandboxModule(),n=await cu(t,e.templateKey),r=du(e.createOptions.tags,e.tags);if(n===null){let i={...e.createOptions,name:e.templateKey,persistent:!1};r!==void 0&&(i.tags=r),n=await t.Sandbox.create(i)}else await fu(n,r);if(typeof n.currentSnapshotId==`string`&&n.currentSnapshotId.length>0)return{sandboxName:n.name,snapshotId:n.currentSnapshotId,templateKey:e.templateKey};await au(n,e.createOptions);let i=$(ru(n,e.templateKey));e.bootstrap!==void 0&&await e.bootstrap({use:async e=>(e!==void 0&&await n.update(e),i)});for(let t of e.seedFiles)typeof t.content==`string`?await i.writeTextFile(t.path,t.content):await i.writeBinaryFile(t.path,t.content);let a=await n.snapshot();return{sandboxName:n.name,snapshotId:a.snapshotId,templateKey:e.templateKey}}async function eu(e){let t=uu(e.existingMetadata)??e.sessionKey,n=await cu(e.sandboxModule,t);if(n!==null)return await fu(n,e.tags),n;let r={...e.createOptions,name:t,persistent:!0,source:{snapshotId:e.snapshotId,type:`snapshot`}};return e.tags!==void 0&&(r.tags=e.tags),await e.sandboxModule.Sandbox.create(r)}function tu(e,t){return{session:$(ru(e,t)),useSessionFn:async n=>(n!==void 0&&await e.update(n),nu(e,t)),async captureState(){return{backendName:`vercel`,metadata:{sandboxName:e.name},sessionKey:t}},async dispose(){}}}function nu(e,t){return{...$(ru(e,t)),get name(){return e.name},get persistent(){return e.persistent},get status(){return e.status},get networkPolicy(){return e.networkPolicy},get tags(){return e.tags},async update(t){await e.update(t)},async stop(t){await e.stop(t)},async snapshot(t){return await e.snapshot(t)},domain(t){return e.domain(t)}}}function ru(e,t){return{id:t,async readFile(t){return await e.readFile({path:t})??null},resolvePath:iu,async runCommand(t,n){let r=await e.runCommand({args:[`-lc`,t],cmd:`bash`,cwd:n?.workingDirectory??`/workspace`,signal:n?.abortSignal}),[i,a]=await Promise.all([r.stdout(),r.stderr()]);return{exitCode:r.exitCode,stderr:a,stdout:i}},async writeFile(t,n){let r=await Dl(n);await e.writeFiles([{content:r,path:t}])}}}function iu(e){return e.startsWith(`/`)?e:`${G}/${e}`}async function au(e,t){await ou(e,{failureMessage:`Failed to initialize Vercel sandbox workspace.`,script:`mkdir -p ${G} && chown ${su}:${su} ${G}`}),t.networkPolicy!==`deny-all`&&await ou(e,{failureMessage:`Failed to install ripgrep in Vercel sandbox.`,script:`command -v rg >/dev/null 2>&1 || { dnf install -y spal-release && dnf install -y ripgrep; }`})}async function ou(e,t){let n=await e.runCommand({args:[`-lc`,t.script],cmd:`bash`,sudo:!0});if(n.exitCode!==0){let e=await n.stderr();throw Error(`${t.failureMessage} ${e}`.trim())}}const su=`vercel-sandbox`;async function cu(e,t){try{return await e.Sandbox.get({name:t})}catch(e){if(lu(e))return null;throw Error(`Failed to look up Vercel sandbox "${t}": ${mu(e)}`,{cause:e})}}function lu(e){return e instanceof Error?(e.response?.status??e.cause?.response?.status)===404:!1}function uu(e){let t=e?.sandboxName;return typeof t==`string`?t:void 0}function du(e,t){let n={};if(e!==void 0)for(let[t,r]of Object.entries(e))n[t]=r;if(t!==void 0)for(let[e,r]of Object.entries(t))n[e]=r;let r=Object.keys(n).length;if(r!==0){if(r>gu)throw Error(`Vercel Sandbox supports at most ${gu} tags. Ash reserves "agent", "channel", and "sessionId"; remove or consolidate custom tags passed to vercelBackend().`);return n}}async function fu(e,t){t===void 0||pu(e.tags,t)||await e.update({tags:t})}function pu(e,t){let n=e??{},r=Object.entries(n),i=Object.entries(t);return r.length===i.length?i.every(([e,t])=>n[e]===t):!1}function mu(e){return e instanceof Error?e.message:String(e)}const hu=1800*1e3,gu=5;function _u(){return Zl()}function vu(){let e;function t(){return e===void 0&&(e=process.env.VERCEL?_u():Xl()),e}return{get name(){return t().name},create(e){return t().create(e)},async prewarm(e){await t().prewarm(e)}}}async function yu(e,t,r){try{let i=n(await Z({definition:e,kindLabel:`sandbox`,moduleMap:t,nodeId:r}),`Expected the sandbox export "${e.exportName??`default`}" from "${e.logicalPath}" to return an object.`);return{backend:bu(i.backend,e.logicalPath),bootstrap:i.bootstrap,description:e.description,exportName:e.exportName,logicalPath:e.logicalPath,onSession:i.onSession,sourceId:e.sourceId,sourceKind:`module`}}catch(t){throw t instanceof X?t:new X(`Failed to attach the sandbox lifecycle handlers from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function bu(e,t){if(e===void 0)return vu();if(typeof e!=`object`||!e)throw new X(`Sandbox "${t}" exposed a non-object "backend" field. Use vercelBackend(), localBackend(), or another factory that returns a SandboxBackend value.`,{logicalPath:t});let n=e;if(typeof n.name!=`string`||n.name.length===0)throw new X(`Sandbox "${t}" backend is missing a non-empty string "name" identifier.`,{logicalPath:t});if(typeof n.create!=`function`)throw new X(`Sandbox "${t}" backend is missing a "create" function.`,{logicalPath:t});return n}async function xu(e,t,r){try{let i=n(await Z({definition:e,kindLabel:`tool`,moduleMap:t,nodeId:r}),wu(e,`to return an object`)),a=l(i.execute,wu(e,`to provide an execute function`));return{description:e.description,execute:a,exportName:e.exportName,inputSchema:e.inputSchema,logicalPath:e.logicalPath,name:e.name,sourceId:e.sourceId,sourceKind:`module`,...Su(i,e)}}catch(t){throw t instanceof X?t:new X(`Failed to attach the tool execute function from "${e.logicalPath}": ${m(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function Su(e,t){let n={};e.onCompact!==void 0&&(n.onCompact=l(e.onCompact,wu(t,`to provide an onCompact function`))),e.needsApproval!==void 0&&(n.needsApproval=l(e.needsApproval,wu(t,`to provide a needsApproval function`)));let r=Cu(e,t);return r!==void 0&&(n.retentionPolicy=r),e.inputSchema!==void 0&&Tu(e.inputSchema)&&(n.inputStandardSchema=e.inputSchema),n}function Cu(e,t){let n=e.retentionPolicy;if(n!==void 0){if(n===`auto`||n===`keep`||typeof n==`function`)return n;throw new X(wu(t,`to set retentionPolicy to "auto", "keep", or a function`),{logicalPath:t.logicalPath,sourceId:t.sourceId})}}function wu(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}function Tu(e){return typeof e==`object`&&!!e&&`~standard`in e&&typeof e[`~standard`]==`object`}async function Eu(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),n=[],r=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){r.push(t.name);continue}n.push(await Cl(t,e.moduleMap,e.nodeId))}let i=await Promise.all(e.manifest.tools.map(t=>xu(t,e.moduleMap,e.nodeId))),a=await Promise.all(e.manifest.hooks.map(t=>Tl(t,e.moduleMap,e.nodeId))),o=await Promise.all(e.manifest.connections.map(t=>wl(t,e.moduleMap,e.nodeId))),s=e.manifest.sandbox===null?null:await yu(e.manifest.sandbox,e.moduleMap,e.nodeId),c=Du(e.manifest.instructions),l=e.manifest.workspaceResourceRoot,u={channels:n,config:Ou(e.manifest),connections:o,disabledFrameworkChannels:r,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],hooks:a,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:s,workspaceResourceRoot:l,skills:t,tools:i,workspaceSpec:{rootEntries:[...l.rootEntries]}};return c===void 0?u:{...u,instructions:c}}function Du(e){if(e!==void 0)return{name:e.name,logicalPath:e.logicalPath,markdown:e.markdown,sourceId:e.sourceId,sourceKind:e.sourceKind}}function Ou(e){let t={metadata:{...e.config.metadata},model:e.config.model.source===void 0?{id:e.config.model.id,contextWindowTokens:e.config.model.contextWindowTokens,providerOptions:e.config.model.providerOptions}:{contextWindowTokens:e.config.model.contextWindowTokens,id:e.config.model.id,providerOptions:e.config.model.providerOptions,source:{exportName:e.config.model.source.exportName,sourceKind:`module`,logicalPath:e.config.model.source.logicalPath,sourceId:e.config.model.source.sourceId}},name:e.config.name};if(e.config.compaction!==void 0){let n={};e.config.compaction.model!==void 0&&(n.model=e.config.compaction.model.source===void 0?{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions}:{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions,source:{exportName:e.config.compaction.model.source.exportName,sourceKind:`module`,logicalPath:e.config.compaction.model.source.logicalPath,sourceId:e.config.compaction.model.source.sourceId}}),e.config.compaction.thresholdPercent!==void 0&&(n.thresholdPercent=e.config.compaction.thresholdPercent),t.compaction=n}return e.config.source!==void 0&&(t.source=Sl(e.config.source)),t}function ku(e){return{sandbox:{definition:e.authoredSandbox??Au(),workspaceResourceRoot:e.workspaceResourceRoot}}}function Au(){return{backend:vu(),logicalPath:`ash:framework/default-sandbox`,sourceId:`ash:default-sandbox`,sourceKind:`module`}}const ju=`load_skill`,Mu=Object.freeze({type:`object`,properties:Object.freeze({message:Object.freeze({type:`string`,description:`The message to send to the subagent. Provide all context the subagent needs to complete the task; the subagent does not see the parent's history.`})}),required:Object.freeze([`message`]),additionalProperties:!1});function Nu(e){let t=[],n=new Ma(`subagent`,e.reservedToolNames??[]),r=new Map;for(let i of e.subagents){let e={logicalPath:i.logicalPath,sourceId:i.sourceId};if(r.has(i.nodeId))throw new H(`subagent`,`Found multiple runtime subagents mapped to node id "${i.nodeId}".`,{...e,entryName:i.name});let a=Pu(i),o={definition:i,prepared:a};n.register(i.name,o,{location:e,duplicateMessage:`Found multiple subagents named "${i.name}". Subagent names must be unique at runtime.`,reservedMessage:`Subagent "${i.name}" collides with another runtime-visible tool name.`}),t.push(a),r.set(i.nodeId,o)}return{preparedTools:t,subagentsByName:n.asMap(),subagentsByNodeId:r}}function Pu(e){return{description:e.description,inputSchema:Mu,kind:`subagent`,logicalPath:e.logicalPath,name:e.name,nodeId:e.nodeId,sourceId:e.sourceId}}async function Fu(e,t={}){let n=[],r=new Ma(`tool`,t.reservedToolNames??[]);for(let t of e.tools){let e=await Iu(t);r.register(t.name,{definition:t,prepared:e},{location:{logicalPath:t.logicalPath,sourceId:t.sourceId},duplicateMessage:`Found multiple authored tools named "${t.name}". Tool names must be unique at runtime.`,reservedMessage:`Tool "${t.name}" collides with another runtime-visible tool name.`}),n.push(e)}return{preparedTools:n,toolsByName:r.asMap()}}async function Iu(e){return{description:e.description,inputSchema:await Lu(e),kind:`authored-tool`,logicalPath:e.logicalPath,name:e.name,sourceId:e.sourceId}}async function Lu(e){return e.inputSchema}var Ru=class extends Error{logicalPath;nodeId;sourceId;constructor(e,t={}){super(e),this.name=`ResolveRuntimeAgentGraphError`,t.logicalPath!==void 0&&(this.logicalPath=t.logicalPath),t.nodeId!==void 0&&(this.nodeId=t.nodeId),t.sourceId!==void 0&&(this.sourceId=t.sourceId)}};async function zu(e){let t=new Map,n=Uu(e.manifest),r=new Map(e.manifest.subagents.map(e=>[e.nodeId,e]));return{nodesByNodeId:t,root:await Bu({childNodeIdsByParentNodeId:n,manifest:e.manifest,moduleMap:e.moduleMap,nodeId:L,nodesByNodeId:t,subagentNodesById:r})}}async function Bu(e){let t=Wu(e.nodeId);if(e.nodesByNodeId.has(t))throw new Ru(`Found multiple runtime agent nodes for node id "${t}".`,{nodeId:t,sourceId:e.sourceId});let n=await Eu({manifest:e.manifest,moduleMap:e.moduleMap,nodeId:e.nodeId}),r=n.connections.length>0,i=yl({hasConnections:r}),a=r?Ku(i,n.connections):i,o=new Set(a.map(e=>e.name)),s=bl(),c=new Set(n.tools.map(e=>e.name));for(let r of n.disabledFrameworkTools)if(!s.has(r))throw new Ru(`agent/tools/${r}.ts exports disableTool() but "${r}" is not a framework tool. Rename the file to one of: ${[...s].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let l=new Set(n.disabledFrameworkTools),u=await Fu({tools:[...a.filter(e=>!c.has(e.name)&&!l.has(e.name)),...n.tools]},{reservedToolNames:o.has(`load_skill`)||c.has(`load_skill`)?[]:[ju]}),d=new Set(n.channels.map(e=>e.name)),f=tc();for(let r of n.disabledFrameworkChannels)if(!f.has(r))throw new Ru(`agent/channels/${r}.ts exports disableRoute() but "${r}" is not a framework channel. Rename the file to one of: ${[...f].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let p=new Set(n.disabledFrameworkChannels),m=[...ec().filter(e=>!d.has(e.name)&&!p.has(e.name)),...n.channels],h=ku({authoredSandbox:n.sandbox,workspaceResourceRoot:n.workspaceResourceRoot}),g=Nu({reservedToolNames:[ju,...u.preparedTools.map(e=>e.name)],subagents:await Vu({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,parentNodeId:e.nodeId,subagentNodesById:e.subagentNodesById})}),_={agent:n,channels:m,hookRegistry:xl(n.hooks),nodeId:t,sandboxRegistry:h,sourceId:e.sourceId,subagentRegistry:g,toolRegistry:u,turnAgent:Jo({agent:n,nodeId:t,tools:[...u.preparedTools,...g.preparedTools]})};return e.nodesByNodeId.set(t,_),_}async function Vu(e){let t=[],n=e.childNodeIdsByParentNodeId.get(e.parentNodeId)??[];for(let r of n){let n=e.subagentNodesById.get(r);if(n===void 0)throw new Ru(`Missing compiled subagent node "${r}" while resolving runtime subagents.`,{nodeId:Wu(e.parentNodeId),sourceId:r});t.push(await Hu({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,sourceRef:n,subagentNodesById:e.subagentNodesById}))}return t}async function Hu(e){let t={description:e.sourceRef.description,logicalPath:e.sourceRef.logicalPath,name:e.sourceRef.name,nodeId:Wu(e.sourceRef.nodeId),sourceId:e.sourceRef.sourceId,sourceKind:`module`};return await Bu({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.sourceRef.agent,moduleMap:e.moduleMap,nodeId:e.sourceRef.nodeId,nodesByNodeId:e.nodesByNodeId,sourceId:e.sourceRef.sourceId,subagentNodesById:e.subagentNodesById}),t}function Uu(e){let t=new Map;for(let n of e.subagentEdges){let e=t.get(n.parentNodeId);if(e===void 0){t.set(n.parentNodeId,[n.childNodeId]);continue}e.push(n.childNodeId)}return t}function Wu(e){return e===`__root__`?so:e}const Gu=Fo.name;function Ku(e,t){let n=t.map(e=>e.connectionName).join(`, `);return e.map(e=>e.name===Gu?{...e,description:`${e.description} Available connections: ${n}.`}:e)}const qu=process.env.ASH_DISABLE_AGENT_CACHE===`1`;async function Ju(e){let[t,n]=await Promise.all([fo({compiledArtifactsSource:e}),Yu(e)]),r=await zu({manifest:t,moduleMap:n}),i=r.root;return{adapterRegistry:Ia({channels:ed(r)}),compiledArtifactsSource:e,graph:r,hookRegistry:i.hookRegistry,moduleMap:n,resolvedAgent:i.agent,subagentRegistry:i.subagentRegistry,toolRegistry:i.toolRegistry,turnAgent:i.turnAgent}}async function Yu(e){return e.kind===`disk`&&e.moduleMapLoadMode===`authored-source`?await Xu(e):await _o({compiledArtifactsSource:e})}async function Xu(e){if(e.moduleMapLoaderPath===void 0)throw Error(`Authored-source module map loading requires "moduleMapLoaderPath" in the compiled artifacts source.`);return await(await import(xe(e.moduleMapLoaderPath).href)).loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:e})}async function Zu(e){if(qu)return Ju(e);let t=Xa(),n=Ha(e),r=await io(e),i=t.bundleCacheKeyBySourceKey.get(n);i!==void 0&&i!==r&&t.bundleCache.delete(i),t.bundleCacheKeyBySourceKey.set(n,r);let a=t.bundleCache.get(r);if(a!==void 0)return a;let o=Ju(e).catch(e=>{throw t.bundleCache.delete(r),t.bundleCacheKeyBySourceKey.get(n)===r&&t.bundleCacheKeyBySourceKey.delete(n),e});return t.bundleCache.set(r,o),o}async function Qu(e){let t=await Zu(e.compiledArtifactsSource);if(e.nodeId===void 0)return t;let n=co(t.graph,e.nodeId);return{adapterRegistry:t.adapterRegistry,compiledArtifactsSource:t.compiledArtifactsSource,graph:{nodesByNodeId:t.graph.nodesByNodeId,root:n},hookRegistry:n.hookRegistry,moduleMap:t.moduleMap,nodeId:e.nodeId,resolvedAgent:n.agent,subagentRegistry:n.subagentRegistry,toolRegistry:n.toolRegistry,turnAgent:n.turnAgent}}function $u(){let e=Xa();e.bundleCache.clear(),e.bundleCacheKeyBySourceKey.clear()}function ed(e){let t=new Map;for(let n of e.nodesByNodeId.values())for(let e of n.channels)t.set(`${e.sourceId}:${e.name}`,e);return[...t.values()]}new B(`ash.channel`,{codec:{serialize(e){return{kind:xa(e),state:e.state?{...e.state}:{}}},deserialize(e,t){let n=t.get(td);if(n===void 0)throw Error(`Cannot deserialize "ash.channel" before "ash.bundle". The runtime bundle must be present in context.`);return La(n.adapterRegistry,e)}}});const td=new B(`ash.bundle`,{codec:{serialize:e=>({nodeId:e.nodeId,source:e.compiledArtifactsSource}),deserialize:e=>{let{source:t,nodeId:n}=e;return Qu({compiledArtifactsSource:t,nodeId:n})}}});new B(`ash.session`);const nd=new B(`ash.sandbox`),rd=v(),id={workflowId:`workflow//${rd.name}@${rd.version}//workflowEntry`};function ad(e=process.cwd()){return C(e)}function od(e){return be(`sha256`).update(e).update(`\0`).update(id.workflowId).digest(`hex`).slice(0,12)}function sd(){return!!process.env.VERCEL}function cd(e,t=`all`){let n=S(e,`.ash`,`nitro`);return t===`all`?n:S(n,t)}function ld(e,t){return S(e,`.ash`,`nitro-output`,t)}function ud(e){return S(h(),`.ash`,`workflow-cache`,od(e))}function dd(e){return S(e,`.ash`,`sandbox-cache`)}function fd(e){return sd()?S(e,`.vercel`,`output`):S(e,`.output`)}function pd(e){return{appRoot:e,outputDir:fd(e),workflowId:id.workflowId,workflowBuildDir:ud(e),workflowSourceDir:_(`src/execution`)}}export{Sr as C,jn as D,L as E,Dr as S,Cr as T,Ha as _,ud as a,Qr as b,tc as c,fo as d,so as f,Va as g,Ba as h,ld as i,ec as l,U as m,ad as n,$u as o,to as p,cd as r,zu as s,pd as t,G as u,Qi as v,wr as w,kr as x,$i as y};
|
|
@@ -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-
|
|
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-CFoo44rU.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-
|
|
1
|
+
import{D as e,b as t,t as n,v as r,y as i}from"../../chunks/paths-CFoo44rU.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};
|
package/dist/src/cli/run.js
CHANGED
|
@@ -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-
|
|
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-ByUKG--q.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-ByUKG--q.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};
|
|
@@ -19,10 +19,18 @@ export type NetworkPolicy =
|
|
|
19
19
|
| undefined;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
export interface SandboxKeepLastSnapshotsConfig {
|
|
23
|
+
count: number;
|
|
24
|
+
expiration?: number | undefined;
|
|
25
|
+
deleteEvicted?: boolean | undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
22
28
|
export interface SandboxUpdateParams {
|
|
23
29
|
currentSnapshotId?: string | undefined;
|
|
30
|
+
keepLastSnapshots?: SandboxKeepLastSnapshotsConfig | null | undefined;
|
|
24
31
|
networkPolicy?: NetworkPolicy | undefined;
|
|
25
32
|
persistent?: boolean | undefined;
|
|
33
|
+
ports?: number[] | undefined;
|
|
26
34
|
resources?: { vcpus?: number | undefined } | undefined;
|
|
27
35
|
snapshotExpiration?: number | undefined;
|
|
28
36
|
tags?: Record<string, string> | undefined;
|
|
@@ -37,7 +45,6 @@ export interface SandboxCreateOptions {
|
|
|
37
45
|
signal?: AbortSignal | undefined;
|
|
38
46
|
tags?: Record<string, string> | undefined;
|
|
39
47
|
timeout?: number | undefined;
|
|
40
|
-
[key: string]: unknown;
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
export interface SandboxCommandResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"../../chunks/paths-
|
|
1
|
+
import{n as e}from"../../chunks/paths-CFoo44rU.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-ByUKG--q.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,7 +1,7 @@
|
|
|
1
1
|
import type * as VercelSandboxSdk from "#compiled/@vercel/sandbox/index.js";
|
|
2
2
|
import type { Sandbox as SdkSandbox } from "#compiled/@vercel/sandbox/index.js";
|
|
3
3
|
import type { SandboxBackend } from "#public/definitions/sandbox-backend.js";
|
|
4
|
-
import type { VercelSandbox, VercelSandboxSessionUseOptions } from "#public/sandbox/vercel-sandbox.js";
|
|
4
|
+
import type { VercelSandbox, VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions } from "#public/sandbox/vercel-sandbox.js";
|
|
5
5
|
type VercelSandboxModule = typeof VercelSandboxSdk;
|
|
6
6
|
/**
|
|
7
7
|
* User-controllable subset of `Sandbox.create` parameters.
|
|
@@ -18,5 +18,5 @@ export interface CreateVercelSandboxBackendInput {
|
|
|
18
18
|
/**
|
|
19
19
|
* Creates the Vercel-backed sandbox backend.
|
|
20
20
|
*/
|
|
21
|
-
export declare function createVercelSandboxBackend(input?: CreateVercelSandboxBackendInput): SandboxBackend<VercelSandbox, VercelSandboxSessionUseOptions>;
|
|
21
|
+
export declare function createVercelSandboxBackend(input?: CreateVercelSandboxBackendInput): SandboxBackend<VercelSandbox, VercelSandboxBootstrapUseOptions, VercelSandboxSessionUseOptions>;
|
|
22
22
|
export {};
|
|
@@ -119,7 +119,14 @@ async function ensureTemplate(input) {
|
|
|
119
119
|
await ensureSandboxWorkingDirectory(sandbox, input.createOptions);
|
|
120
120
|
const templateSession = buildSandboxSession(createVercelInternalSandboxSession(sandbox, input.templateKey));
|
|
121
121
|
if (input.bootstrap !== undefined) {
|
|
122
|
-
await input.bootstrap({
|
|
122
|
+
await input.bootstrap({
|
|
123
|
+
use: async (options) => {
|
|
124
|
+
if (options !== undefined) {
|
|
125
|
+
await sandbox.update(options);
|
|
126
|
+
}
|
|
127
|
+
return templateSession;
|
|
128
|
+
},
|
|
129
|
+
});
|
|
123
130
|
}
|
|
124
131
|
for (const file of input.seedFiles) {
|
|
125
132
|
if (typeof file.content === "string") {
|
|
@@ -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.
|
|
9
|
+
const BUNDLED_FALLBACK_PACKAGE_VERSION = "0.17.0";
|
|
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",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createCrossChannelReceiveFn } from "#channel/cross-channel-receive.js";
|
|
1
2
|
import { createSendFn } from "#channel/send.js";
|
|
2
3
|
import { createGetSessionFn } from "#channel/session.js";
|
|
3
4
|
import { resolveNitroChannelRuntimeBundle } from "#internal/nitro/routes/runtime-stack.js";
|
|
@@ -40,9 +41,11 @@ export async function dispatchChannelRequest(event, routeKey, config) {
|
|
|
40
41
|
const adapter = matchedChannel.adapter ?? { kind: "channel" };
|
|
41
42
|
const send = createSendFn(bundle.runtime, adapter, matchedChannel.name);
|
|
42
43
|
const getSession = createGetSessionFn(bundle.runtime);
|
|
44
|
+
const receive = createCrossChannelReceiveFn(bundle.runtime, bundle.channels);
|
|
43
45
|
const args = {
|
|
44
46
|
send,
|
|
45
47
|
getSession,
|
|
48
|
+
receive,
|
|
46
49
|
params,
|
|
47
50
|
waitUntil,
|
|
48
51
|
requestIp,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type AuthFn } from "#public/channels/auth.js";
|
|
2
|
-
import { type
|
|
2
|
+
import { type UploadPolicyInput } from "#public/channels/upload-policy.js";
|
|
3
3
|
import { type Channel } from "#public/definitions/defineChannel.js";
|
|
4
4
|
export interface AshChannelInput {
|
|
5
5
|
readonly auth: AuthFn<Request>;
|
|
6
|
-
readonly uploadPolicy?:
|
|
6
|
+
readonly uploadPolicy?: UploadPolicyInput;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Concrete return type of {@link ashChannel}. Named so consumers can
|
|
@@ -24,6 +24,9 @@ export declare function collectSlackFileParts(attachments: readonly SlackAttachm
|
|
|
24
24
|
* the bot in a follow-up. Any error during refresh is logged and treated
|
|
25
25
|
* as "no attachments" so the text portion of the mention still gets
|
|
26
26
|
* delivered.
|
|
27
|
+
*
|
|
28
|
+
* Skips the thread-history lookback when the policy disables uploads,
|
|
29
|
+
* since the refresh can't surface anything we'd deliver.
|
|
27
30
|
*/
|
|
28
31
|
export declare function collectInboundFileParts(input: {
|
|
29
32
|
readonly mention: Pick<SlackMessage, "attachments">;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLogger } from "#internal/logging.js";
|
|
2
2
|
import { resolveSlackBotToken, } from "#public/channels/slack/api.js";
|
|
3
|
-
import { evaluateFilePart, formatUploadPolicyViolation } from "#public/channels/upload-policy.js";
|
|
3
|
+
import { evaluateFilePart, formatUploadPolicyViolation, isUploadsDisabled, } from "#public/channels/upload-policy.js";
|
|
4
4
|
const log = createLogger("slack.attachments");
|
|
5
5
|
/**
|
|
6
6
|
* Emits one {@link FilePart} per supported attachment in the inbound
|
|
@@ -56,11 +56,16 @@ function toSlackFilePart(attachment, index) {
|
|
|
56
56
|
* the bot in a follow-up. Any error during refresh is logged and treated
|
|
57
57
|
* as "no attachments" so the text portion of the mention still gets
|
|
58
58
|
* delivered.
|
|
59
|
+
*
|
|
60
|
+
* Skips the thread-history lookback when the policy disables uploads,
|
|
61
|
+
* since the refresh can't surface anything we'd deliver.
|
|
59
62
|
*/
|
|
60
63
|
export async function collectInboundFileParts(input) {
|
|
61
64
|
const fromMention = collectSlackFileParts(input.mention.attachments, input.policy);
|
|
62
65
|
if (fromMention.length > 0)
|
|
63
66
|
return fromMention;
|
|
67
|
+
if (isUploadsDisabled(input.policy))
|
|
68
|
+
return [];
|
|
64
69
|
try {
|
|
65
70
|
await input.thread.refresh();
|
|
66
71
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { slackChannel, type SlackApiResponse, type SlackBotToken, type SlackChannel, type SlackChannelConfig, type SlackChannelCredentials, type SlackChannelEvents, type SlackChannelState, type SlackContext, type SlackEventContext, type SlackHandle, type SlackInboundResult, type SlackInboundResultOrPromise, type SlackInteractionAction, type SlackMentionResult, type SlackMentionResultOrPromise, type SlackReceiveArgs, type SlackThread, type SlackWebhookVerifier, } from "#public/channels/slack/slackChannel.js";
|
|
1
|
+
export { slackChannel, type SlackApiResponse, type SlackBotToken, type SlackChannel, type SlackChannelConfig, type SlackChannelCredentials, type SlackChannelEvents, type SlackChannelState, type SlackContext, type SlackEventContext, type SlackHandle, type SlackInboundResult, type SlackInboundResultOrPromise, type SlackInitialPost, type SlackInteractionAction, type SlackMentionResult, type SlackMentionResultOrPromise, type SlackReceiveArgs, type SlackThread, type SlackWebhookVerifier, } from "#public/channels/slack/slackChannel.js";
|
|
2
2
|
export type { SlackAttachment, SlackAuthor, SlackInboundContext, SlackMessage, } from "#public/channels/slack/inbound.js";
|
|
3
3
|
export type { SlackPostInput, SlackPostedMessage, SlackThreadMessage, SlackUploadFilesOptions, SlackUploadFilesResult, } from "#public/channels/slack/api.js";
|
|
4
4
|
export { cardToBlocks, cardToFallbackText, type BlockKitBlock, } from "#public/channels/slack/blocks.js";
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { TypedReceiveRoute } from "#channel/receive-args.js";
|
|
1
2
|
import type { SessionAuthContext } from "#channel/types.js";
|
|
3
|
+
import type { CardElement } from "#compiled/chat/index.js";
|
|
2
4
|
import type { HandleMessageStreamEvent } from "#protocol/message.js";
|
|
3
5
|
import { type SlackBotToken, type SlackHandle, type SlackThread } from "#public/channels/slack/api.js";
|
|
4
6
|
import { type SlackMessage } from "#public/channels/slack/inbound.js";
|
|
5
|
-
import { type
|
|
7
|
+
import { type UploadPolicyInput } from "#public/channels/upload-policy.js";
|
|
6
8
|
import { type SlackWebhookVerifier } from "#public/channels/slack/verify.js";
|
|
7
9
|
import { type Channel } from "#public/definitions/defineChannel.js";
|
|
8
10
|
type EventData<T extends HandleMessageStreamEvent["type"]> = Extract<HandleMessageStreamEvent, {
|
|
@@ -94,6 +96,23 @@ export interface SlackChannelCredentials {
|
|
|
94
96
|
export interface SlackReceiveArgs {
|
|
95
97
|
readonly channelId: string;
|
|
96
98
|
readonly threadTs?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Optional message posted into the Slack channel before the agent
|
|
101
|
+
* runs. The post becomes the thread root and the agent's first turn
|
|
102
|
+
* lands threaded under it. Useful for cross-channel handoffs where
|
|
103
|
+
* the caller wants a visible "this is why we're here" anchor before
|
|
104
|
+
* the model speaks. Mutually exclusive with {@link threadTs}.
|
|
105
|
+
*/
|
|
106
|
+
readonly initialPost?: SlackInitialPost;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Pre-agent post issued by `slackChannel().receive` when the caller
|
|
110
|
+
* provides `args.initialPost`. The shape mirrors `ctx.thread.post`'s
|
|
111
|
+
* card variant so the same `Card({...})` construction can be reused.
|
|
112
|
+
*/
|
|
113
|
+
export interface SlackInitialPost {
|
|
114
|
+
readonly card: CardElement;
|
|
115
|
+
readonly fallbackText?: string;
|
|
97
116
|
}
|
|
98
117
|
export interface SlackInteractionAction {
|
|
99
118
|
readonly actionId: string;
|
|
@@ -179,9 +198,10 @@ export interface SlackChannelConfig {
|
|
|
179
198
|
* Inbound upload policy applied to file attachments before they
|
|
180
199
|
* reach the harness. Violating attachments are dropped with a
|
|
181
200
|
* warning so the text portion of the mention still gets delivered.
|
|
182
|
-
*
|
|
201
|
+
* Pass `"disabled"` to reject every attachment. Defaults to the
|
|
202
|
+
* framework's 25 MB cap with unrestricted media types.
|
|
183
203
|
*/
|
|
184
|
-
readonly uploadPolicy?:
|
|
204
|
+
readonly uploadPolicy?: UploadPolicyInput;
|
|
185
205
|
/**
|
|
186
206
|
* Invoked the moment a Slack `app_mention` event arrives (and only
|
|
187
207
|
* for `app_mention` events — other Slack event types are ignored).
|
|
@@ -259,7 +279,7 @@ export interface SlackChannelConfig {
|
|
|
259
279
|
* default-export a `slackChannel(...)` call under `declaration: true`
|
|
260
280
|
* without TypeScript falling back to an internal path for `Channel`.
|
|
261
281
|
*/
|
|
262
|
-
export interface SlackChannel extends Channel<SlackChannelState> {
|
|
282
|
+
export interface SlackChannel extends Channel<SlackChannelState>, TypedReceiveRoute<SlackReceiveArgs> {
|
|
263
283
|
}
|
|
264
284
|
/**
|
|
265
285
|
* Slack channel factory. Wires up the Slack webhook route, mention
|
|
@@ -4,7 +4,7 @@ import { buildSlackTurnMessage, collectInboundFileParts, createSlackFetchFile, }
|
|
|
4
4
|
import { defaultEvents, defaultInputRequestedHandler, defaultOnAppMention, defaultOnDirectMessage, } from "#public/channels/slack/defaults.js";
|
|
5
5
|
import { parseAppMentionEvent, parseDirectMessageEvent, prependSlackContext, } from "#public/channels/slack/inbound.js";
|
|
6
6
|
import { handleInteractionPost } from "#public/channels/slack/interactions.js";
|
|
7
|
-
import { mergeUploadPolicy } from "#public/channels/upload-policy.js";
|
|
7
|
+
import { mergeUploadPolicy, } from "#public/channels/upload-policy.js";
|
|
8
8
|
import { verifySlackRequest } from "#public/channels/slack/verify.js";
|
|
9
9
|
import { defineChannel, POST, } from "#public/definitions/defineChannel.js";
|
|
10
10
|
const log = createLogger("slack.channel");
|
|
@@ -72,11 +72,33 @@ export function slackChannel(config = {}) {
|
|
|
72
72
|
}),
|
|
73
73
|
],
|
|
74
74
|
async receive(input, { send }) {
|
|
75
|
-
const
|
|
76
|
-
|
|
75
|
+
const receiveArgs = input.args;
|
|
76
|
+
const channelId = receiveArgs.channelId;
|
|
77
|
+
if (!channelId || typeof channelId !== "string") {
|
|
77
78
|
throw new Error("slackChannel().receive requires args.channelId.");
|
|
78
79
|
}
|
|
79
|
-
const
|
|
80
|
+
const requestedThreadTs = typeof receiveArgs.threadTs === "string" ? receiveArgs.threadTs : "";
|
|
81
|
+
const initialPost = receiveArgs.initialPost;
|
|
82
|
+
if (initialPost && requestedThreadTs.length > 0) {
|
|
83
|
+
throw new Error("slackChannel().receive: `threadTs` and `initialPost` are mutually exclusive.");
|
|
84
|
+
}
|
|
85
|
+
let threadTs = requestedThreadTs;
|
|
86
|
+
if (initialPost) {
|
|
87
|
+
const { thread } = buildSlackBinding({
|
|
88
|
+
botToken: config.credentials?.botToken,
|
|
89
|
+
channelId,
|
|
90
|
+
threadTs: "",
|
|
91
|
+
teamId: undefined,
|
|
92
|
+
});
|
|
93
|
+
const postInput = {
|
|
94
|
+
card: initialPost.card,
|
|
95
|
+
};
|
|
96
|
+
if (initialPost.fallbackText !== undefined) {
|
|
97
|
+
postInput.fallbackText = initialPost.fallbackText;
|
|
98
|
+
}
|
|
99
|
+
const posted = await thread.post(postInput);
|
|
100
|
+
threadTs = posted.id;
|
|
101
|
+
}
|
|
80
102
|
return send(input.message, {
|
|
81
103
|
auth: input.auth,
|
|
82
104
|
continuationToken: encodeSlackContinuationToken(channelId, threadTs),
|