experimental-ash 0.40.1 → 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.
- package/CHANGELOG.md +14 -0
- package/dist/docs/public/tools.md +165 -0
- package/dist/src/compiler/manifest.d.ts +16 -2
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/module-map.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/normalize-tool.d.ts +7 -3
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +35 -0
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -0
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +37 -0
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/providers/sandbox.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/code-mode.d.ts +1 -1
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/types.d.ts +7 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.d.ts +9 -3
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/internal/authored-module.d.ts +4 -0
- package/dist/src/internal/authored-module.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +39 -0
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +4 -0
- package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
- package/dist/src/public/definitions/agent.d.ts +1 -1
- package/dist/src/public/definitions/defineChannel.js +1 -1
- package/dist/src/public/definitions/tool.d.ts +67 -0
- package/dist/src/public/definitions/tool.js +1 -1
- package/dist/src/public/index.d.ts +1 -1
- package/dist/src/public/tools/index.d.ts +2 -1
- package/dist/src/public/tools/index.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search.js +1 -1
- package/dist/src/runtime/framework-tools/connection-tools.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/resolve-dynamic-tool.d.ts +12 -0
- package/dist/src/runtime/resolve-dynamic-tool.js +1 -0
- package/dist/src/runtime/types.d.ts +12 -0
- package/dist/src/shared/agent-definition.d.ts +25 -0
- package/dist/src/shared/code-mode.d.ts +14 -1
- package/dist/src/shared/code-mode.js +1 -1
- package/dist/src/shared/dynamic-tool-definition.d.ts +132 -0
- package/dist/src/shared/dynamic-tool-definition.js +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,isCodeModeToolExecutionOptions,readCodeModeConnectionAuthContext,toCodeModeConnectionAuthArgs}from"#runtime/framework-tools/code-mode-connection-auth.js";import{qualifiedConnectionToolName}from"#runtime/framework-tools/connection-tools.js";import{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{loadCodeModeModule}from"#shared/code-mode.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,isCodeModeToolExecutionOptions,readCodeModeConnectionAuthContext,toCodeModeConnectionAuthArgs}from"#runtime/framework-tools/code-mode-connection-auth.js";import{qualifiedConnectionToolName}from"#runtime/framework-tools/connection-tools.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";const logger=createLogger(`framework.connection-search`),ConnectionRegistryKey=new ContextKey(`ash.connectionRegistry`),DiscoveredConnectionToolsKey=new ContextKey(`ash.discoveredConnectionTools`),CONNECTION_SEARCH_TOOL_DEFINITION={description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. linear__list_issues) in your next response.`,execute:async(e,t)=>executeConnectionSearch(e,{codeMode:isCodeModeToolExecutionOptions(t),codeModeInterrupt:readCodeModeConnectionAuthContext(t)}),inputSchema:{additionalProperties:!1,properties:{connection:{description:`Optional: limit search to a specific connection name.`,type:`string`},limit:{description:`Max results to return. Default 10.`,type:`number`},keywords:{description:`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`,type:`string`}},required:[`keywords`],type:`object`},logicalPath:`ash:framework/connection-search`,name:`connection_search`,onCompact(){return loadContext().set(DiscoveredConnectionToolsKey,{byConnection:{}}),{}},sourceId:`ash:connection-search-tool`,sourceKind:`module`};async function executeConnectionSearch(e,n){let i=loadContext(),c=i.get(ConnectionRegistryKey);if(c===void 0)return[];await completePendingAuthorizations(c);let l=e.limit??10,u=tokenize(e.keywords),d=[],f=[],p=e.connection!==void 0&&e.connection!==``?c.getConnections().filter(t=>t.connectionName===e.connection):c.getConnections(),m={...i.get(DiscoveredConnectionToolsKey)?.byConnection},h=[];for(let t of p){if(n?.codeModeInterrupt?.resolution.status===`failed`&&n.codeModeInterrupt.payload.connectionName===t.connectionName){let{resolution:e}=n.codeModeInterrupt;f.push({connection:t.connectionName,description:t.description,error:e.reason,needsAuthorization:e.retryable});continue}let i;try{i=await c.getClient(t.connectionName).getToolMetadata()}catch(i){if(isConnectionAuthorizationRequiredError(i)){let i=resolveInteractiveAuth(c,t.connectionName);if(i&&n?.codeMode===!0){let{requestCodeModeInterrupt:n}=await loadCodeModeModule();n({args:toCodeModeConnectionAuthArgs(e),connectionName:t.connectionName,kind:CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,toolName:`connection_search`})}if(i){let e=getHookUrl(t.connectionName);if(e){let n=resolveConnectionPrincipal(t.connectionName,i);try{let{challenge:r,state:a}=await i.startAuthorization({callbackUrl:e,connection:{url:t.url??``},principal:n});h.push({name:t.connectionName,challenge:r,hookUrl:e,state:a})}catch(e){logger.warn(`startAuthorization failed`,{connection:t.connectionName,error:e instanceof Error?e:Error(String(e))})}}}f.push({connection:t.connectionName,description:t.description,needsAuthorization:!0});continue}if(isConnectionAuthorizationFailedError(i)){logger.warn(`connection authorization failed`,{connection:t.connectionName,reason:i.reason,retryable:i.retryable,error:i}),f.push({connection:t.connectionName,description:t.description,error:`Authorization failed for ${t.connectionName}: ${i.message}`});continue}let o=i instanceof Error?i.message:`unknown error`;logger.warn(`failed to load connection tools`,{connection:t.connectionName,error:i instanceof Error?i:Error(o)}),f.push({connection:t.connectionName,description:t.description,error:`Failed to load tools for "${t.connectionName}": ${o}`});continue}m[t.connectionName]=i;for(let e of i){let n=scoreMatch(u,e);n>0&&d.push({item:{connection:t.connectionName,description:e.description,inputSchema:e.inputSchema,qualifiedName:qualifiedConnectionToolName(t.connectionName,e.name),tool:e.name},score:n})}}if(i.set(DiscoveredConnectionToolsKey,{byConnection:m}),h.length>0)return requestAuthorization(h);d.sort((e,t)=>t.score-e.score);let g=d.slice(0,l).map(e=>e.item);return g.length>0?[...g,...f]:p.map(e=>f.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}async function completePendingAuthorizations(e){let n=loadContext();for(let t of e.getConnections()){let r=getAuthorizationResult(t.connectionName);if(!r)continue;let a=resolveInteractiveAuth(e,t.connectionName);if(!a)continue;let o=resolveConnectionPrincipal(t.connectionName,a),s=await a.completeAuthorization({callbackUrl:r.hookUrl,connection:{url:t.url??``},principal:o,request:r.callback,state:r.state});writeCachedToken(n,t.connectionName,principalKey(o),s)}}function tokenize(e){return e.toLowerCase().split(/[\s_\-./]+/).filter(e=>e.length>1)}function scoreMatch(e,t){let n=tokenize(t.name),r=tokenize(t.description),i=0;for(let t of e){for(let e of n)(e.includes(t)||t.includes(e))&&(i+=3);for(let e of r)(e.includes(t)||t.includes(e))&&(i+=1)}return i}function resolveInteractiveAuth(e,t){let n=e.getConnections().find(e=>e.connectionName===t);if(n?.authorization&&supportsInteractiveAuthorization(n.authorization))return n.authorization}export{CONNECTION_SEARCH_TOOL_DEFINITION,ConnectionRegistryKey,DiscoveredConnectionToolsKey,executeConnectionSearch,scoreMatch,tokenize};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{loadContext}from"#context/container.js";import"#runtime/framework-tools/connection-search.js";import{
|
|
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{
|
|
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))),
|
|
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
|
-
|
|
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
|
|
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};
|