experimental-ash 0.40.0 → 0.41.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/docs/public/tools.md +165 -0
  3. package/dist/src/compiled/.vendor-stamp.json +1 -1
  4. package/dist/src/compiled/@workflow/core/index.js +1 -1
  5. package/dist/src/compiled/@workflow/core/runtime.js +1 -1
  6. package/dist/src/compiled/_chunks/workflow/{resume-hook-D6dFbxMV.js → resume-hook-B2kqAsX6.js} +1 -1
  7. package/dist/src/compiler/manifest.d.ts +16 -2
  8. package/dist/src/compiler/manifest.js +1 -1
  9. package/dist/src/compiler/module-map.js +1 -1
  10. package/dist/src/compiler/normalize-agent-config.js +1 -1
  11. package/dist/src/compiler/normalize-manifest.js +1 -1
  12. package/dist/src/compiler/normalize-tool.d.ts +7 -3
  13. package/dist/src/compiler/normalize-tool.js +1 -1
  14. package/dist/src/context/dynamic-tool-lifecycle.d.ts +35 -0
  15. package/dist/src/context/dynamic-tool-lifecycle.js +1 -0
  16. package/dist/src/context/hook-lifecycle.js +1 -1
  17. package/dist/src/context/keys.d.ts +37 -0
  18. package/dist/src/context/keys.js +1 -1
  19. package/dist/src/context/providers/sandbox.js +1 -1
  20. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  21. package/dist/src/execution/node-step.js +1 -1
  22. package/dist/src/execution/workflow-steps.js +1 -1
  23. package/dist/src/harness/attachment-staging.js +1 -1
  24. package/dist/src/harness/code-mode.d.ts +1 -1
  25. package/dist/src/harness/code-mode.js +1 -1
  26. package/dist/src/harness/tool-loop.js +1 -1
  27. package/dist/src/harness/types.d.ts +7 -0
  28. package/dist/src/internal/application/package.js +1 -1
  29. package/dist/src/internal/authored-definition/core.js +1 -1
  30. package/dist/src/internal/authored-definition/schema-backed.d.ts +9 -3
  31. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  32. package/dist/src/internal/authored-module.d.ts +4 -0
  33. package/dist/src/internal/authored-module.js +1 -1
  34. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  35. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +39 -0
  36. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +4 -0
  37. package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
  38. package/dist/src/public/definitions/agent.d.ts +1 -1
  39. package/dist/src/public/definitions/defineChannel.js +1 -1
  40. package/dist/src/public/definitions/tool.d.ts +67 -0
  41. package/dist/src/public/definitions/tool.js +1 -1
  42. package/dist/src/public/index.d.ts +1 -1
  43. package/dist/src/public/tools/index.d.ts +2 -1
  44. package/dist/src/public/tools/index.js +1 -1
  45. package/dist/src/runtime/framework-tools/connection-search.js +1 -1
  46. package/dist/src/runtime/framework-tools/connection-tools.js +1 -1
  47. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  48. package/dist/src/runtime/resolve-agent.js +1 -1
  49. package/dist/src/runtime/resolve-dynamic-tool.d.ts +12 -0
  50. package/dist/src/runtime/resolve-dynamic-tool.js +1 -0
  51. package/dist/src/runtime/types.d.ts +12 -0
  52. package/dist/src/shared/agent-definition.d.ts +25 -0
  53. package/dist/src/shared/code-mode.d.ts +14 -1
  54. package/dist/src/shared/code-mode.js +1 -1
  55. package/dist/src/shared/dynamic-tool-definition.d.ts +132 -0
  56. package/dist/src/shared/dynamic-tool-definition.js +1 -0
  57. package/package.json +1 -1
@@ -1 +1 @@
1
- import{isObject}from"#shared/guards.js";import{loadContext}from"#context/container.js";import"#runtime/framework-tools/connection-search.js";import{jsonSchema}from"ai";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,toCodeModeConnectionAuthArgs}from"#runtime/framework-tools/code-mode-connection-auth.js";import{loadCodeModeModule}from"#shared/code-mode.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";function qualifiedConnectionToolName(e,t){return`${e}__${t}`}async function resolveConnectionToolsFromState(t,n,r){let i={};for(let[a,o]of Object.entries(n.byConnection)){let n=r.authMode===`code-mode`&&r.codeModeMetadataOnlyConnectionNames?.has(a)===!0,s=n?void 0:await t.getClient(a).getTools(),c=t.getConnectionApproval(a);for(let l of o){let o=qualifiedConnectionToolName(a,l.name);if(r.existingToolNames?.has(o))continue;let u=s?.[l.name]??(n?createMetadataOnlyTool(l,o):void 0);if(u===void 0)continue;let d=!n&&c!==void 0?async t=>c({approvedTools:r.approvedTools??new Set,toolInput:isObject(t)?t:void 0,toolName:o}):void 0,f=t.getConnections().find(e=>e.connectionName===a),p=u.execute,m=r.authMode===`code-mode`?wrapCodeModeConnectionToolExecute({connectionDefinition:f,connectionName:a,originalExecute:p,toolName:l.name}):wrapConnectionToolExecute({connectionDefinition:f,connectionName:a,originalExecute:p,toolName:l.name});i[o]={...u,execute:m,needsApproval:d}}}return i}function createMetadataOnlyTool(e,t){return{description:e.description,execute:async()=>{throw Error(`Connection tool "${t}" cannot execute without authorization.`)},inputSchema:jsonSchema(e.inputSchema)}}function wrapCodeModeConnectionToolExecute(e){let{connectionDefinition:n,connectionName:i,originalExecute:a,toolName:m}=e;if(a===void 0)return;let h=n?.authorization&&supportsInteractiveAuthorization(n.authorization)?n.authorization:void 0,g=n?.url??``;return async(e,n)=>{if(h){let e=getAuthorizationResult(i);if(e){let n=loadContext(),r=resolveConnectionPrincipal(i,h),a=await h.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:g},principal:r,request:e.callback,state:e.state});writeCachedToken(n,i,principalKey(r),a)}}try{return await a(e,n)}catch(t){if(!isConnectionAuthorizationRequiredError(t)||!h)throw t;let{requestCodeModeInterrupt:n}=await loadCodeModeModule();n({args:toCodeModeConnectionAuthArgs(e),connectionName:i,kind:CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,toolName:m})}}}function wrapConnectionToolExecute(e){let{connectionDefinition:n,connectionName:o,originalExecute:s}=e;if(s===void 0)return;let c=n?.authorization&&supportsInteractiveAuthorization(n.authorization)?n.authorization:void 0,m=n?.url??``;return async(e,n)=>{if(c){let e=getAuthorizationResult(o);if(e){let n=loadContext(),r=resolveConnectionPrincipal(o,c),i=await c.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:m},principal:r,request:e.callback,state:e.state});writeCachedToken(n,o,principalKey(r),i)}}try{return await s(e,n)}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!c)throw e;let t=getHookUrl(o);if(!t)throw e;let n=resolveConnectionPrincipal(o,c),{challenge:r,state:s}=await c.startAuthorization({callbackUrl:t,connection:{url:m},principal:n});return requestAuthorization([{name:o,challenge:r,hookUrl:t,state:s}])}}}export{qualifiedConnectionToolName,resolveConnectionToolsFromState,wrapCodeModeConnectionToolExecute,wrapConnectionToolExecute};
1
+ import{isObject}from"#shared/guards.js";import{loadContext}from"#context/container.js";import{jsonSchema}from"ai";import"#runtime/framework-tools/connection-search.js";import{loadCodeModeModule}from"#shared/code-mode.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,toCodeModeConnectionAuthArgs}from"#runtime/framework-tools/code-mode-connection-auth.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";function qualifiedConnectionToolName(e,t){return`${e}__${t}`}async function resolveConnectionToolsFromState(t,n,r){let i={};for(let[a,o]of Object.entries(n.byConnection)){let n=r.authMode===`code-mode`&&r.codeModeMetadataOnlyConnectionNames?.has(a)===!0,s=n?void 0:await t.getClient(a).getTools(),c=t.getConnectionApproval(a);for(let l of o){let o=qualifiedConnectionToolName(a,l.name);if(r.existingToolNames?.has(o))continue;let u=s?.[l.name]??(n?createMetadataOnlyTool(l,o):void 0);if(u===void 0)continue;let d=!n&&c!==void 0?async t=>c({approvedTools:r.approvedTools??new Set,toolInput:isObject(t)?t:void 0,toolName:o}):void 0,f=t.getConnections().find(e=>e.connectionName===a),p=u.execute,m=r.authMode===`code-mode`?wrapCodeModeConnectionToolExecute({connectionDefinition:f,connectionName:a,originalExecute:p,toolName:l.name}):wrapConnectionToolExecute({connectionDefinition:f,connectionName:a,originalExecute:p,toolName:l.name});i[o]={...u,execute:m,needsApproval:d}}}return i}function createMetadataOnlyTool(e,t){return{description:e.description,execute:async()=>{throw Error(`Connection tool "${t}" cannot execute without authorization.`)},inputSchema:jsonSchema(e.inputSchema)}}function wrapCodeModeConnectionToolExecute(e){let{connectionDefinition:n,connectionName:a,originalExecute:o,toolName:m}=e;if(o===void 0)return;let h=n?.authorization&&supportsInteractiveAuthorization(n.authorization)?n.authorization:void 0,g=n?.url??``;return async(e,n)=>{if(h){let e=getAuthorizationResult(a);if(e){let n=loadContext(),r=resolveConnectionPrincipal(a,h),i=await h.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:g},principal:r,request:e.callback,state:e.state});writeCachedToken(n,a,principalKey(r),i)}}try{return await o(e,n)}catch(t){if(!isConnectionAuthorizationRequiredError(t)||!h)throw t;let{requestCodeModeInterrupt:n}=await loadCodeModeModule();n({args:toCodeModeConnectionAuthArgs(e),connectionName:a,kind:CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,toolName:m})}}}function wrapConnectionToolExecute(e){let{connectionDefinition:n,connectionName:r,originalExecute:s}=e;if(s===void 0)return;let c=n?.authorization&&supportsInteractiveAuthorization(n.authorization)?n.authorization:void 0,m=n?.url??``;return async(e,n)=>{if(c){let e=getAuthorizationResult(r);if(e){let n=loadContext(),i=resolveConnectionPrincipal(r,c),a=await c.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:m},principal:i,request:e.callback,state:e.state});writeCachedToken(n,r,principalKey(i),a)}}try{return await s(e,n)}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!c)throw e;let t=getHookUrl(r);if(!t)throw e;let n=resolveConnectionPrincipal(r,c),{challenge:i,state:s}=await c.startAuthorization({callbackUrl:t,connection:{url:m},principal:n});return requestAuthorization([{name:r,challenge:i,hookUrl:t,state:s}])}}}export{qualifiedConnectionToolName,resolveConnectionToolsFromState,wrapCodeModeConnectionToolExecute,wrapConnectionToolExecute};
@@ -1 +1 @@
1
- import{expectObjectRecord}from"#internal/authored-module.js";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{CONNECTION_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/connection-search.js";import{createRuntimeToolRegistry}from"#runtime/tools/registry.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{CODE_MODE_TOOL_NAME}from"#shared/code-mode.js";import{getAllFrameworkChannelNames,getFrameworkChannelDefinitions}from"#runtime/framework-channels/index.js";import{resolveAgent}from"#runtime/resolve-agent.js";import{loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createResolvedRuntimeTurnAgent}from"#runtime/agent/bootstrap.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{getAllFrameworkToolNames,getFrameworkToolDefinitions}from"#runtime/framework-tools/index.js";import{createRuntimeHookRegistry}from"#runtime/hooks/registry.js";import{createRuntimeSandboxRegistry}from"#runtime/sandbox/registry.js";import{createRuntimeSubagentRegistry}from"#runtime/subagents/registry.js";var ResolveRuntimeAgentGraphError=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 resolveRuntimeAgentGraph(e){let n=new Map,r=createChildNodeIdsByParentNodeId(e.manifest),i=new Map(e.manifest.subagents.map(e=>[e.nodeId,e]));return{nodesByNodeId:n,root:await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:r,manifest:e.manifest,moduleMap:e.moduleMap,nodeId:ROOT_COMPILED_AGENT_NODE_ID,nodesByNodeId:n,subagentNodesById:i})}}async function resolveRuntimeAgentNode(e){let t=toRuntimeNodeId(e.nodeId);if(e.nodesByNodeId.has(t))throw new ResolveRuntimeAgentGraphError(`Found multiple runtime agent nodes for node id "${t}".`,{nodeId:t,sourceId:e.sourceId});let n=await resolveAgent({manifest:e.manifest,moduleMap:e.moduleMap,nodeId:e.nodeId}),i=n.connections.length>0,a=getFrameworkToolDefinitions({hasConnections:i}),o=i?enrichConnectionSearchDescription(a,n.connections):a,s=new Set(o.map(e=>e.name)),c=getAllFrameworkToolNames(),l=new Set(n.tools.map(e=>e.name));for(let r of n.disabledFrameworkTools)if(!c.has(r))throw new ResolveRuntimeAgentGraphError(`agent/tools/${r}.ts exports disableTool() but "${r}" is not a framework tool. Rename the file to one of: ${[...c].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let u=new Set(n.disabledFrameworkTools),d=await createRuntimeToolRegistry({tools:[...o.filter(e=>!l.has(e.name)&&!u.has(e.name)),...n.tools]},{reservedToolNames:[CODE_MODE_TOOL_NAME,...s.has(LOAD_SKILL_TOOL_NAME)||l.has(LOAD_SKILL_TOOL_NAME)?[]:[LOAD_SKILL_TOOL_NAME]]}),f=new Set(n.channels.map(e=>e.name)),p=getAllFrameworkChannelNames();for(let r of n.disabledFrameworkChannels)if(!p.has(r))throw new ResolveRuntimeAgentGraphError(`agent/channels/${r}.ts exports disableRoute() but "${r}" is not a framework channel. Rename the file to one of: ${[...p].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let m=new Set(n.disabledFrameworkChannels),h=[...getFrameworkChannelDefinitions().filter(e=>!f.has(e.name)&&!m.has(e.name)),...n.channels],g=createRuntimeSandboxRegistry({authoredSandbox:n.sandbox,workspaceResourceRoot:n.workspaceResourceRoot}),_=createRuntimeSubagentRegistry({reservedToolNames:[LOAD_SKILL_TOOL_NAME,...d.preparedTools.map(e=>e.name)],subagents:await resolveRuntimeSubagents({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.manifest,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,parentNodeId:e.nodeId,subagentNodesById:e.subagentNodesById})}),v={agent:n,channels:h,hookRegistry:createRuntimeHookRegistry(n.hooks),nodeId:t,sandboxRegistry:g,sourceId:e.sourceId,subagentRegistry:_,toolRegistry:d,turnAgent:createResolvedRuntimeTurnAgent({agent:n,nodeId:t,tools:[...d.preparedTools,..._.preparedTools]})};return e.nodesByNodeId.set(t,v),v}async function resolveRuntimeSubagents(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 ResolveRuntimeAgentGraphError(`Missing compiled subagent node "${r}" while resolving runtime subagents.`,{nodeId:toRuntimeNodeId(e.parentNodeId),sourceId:r});t.push(await resolveRuntimeSubagent({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,sourceRef:n,subagentNodesById:e.subagentNodesById}))}for(let n of e.manifest.remoteAgents)t.push(await resolveRuntimeRemoteAgent({moduleMap:e.moduleMap,nodeScopeId:e.parentNodeId,sourceRef:n}));return t}async function resolveRuntimeSubagent(e){let t={description:e.sourceRef.description,kind:`subagent`,logicalPath:e.sourceRef.logicalPath,name:e.sourceRef.name,nodeId:toRuntimeNodeId(e.sourceRef.nodeId),sourceId:e.sourceRef.sourceId,sourceKind:`module`};return await resolveRuntimeAgentNode({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}async function resolveRuntimeRemoteAgent(t){let n=expectObjectRecord(await loadResolvedModuleExport({definition:t.sourceRef,kindLabel:`remote agent`,moduleMap:t.moduleMap,nodeId:t.nodeScopeId}),`Expected remote agent source "${t.sourceRef.logicalPath}" to export an object.`),r={description:t.sourceRef.description,kind:`remote`,logicalPath:t.sourceRef.logicalPath,name:t.sourceRef.name,nodeId:toRuntimeNodeId(t.sourceRef.nodeId),path:t.sourceRef.path,sourceId:t.sourceRef.sourceId,sourceKind:`module`,url:t.sourceRef.url};typeof n.auth==`function`&&(r.auth=n.auth);let i=resolveRemoteAgentHeaders(n.headers);return i!==void 0&&(r.headers=i),r}function resolveRemoteAgentHeaders(e){if(e===void 0)return;if(typeof e==`function`)return e;if(typeof e!=`object`||!e||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}function createChildNodeIdsByParentNodeId(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 toRuntimeNodeId(e){return e===ROOT_COMPILED_AGENT_NODE_ID?ROOT_RUNTIME_AGENT_NODE_ID:e}function getConnectionSearchName(){return CONNECTION_SEARCH_TOOL_DEFINITION.name}function enrichConnectionSearchDescription(e,t){let n=t.map(e=>e.connectionName).join(`, `);return e.map(e=>e.name===getConnectionSearchName()?{...e,description:`${e.description} Available connections: ${n}.`}:e)}export{resolveRuntimeAgentGraph};
1
+ import{expectObjectRecord}from"#internal/authored-module.js";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{CONNECTION_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/connection-search.js";import{CODE_MODE_TOOL_NAME}from"#shared/code-mode.js";import{createRuntimeToolRegistry}from"#runtime/tools/registry.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{getAllFrameworkChannelNames,getFrameworkChannelDefinitions}from"#runtime/framework-channels/index.js";import{resolveAgent}from"#runtime/resolve-agent.js";import{loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createResolvedRuntimeTurnAgent}from"#runtime/agent/bootstrap.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{getAllFrameworkToolNames,getFrameworkToolDefinitions}from"#runtime/framework-tools/index.js";import{createRuntimeHookRegistry}from"#runtime/hooks/registry.js";import{createRuntimeSandboxRegistry}from"#runtime/sandbox/registry.js";import{createRuntimeSubagentRegistry}from"#runtime/subagents/registry.js";var ResolveRuntimeAgentGraphError=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 resolveRuntimeAgentGraph(e){let n=new Map,r=createChildNodeIdsByParentNodeId(e.manifest),i=new Map(e.manifest.subagents.map(e=>[e.nodeId,e]));return{nodesByNodeId:n,root:await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:r,manifest:e.manifest,moduleMap:e.moduleMap,nodeId:ROOT_COMPILED_AGENT_NODE_ID,nodesByNodeId:n,subagentNodesById:i})}}async function resolveRuntimeAgentNode(e){let t=toRuntimeNodeId(e.nodeId);if(e.nodesByNodeId.has(t))throw new ResolveRuntimeAgentGraphError(`Found multiple runtime agent nodes for node id "${t}".`,{nodeId:t,sourceId:e.sourceId});let n=await resolveAgent({manifest:e.manifest,moduleMap:e.moduleMap,nodeId:e.nodeId}),a=n.connections.length>0,o=getFrameworkToolDefinitions({hasConnections:a}),s=a?enrichConnectionSearchDescription(o,n.connections):o,c=new Set(s.map(e=>e.name)),l=getAllFrameworkToolNames(),u=new Set(n.tools.map(e=>e.name));for(let r of n.disabledFrameworkTools)if(!l.has(r))throw new ResolveRuntimeAgentGraphError(`agent/tools/${r}.ts exports disableTool() but "${r}" is not a framework tool. Rename the file to one of: ${[...l].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let d=new Set(n.disabledFrameworkTools),f=await createRuntimeToolRegistry({tools:[...s.filter(e=>!u.has(e.name)&&!d.has(e.name)),...n.tools]},{reservedToolNames:[CODE_MODE_TOOL_NAME,...c.has(LOAD_SKILL_TOOL_NAME)||u.has(LOAD_SKILL_TOOL_NAME)?[]:[LOAD_SKILL_TOOL_NAME]]}),p=new Set(n.channels.map(e=>e.name)),m=getAllFrameworkChannelNames();for(let r of n.disabledFrameworkChannels)if(!m.has(r))throw new ResolveRuntimeAgentGraphError(`agent/channels/${r}.ts exports disableRoute() but "${r}" is not a framework channel. Rename the file to one of: ${[...m].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let h=new Set(n.disabledFrameworkChannels),g=[...getFrameworkChannelDefinitions().filter(e=>!p.has(e.name)&&!h.has(e.name)),...n.channels],_=createRuntimeSandboxRegistry({authoredSandbox:n.sandbox,workspaceResourceRoot:n.workspaceResourceRoot}),v=createRuntimeSubagentRegistry({reservedToolNames:[LOAD_SKILL_TOOL_NAME,...f.preparedTools.map(e=>e.name)],subagents:await resolveRuntimeSubagents({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.manifest,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,parentNodeId:e.nodeId,subagentNodesById:e.subagentNodesById})}),y={agent:n,channels:g,hookRegistry:createRuntimeHookRegistry(n.hooks),nodeId:t,sandboxRegistry:_,sourceId:e.sourceId,subagentRegistry:v,toolRegistry:f,turnAgent:createResolvedRuntimeTurnAgent({agent:n,nodeId:t,tools:[...f.preparedTools,...v.preparedTools]})};return e.nodesByNodeId.set(t,y),y}async function resolveRuntimeSubagents(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 ResolveRuntimeAgentGraphError(`Missing compiled subagent node "${r}" while resolving runtime subagents.`,{nodeId:toRuntimeNodeId(e.parentNodeId),sourceId:r});t.push(await resolveRuntimeSubagent({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,sourceRef:n,subagentNodesById:e.subagentNodesById}))}for(let n of e.manifest.remoteAgents)t.push(await resolveRuntimeRemoteAgent({moduleMap:e.moduleMap,nodeScopeId:e.parentNodeId,sourceRef:n}));return t}async function resolveRuntimeSubagent(e){let t={description:e.sourceRef.description,kind:`subagent`,logicalPath:e.sourceRef.logicalPath,name:e.sourceRef.name,nodeId:toRuntimeNodeId(e.sourceRef.nodeId),sourceId:e.sourceRef.sourceId,sourceKind:`module`};return await resolveRuntimeAgentNode({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}async function resolveRuntimeRemoteAgent(t){let n=expectObjectRecord(await loadResolvedModuleExport({definition:t.sourceRef,kindLabel:`remote agent`,moduleMap:t.moduleMap,nodeId:t.nodeScopeId}),`Expected remote agent source "${t.sourceRef.logicalPath}" to export an object.`),r={description:t.sourceRef.description,kind:`remote`,logicalPath:t.sourceRef.logicalPath,name:t.sourceRef.name,nodeId:toRuntimeNodeId(t.sourceRef.nodeId),path:t.sourceRef.path,sourceId:t.sourceRef.sourceId,sourceKind:`module`,url:t.sourceRef.url};typeof n.auth==`function`&&(r.auth=n.auth);let i=resolveRemoteAgentHeaders(n.headers);return i!==void 0&&(r.headers=i),r}function resolveRemoteAgentHeaders(e){if(e===void 0)return;if(typeof e==`function`)return e;if(typeof e!=`object`||!e||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}function createChildNodeIdsByParentNodeId(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 toRuntimeNodeId(e){return e===ROOT_COMPILED_AGENT_NODE_ID?ROOT_RUNTIME_AGENT_NODE_ID:e}function getConnectionSearchName(){return CONNECTION_SEARCH_TOOL_DEFINITION.name}function enrichConnectionSearchDescription(e,t){let n=t.map(e=>e.connectionName).join(`, `);return e.map(e=>e.name===getConnectionSearchName()?{...e,description:`${e.description} Available connections: ${n}.`}:e)}export{resolveRuntimeAgentGraph};
@@ -1 +1 @@
1
- import{ResolveAgentError,createResolvedModuleSourceRef}from"#runtime/resolve-helpers.js";import{resolveChannelDefinition}from"#runtime/resolve-channel.js";import{resolveConnectionDefinition}from"#runtime/resolve-connection.js";import{resolveHookDefinition}from"#runtime/resolve-hook.js";import{resolveSandboxDefinition}from"#runtime/resolve-sandbox.js";import{resolveToolDefinition}from"#runtime/resolve-tool.js";async function resolveAgent(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),r=[],i=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){i.push(t.name);continue}r.push(await resolveChannelDefinition(t,e.moduleMap,e.nodeId))}let a=await Promise.all(e.manifest.tools.map(t=>resolveToolDefinition(t,e.moduleMap,e.nodeId))),o=await Promise.all(e.manifest.hooks.map(t=>resolveHookDefinition(t,e.moduleMap,e.nodeId))),s=await Promise.all(e.manifest.connections.map(t=>resolveConnectionDefinition(t,e.moduleMap,e.nodeId))),c=e.manifest.sandbox===null?null:await resolveSandboxDefinition(e.manifest.sandbox,e.moduleMap,e.nodeId),l=createResolvedInstructions(e.manifest.instructions),u=e.manifest.workspaceResourceRoot,d={channels:r,config:createResolvedAgentConfig(e.manifest),connections:s,disabledFrameworkChannels:i,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],hooks:o,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:c,workspaceResourceRoot:u,skills:t,tools:a,workspaceSpec:{rootEntries:[...u.rootEntries]}};return l===void 0?d:{...d,instructions:l}}function createResolvedInstructions(e){if(e!==void 0)return{name:e.name,logicalPath:e.logicalPath,markdown:e.markdown,sourceId:e.sourceId,sourceKind:e.sourceKind}}function createResolvedAgentConfig(e){let n={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 t={};e.config.compaction.model!==void 0&&(t.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&&(t.thresholdPercent=e.config.compaction.thresholdPercent),n.compaction=t}return e.config.source!==void 0&&(n.source=createResolvedModuleSourceRef(e.config.source)),n}export{ResolveAgentError,resolveAgent};
1
+ import{ResolveAgentError,createResolvedModuleSourceRef}from"#runtime/resolve-helpers.js";import{resolveChannelDefinition}from"#runtime/resolve-channel.js";import{resolveConnectionDefinition}from"#runtime/resolve-connection.js";import{resolveHookDefinition}from"#runtime/resolve-hook.js";import{resolveSandboxDefinition}from"#runtime/resolve-sandbox.js";import{resolveDynamicToolDefinition}from"#runtime/resolve-dynamic-tool.js";import{resolveToolDefinition}from"#runtime/resolve-tool.js";async function resolveAgent(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),r=[],i=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){i.push(t.name);continue}r.push(await resolveChannelDefinition(t,e.moduleMap,e.nodeId))}let a=await Promise.all(e.manifest.tools.map(t=>resolveToolDefinition(t,e.moduleMap,e.nodeId))),o=await Promise.all(e.manifest.dynamicTools.map(t=>resolveDynamicToolDefinition(t,e.moduleMap,e.nodeId))),s=await Promise.all(e.manifest.hooks.map(t=>resolveHookDefinition(t,e.moduleMap,e.nodeId))),c=await Promise.all(e.manifest.connections.map(t=>resolveConnectionDefinition(t,e.moduleMap,e.nodeId))),l=e.manifest.sandbox===null?null:await resolveSandboxDefinition(e.manifest.sandbox,e.moduleMap,e.nodeId),u=createResolvedInstructions(e.manifest.instructions),d=e.manifest.workspaceResourceRoot,f={channels:r,config:createResolvedAgentConfig(e.manifest),connections:c,disabledFrameworkChannels:i,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],dynamicToolResolvers:o,hooks:s,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:l,workspaceResourceRoot:d,skills:t,tools:a,workspaceSpec:{rootEntries:[...d.rootEntries]}};return u===void 0?f:{...f,instructions:u}}function createResolvedInstructions(e){if(e!==void 0)return{name:e.name,logicalPath:e.logicalPath,markdown:e.markdown,sourceId:e.sourceId,sourceKind:e.sourceKind}}function createResolvedAgentConfig(e){let n={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 t={};e.config.compaction.model!==void 0&&(t.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&&(t.thresholdPercent=e.config.compaction.thresholdPercent),n.compaction=t}return e.config.experimental!==void 0&&(n.experimental={codeMode:e.config.experimental.codeMode}),e.config.source!==void 0&&(n.source=createResolvedModuleSourceRef(e.config.source)),n}export{ResolveAgentError,resolveAgent};
@@ -0,0 +1,12 @@
1
+ import type { CompiledDynamicToolDefinition } from "#compiler/manifest.js";
2
+ import type { CompiledModuleMap } from "#compiler/module-map.js";
3
+ import type { ResolvedDynamicToolResolver } from "#runtime/types.js";
4
+ /**
5
+ * Resolves one compiled dynamic tool entry into a runtime-owned resolver
6
+ * with live event handler functions reattached from the authored module.
7
+ *
8
+ * The resolver's `events` map is validated: each declared event name must
9
+ * map to a function. The handlers are not called here — they run later at
10
+ * the lifecycle point indicated by each event name.
11
+ */
12
+ export declare function resolveDynamicToolDefinition(definition: CompiledDynamicToolDefinition, moduleMap: CompiledModuleMap, nodeId: string | undefined): Promise<ResolvedDynamicToolResolver>;
@@ -0,0 +1 @@
1
+ import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{registerDefinitionSource,stampDefinitionKey}from"#public/tool-result-narrowing.js";async function resolveDynamicToolDefinition(i,a,o){try{let n=expectObjectRecord(await loadResolvedModuleExport({definition:i,kindLabel:`dynamic-tool`,moduleMap:a,nodeId:o}),describe(i,`to return an object`)),r=expectObjectRecord(n.events,describe(i,`to provide an events object`)),s={};for(let t of i.eventNames)s[t]=expectFunction(r[t],describe(i,`to provide a handler for event "${t}"`));let c=`dynamic-tool-source:${i.sourceId}`;return stampDefinitionKey(n,c),registerDefinitionSource(c,{kind:`tool`,logicalPath:i.logicalPath,name:i.slug}),{eventNames:[...i.eventNames],events:s,exportName:i.exportName,identity:i.identity,logicalPath:i.logicalPath,slug:i.slug,sourceId:i.sourceId,sourceKind:`module`}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to resolve dynamic tool from "${i.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:i.logicalPath,sourceId:i.sourceId})}}function describe(e,t){return`Expected the dynamic tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}export{resolveDynamicToolDefinition};
@@ -254,6 +254,17 @@ interface ResolvedAgentMetadata {
254
254
  readonly appRoot: string;
255
255
  readonly diagnosticsSummary: DiscoverDiagnosticsSummary;
256
256
  }
257
+ /**
258
+ * Runtime resolver for dynamic tools declared via `defineTools({ events })`
259
+ * or `defineTool({ events })`. Carries the live event handler functions
260
+ * loaded from the compiled module.
261
+ */
262
+ export interface ResolvedDynamicToolResolver extends Readonly<ModuleSourceRef> {
263
+ readonly slug: string;
264
+ readonly identity: "single" | "multi";
265
+ readonly eventNames: readonly string[];
266
+ readonly events: Readonly<Record<string, (event: unknown, ctx: unknown) => unknown | Promise<unknown>>>;
267
+ }
257
268
  /**
258
269
  * Runtime-owned authored agent model resolved from compiler artifacts.
259
270
  */
@@ -275,6 +286,7 @@ export interface ResolvedAgent {
275
286
  * filter the framework default tool set.
276
287
  */
277
288
  readonly disabledFrameworkTools: readonly string[];
289
+ readonly dynamicToolResolvers: readonly ResolvedDynamicToolResolver[];
278
290
  readonly metadata: ResolvedAgentMetadata;
279
291
  /**
280
292
  * Authored instructions prompt resolved from `instructions.md` or
@@ -51,6 +51,25 @@ export interface PublicAgentCompactionDefinition {
51
51
  */
52
52
  readonly thresholdPercent?: number;
53
53
  }
54
+ /**
55
+ * Experimental, opt-in agent capabilities authored in `agent.ts`.
56
+ *
57
+ * These options are unstable and may change or be removed in any release.
58
+ * Each agent (the root agent and every subagent) carries its own flags, so
59
+ * code mode can be enabled for the whole graph, only a subagent, or only
60
+ * the parent.
61
+ */
62
+ export interface AgentExperimentalDefinition {
63
+ /**
64
+ * Routes executable tools through a sandboxed code-execution wrapper
65
+ * instead of exposing them directly to the model. The model writes
66
+ * JavaScript that calls the tools inside the sandbox.
67
+ *
68
+ * When unset, Ash falls back to the `ASH_EXPERIMENTAL_CODE_MODE`
69
+ * environment variable (`"1"` enables it) for backwards compatibility.
70
+ */
71
+ readonly codeMode?: boolean;
72
+ }
54
73
  /**
55
74
  * Advanced hosted-build controls authored in `agent.ts`.
56
75
  *
@@ -76,6 +95,7 @@ export type InternalAgentDefinition = {
76
95
  description?: string;
77
96
  build?: AgentBuildDefinition;
78
97
  compaction?: InternalAgentCompactionDefinition;
98
+ experimental?: AgentExperimentalDefinition;
79
99
  model: InternalAgentModelDefinition;
80
100
  source?: ModuleSourceRef;
81
101
  };
@@ -95,6 +115,11 @@ export type PublicAgentDefinition = {
95
115
  readonly description?: string;
96
116
  readonly build?: AgentBuildDefinition;
97
117
  readonly compaction?: PublicAgentCompactionDefinition;
118
+ /**
119
+ * Experimental, opt-in capabilities. Unstable — see
120
+ * {@link AgentExperimentalDefinition}.
121
+ */
122
+ readonly experimental?: AgentExperimentalDefinition;
98
123
  readonly model: PublicAgentModelDefinition;
99
124
  /**
100
125
  * Optional override for the primary model's context window size, in tokens.
@@ -3,7 +3,20 @@ import type * as CodeModeModule from "#compiled/experimental-ai-sdk-code-mode/in
3
3
  export declare const CODE_MODE_TOOL_NAME = "code_mode";
4
4
  type CodeModeModuleNamespace = typeof CodeModeModule;
5
5
  export type { CodeModeApprovalInterrupt, CodeModeInterrupt, CodeModeInterruptExecutionContext, CodeModeInterruptPayload, CodeModeOptions, } from "#compiled/experimental-ai-sdk-code-mode/index.js";
6
- export declare function isCodeModeEnabled(env?: {
6
+ /**
7
+ * Reads the `ASH_EXPERIMENTAL_CODE_MODE` backstop. Per-agent
8
+ * `experimental.codeMode` takes precedence; this env var is the
9
+ * fallback applied to agents that do not set the flag.
10
+ */
11
+ export declare function isCodeModeEnvEnabled(env?: {
12
+ readonly [name: string]: string | undefined;
13
+ }): boolean;
14
+ /**
15
+ * Resolves the effective code-mode setting for one agent. The authored
16
+ * `experimental.codeMode` flag wins; when omitted, Ash falls back to the
17
+ * {@link isCodeModeEnvEnabled} environment backstop.
18
+ */
19
+ export declare function resolveCodeModeEnabled(experimentalCodeMode: boolean | undefined, env?: {
7
20
  readonly [name: string]: string | undefined;
8
21
  }): boolean;
9
22
  export declare function installCodeModeModule(module: CodeModeModuleNamespace): void;
@@ -1 +1 @@
1
- const CODE_MODE_TOOL_NAME=`code_mode`,CODE_MODE_MODULE_KEY=Symbol.for(`ash.codeMode.module`),CODE_MODE_MODULE_SPECIFIER=[`#compiled`,`experimental-ai-sdk-code-mode`,`index.js`].join(`/`);let codeModeModulePromise;function isCodeModeEnabled(e=process.env){return e.CODE_MODE===`1`}function installCodeModeModule(e){globalThis[CODE_MODE_MODULE_KEY]=e}async function loadCodeModeModule(){let e=globalThis[CODE_MODE_MODULE_KEY];return e===void 0?(codeModeModulePromise??=importCodeModeModule(CODE_MODE_MODULE_SPECIFIER),await codeModeModulePromise):e}async function importCodeModeModule(e){return await import(e)}export{CODE_MODE_TOOL_NAME,installCodeModeModule,isCodeModeEnabled,loadCodeModeModule};
1
+ const CODE_MODE_TOOL_NAME=`code_mode`,CODE_MODE_MODULE_KEY=Symbol.for(`ash.codeMode.module`),CODE_MODE_MODULE_SPECIFIER=[`#compiled`,`experimental-ai-sdk-code-mode`,`index.js`].join(`/`);let codeModeModulePromise;function isCodeModeEnvEnabled(e=process.env){return e.ASH_EXPERIMENTAL_CODE_MODE===`1`}function resolveCodeModeEnabled(e,t=process.env){return e??isCodeModeEnvEnabled(t)}function installCodeModeModule(e){globalThis[CODE_MODE_MODULE_KEY]=e}async function loadCodeModeModule(){let e=globalThis[CODE_MODE_MODULE_KEY];return e===void 0?(codeModeModulePromise??=importCodeModeModule(CODE_MODE_MODULE_SPECIFIER),await codeModeModulePromise):e}async function importCodeModeModule(e){return await import(e)}export{CODE_MODE_TOOL_NAME,installCodeModeModule,isCodeModeEnvEnabled,loadCodeModeModule,resolveCodeModeEnabled};
@@ -0,0 +1,132 @@
1
+ import type { PublicToolInputSchema } from "#shared/tool-definition.js";
2
+ import type { SessionContext } from "#public/definitions/callback-context.js";
3
+ import type { SessionAuth } from "#context/keys.js";
4
+ type ToolContext = SessionContext;
5
+ /**
6
+ * Event names supported by dynamic tool resolvers. Initially
7
+ * `"session.started"` and `"step.started"`; more events can be
8
+ * added by expanding this union.
9
+ */
10
+ export type DynamicToolEventName = "session.started" | "turn.started" | "step.started";
11
+ /**
12
+ * Context passed to a dynamic tool resolver's event handler.
13
+ *
14
+ * Provides read-only access to session identity, auth, and channel
15
+ * metadata. State access is not exposed here — resolvers read state
16
+ * through `defineState` handles or via the session context available
17
+ * inside tool `execute` functions.
18
+ */
19
+ export interface DynamicToolResolveContext {
20
+ readonly session: {
21
+ readonly id: string;
22
+ readonly auth: SessionAuth;
23
+ };
24
+ readonly channel: {
25
+ readonly kind?: string;
26
+ readonly continuationToken?: string;
27
+ };
28
+ /**
29
+ * Compiler-injected durable cache for resolver I/O results.
30
+ *
31
+ * First call (per session): executes `fn`, stores the serializable
32
+ * result durably, returns it.
33
+ * Replay (subsequent workflow steps): returns the cached result
34
+ * without calling `fn`.
35
+ *
36
+ * The cached value must be JSON-serializable. Non-serializable
37
+ * values cause a runtime error on first cache write.
38
+ *
39
+ * @internal Injected by the `ash:dynamic-tool-await-cache` bundler
40
+ * transform. Not intended for direct author use.
41
+ */
42
+ __cache<T>(key: string, fn: () => T | Promise<T>): Promise<T>;
43
+ }
44
+ /**
45
+ * A single tool entry within a resolved dynamic tool set.
46
+ *
47
+ * Identity comes from the entry's Record key — there is no `name`
48
+ * field. For `defineTools`, the runtime tool name is always
49
+ * `slug__key`. For `defineTool`, it is the file slug alone.
50
+ *
51
+ * `TInput` defaults to `Record<string, unknown>` but is inferred
52
+ * automatically when `inputSchema` is a Standard Schema (e.g. Zod):
53
+ *
54
+ * ```ts
55
+ * {
56
+ * inputSchema: z.object({ city: z.string() }),
57
+ * async execute(input) { return fetchWeather(input.city); },
58
+ * }
59
+ * ```
60
+ *
61
+ * When `inputSchema` is a plain JSON object, annotate `execute`
62
+ * explicitly:
63
+ *
64
+ * ```ts
65
+ * {
66
+ * inputSchema: { type: "object", properties: { city: { type: "string" } } },
67
+ * async execute(input: { city: string }) { return fetchWeather(input.city); },
68
+ * }
69
+ * ```
70
+ */
71
+ export interface DynamicToolEntry<TInput = Record<string, unknown>, TOutput = unknown> {
72
+ /** @internal Stamp set by `tool()` — raw object literals are rejected. */
73
+ readonly __brand: "ash:tool";
74
+ readonly description: string;
75
+ readonly inputSchema: PublicToolInputSchema<TInput>;
76
+ execute(input: TInput, ctx: ToolContext): TOutput | Promise<TOutput>;
77
+ }
78
+ /**
79
+ * A resolved tool set: keys are entry identifiers, values are tool
80
+ * entries produced by the {@link tool} helper. Uses `any` for the
81
+ * type params so entries with different schemas are assignable to
82
+ * the same Record — `tool()` captures the per-entry types before
83
+ * they reach this widened container.
84
+ */
85
+ export type DynamicToolSet = Readonly<Record<string, DynamicToolEntry<any, any>>>;
86
+ /**
87
+ * Event handler map for dynamic tool definitions. Each key is a
88
+ * supported event name; each value is a resolver function that
89
+ * receives the stream event and resolve context, and returns a
90
+ * record of tool entries or `null`.
91
+ *
92
+ * The handler return type is `DynamicToolSet` — using
93
+ * `DynamicToolEntry<any, any>` so per-entry Zod schemas infer
94
+ * their own `execute(input)` type without being widened.
95
+ */
96
+ export type DynamicToolEvents = {
97
+ readonly [K in DynamicToolEventName]?: (event: unknown, ctx: DynamicToolResolveContext) => DynamicToolSet | null | Promise<DynamicToolSet | null>;
98
+ };
99
+ /**
100
+ * Event handler map for a singular dynamic tool. Each handler returns
101
+ * a single tool entry or `null`.
102
+ */
103
+ export type DynamicSingleToolEvents = {
104
+ readonly [K in DynamicToolEventName]?: (event: unknown, ctx: DynamicToolResolveContext) => DynamicToolEntry | null | Promise<DynamicToolEntry | null>;
105
+ };
106
+ /**
107
+ * Marker discriminator for a `defineTools({ events })` export.
108
+ */
109
+ export declare const DYNAMIC_TOOLS_SENTINEL_KIND: "ash:dynamic-tools";
110
+ /**
111
+ * Marker discriminator for a `defineTool({ events })` export.
112
+ */
113
+ export declare const DYNAMIC_TOOL_SENTINEL_KIND: "ash:dynamic-tool";
114
+ /**
115
+ * Runtime shape of a `defineTools({ events })` export, stamped with a
116
+ * sentinel kind so the compiler/normalizer can detect it.
117
+ */
118
+ export interface DynamicToolsSentinel {
119
+ readonly kind: typeof DYNAMIC_TOOLS_SENTINEL_KIND;
120
+ readonly events: DynamicToolEvents;
121
+ }
122
+ /**
123
+ * Runtime shape of a `defineTool({ events })` export, stamped with a
124
+ * sentinel kind so the compiler/normalizer can detect it.
125
+ */
126
+ export interface DynamicToolSentinel {
127
+ readonly kind: typeof DYNAMIC_TOOL_SENTINEL_KIND;
128
+ readonly events: DynamicSingleToolEvents;
129
+ }
130
+ export declare function isDynamicToolsSentinel(value: unknown): value is DynamicToolsSentinel;
131
+ export declare function isDynamicToolSentinel(value: unknown): value is DynamicToolSentinel;
132
+ export {};
@@ -0,0 +1 @@
1
+ const DYNAMIC_TOOLS_SENTINEL_KIND=`ash:dynamic-tools`,DYNAMIC_TOOL_SENTINEL_KIND=`ash:dynamic-tool`;function isDynamicToolsSentinel(e){return typeof e==`object`&&!!e&&e.kind===`ash:dynamic-tools`}function isDynamicToolSentinel(e){return typeof e==`object`&&!!e&&e.kind===`ash:dynamic-tool`}export{DYNAMIC_TOOLS_SENTINEL_KIND,DYNAMIC_TOOL_SENTINEL_KIND,isDynamicToolSentinel,isDynamicToolsSentinel};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "experimental-ash",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "bin": {
5
5
  "ash": "./bin/ash.js",
6
6
  "experimental-ash": "./bin/ash.js"