experimental-ash 0.46.0 → 0.48.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 +31 -0
- package/dist/docs/public/advanced/hooks.mdx +7 -7
- package/dist/docs/public/advanced/typescript-api.md +1 -1
- package/dist/docs/public/channels/index.md +2 -2
- package/dist/docs/public/channels/slack.mdx +12 -17
- package/dist/docs/public/frontend/use-ash-agent.md +13 -17
- package/dist/src/channel/adapter.js +1 -1
- package/dist/src/channel/routes.d.ts +14 -7
- package/dist/src/channel/send.js +1 -1
- package/dist/src/channel/types.d.ts +6 -3
- package/dist/src/client/index.d.ts +1 -1
- package/dist/src/client/message-reducer-types.d.ts +1 -0
- package/dist/src/client/message-reducer.js +1 -1
- package/dist/src/client/message-response.d.ts +2 -2
- package/dist/src/client/message-response.js +1 -1
- package/dist/src/client/output-schema.d.ts +12 -0
- package/dist/src/client/output-schema.js +1 -0
- package/dist/src/client/session.d.ts +2 -2
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +17 -2
- package/dist/src/compiler/compile-from-memory.d.ts +1 -0
- package/dist/src/compiler/compile-from-memory.js +1 -1
- package/dist/src/compiler/manifest.d.ts +4 -0
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/compiler/remote-agent-node.d.ts +2 -0
- package/dist/src/compiler/remote-agent-node.js +1 -1
- package/dist/src/context/build-dynamic-tools.d.ts +13 -0
- package/dist/src/context/build-dynamic-tools.js +1 -0
- package/dist/src/context/dynamic-instruction-lifecycle.d.ts +13 -13
- package/dist/src/context/dynamic-instruction-lifecycle.js +1 -1
- package/dist/src/context/dynamic-resolve-context.d.ts +12 -0
- package/dist/src/context/dynamic-resolve-context.js +1 -0
- package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +4 -10
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/hook-lifecycle.d.ts +2 -2
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +30 -23
- package/dist/src/context/keys.js +1 -1
- package/dist/src/execution/create-session-step.d.ts +2 -0
- package/dist/src/execution/create-session-step.js +1 -1
- package/dist/src/execution/durable-session-store.d.ts +2 -0
- package/dist/src/execution/next-driver-action.d.ts +1 -0
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/session.d.ts +1 -0
- package/dist/src/execution/session.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-steps.d.ts +22 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/compaction.js +1 -1
- package/dist/src/harness/messages.js +1 -1
- package/dist/src/harness/prompt-cache.d.ts +11 -1
- package/dist/src/harness/prompt-cache.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/types.d.ts +17 -5
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/json-schema.d.ts +1 -6
- package/dist/src/internal/json-schema.js +1 -1
- package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
- package/dist/src/protocol/message.d.ts +29 -3
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/public/channels/ash.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.d.ts +1 -2
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +3 -7
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +1 -2
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +1 -2
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/definitions/instructions.d.ts +7 -12
- package/dist/src/public/definitions/remote-agent.d.ts +9 -0
- package/dist/src/public/definitions/skill.js +1 -1
- package/dist/src/runtime/agent/bootstrap-model-utils.js +1 -1
- package/dist/src/runtime/agent/bootstrap.d.ts +1 -0
- package/dist/src/runtime/agent/bootstrap.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +2 -2
- package/dist/src/runtime/agent/mock-structured-output.d.ts +5 -0
- package/dist/src/runtime/agent/mock-structured-output.js +1 -0
- package/dist/src/runtime/framework-tools/final-output.d.ts +14 -0
- package/dist/src/runtime/framework-tools/final-output.js +1 -0
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -0
- package/dist/src/shared/agent-definition.d.ts +9 -0
- package/dist/src/shared/dynamic-tool-definition.d.ts +20 -0
- package/dist/src/shared/dynamic-tool-definition.js +1 -1
- package/dist/src/shared/json-schema.d.ts +7 -0
- package/dist/src/shared/json-schema.js +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{expectObjectRecord,expectOnlyKnownKeys,expectString}from"#internal/authored-module.js";import{ASH_CREATE_SESSION_ROUTE_PATH}from"#protocol/routes.js";import{createCompiledSubagentNodeId}from"#compiler/manifest.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";import{createPathDerivedSourceId}from"#discover/manifest.js";async function compileSubagentGraph(e){let t=[],n=[],r=[];for(let i of e.subagents){let a=await compileSubagentDefinition({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,parentNodeId:e.parentNodeId,source:i});if(a.kind===`remote`){r.push(a.node);continue}t.push(a.node,...a.descendants.nodes),n.push({childNodeId:a.node.nodeId,parentNodeId:e.parentNodeId},...a.descendants.edges)}return{edges:n,nodes:t,remoteAgents:r}}async function compileSubagentDefinition(e){let t=e.source.manifest.configModule;if(t===void 0)throw Error(`Subagent "${e.source.logicalPath}" is missing an agent config module.`);let n=await loadModuleBackedDefinition({agentRoot:e.source.manifest.agentRoot,kind:`subagent config`,source:t});return readAgentDefinitionKind(n)===`remote`?{kind:`remote`,node:compileRemoteAgent({source:e.source,value:n})}:{kind:`local`,...await compileLocalSubagent(e)}}async function compileSubagent(e){let t=createCompiledSubagentNodeId(e.parentNodeId,e.source.sourceId),n=e.source.subagentId,r=await e.compileAgentNodeManifest({...e.source.manifest,appRoot:e.appRoot},e.context),
|
|
1
|
+
import{expectObjectRecord,expectOnlyKnownKeys,expectString}from"#internal/authored-module.js";import{ASH_CREATE_SESSION_ROUTE_PATH}from"#protocol/routes.js";import{normalizeJsonSchemaDefinition}from"#shared/json-schema.js";import{createCompiledSubagentNodeId}from"#compiler/manifest.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";import{createPathDerivedSourceId}from"#discover/manifest.js";async function compileSubagentGraph(e){let t=[],n=[],r=[];for(let i of e.subagents){let a=await compileSubagentDefinition({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,parentNodeId:e.parentNodeId,source:i});if(a.kind===`remote`){r.push(a.node);continue}t.push(a.node,...a.descendants.nodes),n.push({childNodeId:a.node.nodeId,parentNodeId:e.parentNodeId},...a.descendants.edges)}return{edges:n,nodes:t,remoteAgents:r}}async function compileSubagentDefinition(e){let t=e.source.manifest.configModule;if(t===void 0)throw Error(`Subagent "${e.source.logicalPath}" is missing an agent config module.`);let n=await loadModuleBackedDefinition({agentRoot:e.source.manifest.agentRoot,kind:`subagent config`,source:t});return readAgentDefinitionKind(n)===`remote`?{kind:`remote`,node:compileRemoteAgent({source:e.source,value:n})}:{kind:`local`,...await compileLocalSubagent(e)}}async function compileSubagent(e){let t=createCompiledSubagentNodeId(e.parentNodeId,e.source.sourceId),n=e.source.subagentId,r=await e.compileAgentNodeManifest({...e.source.manifest,appRoot:e.appRoot},e.context),i=r.config.description;if(!i)throw Error(`Local subagent "${e.source.logicalPath}" is missing a "description" field on its agent config. Add \`description\` to \`defineAgent({ ... })\` so the parent agent can decide when to delegate to this subagent.`);let o=await compileSubagentGraph({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,parentNodeId:t,subagents:e.source.manifest.subagents});return{descendants:o,node:{agent:{...r,remoteAgents:[...o.remoteAgents]},description:i,entryPath:e.source.entryPath,logicalPath:e.source.logicalPath,name:n,nodeId:t,rootPath:e.source.rootPath,sourceId:e.source.sourceId,sourceKind:`module`}}}const compileLocalSubagent=compileSubagent;function compileRemoteAgent(e){let t=e.source.manifest.configModule;if(t===void 0)throw Error(`Remote agent "${e.source.logicalPath}" is missing a config module.`);assertRemoteAgentDefinitionHasNoLocalPackageEntries(e.source);let n=normalizeRemoteAgentDefinition(e.value,`Expected the remote agent config export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`);return{...createRemoteAgentModuleSourceRef(e.source,t),description:n.description,entryPath:e.source.entryPath,name:e.source.subagentId,nodeId:e.source.sourceId,outputSchema:n.outputSchema,path:n.path,rootPath:e.source.rootPath,url:n.url}}function createRemoteAgentModuleSourceRef(e,t){let n=e.logicalPath===t.logicalPath?t.logicalPath:`${e.logicalPath}/${t.logicalPath}`,r={logicalPath:n,sourceId:createPathDerivedSourceId(n),sourceKind:`module`};return t.exportName!==void 0&&(r.exportName=t.exportName),r}function readAgentDefinitionKind(e){return typeof e!=`object`||!e?`local`:e.kind===`remote`?`remote`:`local`}function normalizeRemoteAgentDefinition(a,o){let s=expectObjectRecord(a,o);if(expectOnlyKnownKeys(s,[`auth`,`description`,`headers`,`kind`,`outputSchema`,`path`,`url`],o),s.kind!==`remote`)throw Error(`${o} Expected "kind" to be "remote".`);return{description:expectString(s.description,o),outputSchema:s.outputSchema===void 0?void 0:normalizeJsonSchemaDefinition(s.outputSchema),path:s.path===void 0?ASH_CREATE_SESSION_ROUTE_PATH:expectString(s.path,o),url:expectString(s.url,o)}}function assertRemoteAgentDefinitionHasNoLocalPackageEntries(e){let t=e.manifest,n=[t.connections.length>0?`connections/`:void 0,t.hooks.length>0?`hooks/`:void 0,t.instructions.length>0?`instructions`:void 0,t.lib.length>0?`lib/`:void 0,t.sandbox===null?void 0:`sandbox/`,t.sandboxWorkspaces.length>0?`sandbox/workspace/`:void 0,t.schedules.length>0?`schedules/`:void 0,t.skills.length>0?`skills/`:void 0,t.subagents.length>0?`subagents/`:void 0,t.tools.length>0?`tools/`:void 0].filter(e=>e!==void 0);if(n.length!==0)throw Error(`Remote subagent definition "${e.logicalPath}" cannot include local package entries. Remove unsupported entries: ${n.join(`, `)}.`)}export{compileSubagentGraph};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "#compiled/zod/index.js";
|
|
2
|
+
import type { JsonObject } from "#shared/json.js";
|
|
2
3
|
import type { Node } from "#shared/node.js";
|
|
3
4
|
import type { ModuleSourceRef } from "#shared/source-ref.js";
|
|
4
5
|
/**
|
|
@@ -10,6 +11,7 @@ export type CompiledRemoteAgentNode = Readonly<ModuleSourceRef & Node & {
|
|
|
10
11
|
description: string;
|
|
11
12
|
entryPath: string;
|
|
12
13
|
name: string;
|
|
14
|
+
outputSchema?: JsonObject;
|
|
13
15
|
path: string;
|
|
14
16
|
rootPath: string;
|
|
15
17
|
url: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";const compiledRemoteAgentNodeSchema=z.object({description:z.string(),entryPath:z.string(),exportName:z.string().optional(),logicalPath:z.string(),name:z.string(),nodeId:z.string(),path:z.string(),rootPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),url:z.string()}).strict();export{compiledRemoteAgentNodeSchema};
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{jsonObjectSchema}from"#shared/json-schemas.js";const compiledRemoteAgentNodeSchema=z.object({description:z.string(),entryPath:z.string(),exportName:z.string().optional(),logicalPath:z.string(),name:z.string(),nodeId:z.string(),outputSchema:jsonObjectSchema.optional(),path:z.string(),rootPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),url:z.string()}).strict();export{compiledRemoteAgentNodeSchema};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HarnessToolDefinition } from "#harness/execute-tool.js";
|
|
2
|
+
import type { ContextKey } from "#context/key.js";
|
|
3
|
+
/**
|
|
4
|
+
* Builds live dynamic tool definitions. Narrower scopes appear first
|
|
5
|
+
* so they win on name collision (the tool-loop uses `??=` for dedup).
|
|
6
|
+
*
|
|
7
|
+
* Step tools are live closures (re-resolved every step via
|
|
8
|
+
* `LiveStepToolsKey`). Session/turn tools are replayed from durable
|
|
9
|
+
* metadata via the bundler's registered step functions.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildDynamicTools(ctx: {
|
|
12
|
+
get<T>(key: ContextKey<T>): T | undefined;
|
|
13
|
+
}): readonly HarnessToolDefinition[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{LiveStepToolsKey,SessionDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{jsonSchema}from"ai";import{buildCallbackContext}from"#context/build-callback-context.js";const log=createLogger(`dynamic-tools`);function lookupStepFunction(e){try{let t=globalThis[Symbol.for(`@workflow/core//registeredSteps`)];return t===void 0?null:t.get(e)||null}catch{return null}}function replayTools(e){let t=[];for(let n of e){if(!n.executeStepFnName||!n.closureVars){log.warn(`Dynamic tool "${n.name}" has no registered step function — skipping on this step. The bundler transform may not have processed this tool file.`);continue}let e=lookupStepFunction(n.executeStepFnName);if(!e){log.warn(`Dynamic tool "${n.name}" references step function "${n.executeStepFnName}" which is not registered — skipping on this step.`);continue}t.push({description:n.description,execute:t=>e(n.closureVars,t,buildCallbackContext()),inputSchema:jsonSchema(n.inputSchema),name:n.name})}return t}function buildDynamicTools(e){let r=e.get(LiveStepToolsKey)??[],i=replayTools(e.get(TurnDynamicToolMetadataKey)??[]),a=replayTools(e.get(SessionDynamicToolMetadataKey)??[]);return[...r,...i,...a]}export{buildDynamicTools};
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import type { ModelMessage } from "ai";
|
|
1
|
+
import type { ModelMessage, SystemModelMessage } from "ai";
|
|
2
2
|
import type { HandleMessageStreamEvent } from "#protocol/message.js";
|
|
3
3
|
import type { ResolvedDynamicInstructionsResolver } from "#runtime/types.js";
|
|
4
4
|
import type { ContextContainer } from "#context/container.js";
|
|
5
|
-
import { ContextKey } from "#context/key.js";
|
|
5
|
+
import type { ContextKey } from "#context/key.js";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* messages. Read by the tool-loop to inject into the next model call.
|
|
10
|
-
*
|
|
11
|
-
* Virtual keys are cleared at workflow step boundaries, so messages
|
|
12
|
-
* are never persisted or duplicated across steps.
|
|
7
|
+
* Builds the flattened system messages from session + turn durable keys.
|
|
8
|
+
* Session-scoped entries appear first.
|
|
13
9
|
*/
|
|
14
|
-
export declare
|
|
10
|
+
export declare function buildDynamicInstructionMessages(ctx: {
|
|
11
|
+
get<T>(key: ContextKey<T>): T | undefined;
|
|
12
|
+
}): SystemModelMessage[];
|
|
15
13
|
/**
|
|
16
|
-
* Dispatches a stream event to dynamic instruction resolvers.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
14
|
+
* Dispatches a stream event to dynamic instruction resolvers.
|
|
15
|
+
*
|
|
16
|
+
* Each resolver's output replaces its own slot (keyed by slug) in the
|
|
17
|
+
* scope-appropriate durable key (session or turn). The tool-loop calls
|
|
18
|
+
* {@link buildDynamicInstructionMessages} to assemble the flattened
|
|
19
|
+
* result for the model call.
|
|
20
20
|
*/
|
|
21
21
|
export declare function dispatchDynamicInstructionEvent(input: {
|
|
22
22
|
readonly ctx: ContextContainer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{SessionDynamicInstructionsKey,TurnDynamicInstructionsKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{ALLOWED_DYNAMIC_INSTRUCTION_EVENTS,isBrandedInstructionsEntry}from"#shared/dynamic-tool-definition.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";const log=createLogger(`dynamic-instructions`);function lowerToSystemMessage(e){let t=e.markdown.trim();if(t.length!==0)return{role:`system`,content:t}}function durableKeyForEvent(e){switch(e){case`session.started`:return SessionDynamicInstructionsKey;case`turn.started`:return TurnDynamicInstructionsKey;default:return}}function buildDynamicInstructionMessages(e){let r=e.get(SessionDynamicInstructionsKey)??{},i=e.get(TurnDynamicInstructionsKey)??{};return[...Object.values(r).flat(),...Object.values(i).flat()]}async function dispatchDynamicInstructionEvent(e){let{ctx:t,resolvers:n,event:a,messages:o}=e;if(!ALLOWED_DYNAMIC_INSTRUCTION_EVENTS.has(a.type))return;let s=n.filter(e=>e.eventNames.includes(a.type));if(s.length===0)return;let c=durableKeyForEvent(a.type);if(c===void 0)return;let l=buildResolveContext(t,o),u=await Promise.allSettled(s.map(async e=>{let t=e.events[a.type];if(t===void 0)return null;let n=await t(a,l);return n==null?{resolver:e,message:void 0}:isBrandedInstructionsEntry(n)?{resolver:e,message:lowerToSystemMessage(n)}:(log.error(`Dynamic instructions resolver "${e.slug}" returned an unbranded value — wrap with defineInstructions().`),null)})),d={...t.get(c)};for(let e of u){if(e.status===`rejected`){log.error(`Dynamic instructions resolver (${a.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}if(e.value===null)continue;let{resolver:t,message:n}=e.value;n===void 0?delete d[t.slug]:d[t.slug]=[n]}t.set(c,d)}export{buildDynamicInstructionMessages,dispatchDynamicInstructionEvent};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ModelMessage } from "ai";
|
|
2
|
+
import type { DynamicResolveContext } from "#shared/dynamic-tool-definition.js";
|
|
3
|
+
import type { AlsContext } from "#context/container.js";
|
|
4
|
+
type ReadableContext = Pick<AlsContext, "get">;
|
|
5
|
+
/**
|
|
6
|
+
* Builds the {@link DynamicResolveContext} from the active ALS context.
|
|
7
|
+
*
|
|
8
|
+
* Shared by all three dynamic lifecycle dispatchers (tools, skills,
|
|
9
|
+
* instructions) so resolver handlers receive a consistent context shape.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildResolveContext(ctx: ReadableContext, messages: readonly ModelMessage[]): DynamicResolveContext;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getAdapterKind}from"#channel/adapter.js";import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";function buildResolveContext(e,t){let n=e.get(SessionIdKey)??``,r=e.get(AuthKey)??null,i=e.get(InitiatorAuthKey)??null,a=e.get(ChannelKey),o=e.get(ContinuationTokenKey);return{session:{id:n,auth:{current:r,initiator:i}},channel:{kind:a===void 0?void 0:getAdapterKind(a),continuationToken:o},messages:t}}export{buildResolveContext};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{DynamicSkillManifestKey,SandboxKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{ALLOWED_DYNAMIC_SKILL_EVENTS,isBrandedSkillEntry}from"#shared/dynamic-tool-definition.js";import{normalizeSkillPackage,writeSkillPackageToSandbox}from"#shared/skill-package.js";import{ContextKey}from"#context/key.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{formatAvailableSkillsSection}from"#execution/skills/instructions.js";const log=createLogger(`dynamic-skills`);function qualifyDynamicSkillNames(e,t,n){let r=Object.keys(n),i=[];if(r.length===0)return i;if(t||r.length===1)return i.push({name:e,entryKey:r[0],entry:n[r[0]]}),i;for(let t of r)i.push({name:`${e}__${t}`,entryKey:t,entry:n[t]});return i}function formatDynamicSkillAnnouncement(e){return formatAvailableSkillsSection(Object.values(e).flat())??``}const PendingSkillAnnouncementKey=new ContextKey(`ash.pendingSkillAnnouncement`);async function dispatchDynamicSkillEvent(e){let{ctx:a,resolvers:o,event:s,messages:c}=e;if(a.get(PendingSkillAnnouncementKey)===void 0){let e=a.get(DynamicSkillManifestKey);e!==void 0&&Object.keys(e).length>0&&a.setVirtualContext(PendingSkillAnnouncementKey,formatDynamicSkillAnnouncement(e))}if(!ALLOWED_DYNAMIC_SKILL_EVENTS.has(s.type))return;let l=o.filter(e=>e.eventNames.includes(s.type));if(l.length===0)return;let u=buildResolveContext(a,c),d=new Set(a.require(BundleKey).resolvedAgent.skills.map(e=>e.name)),f=a.get(DynamicSkillManifestKey)??{},p=[],m=await Promise.allSettled(l.map(async e=>{let t=e.events[s.type];if(t===void 0)return null;let n=await t(s,u);if(n==null)return{resolver:e,named:[]};let r,i;return isBrandedSkillEntry(n)?(r={_single:n},i=!0):(r=n,i=!1),{resolver:e,named:qualifyDynamicSkillNames(e.slug,i,r)}}));for(let e of m){if(e.status===`rejected`){log.error(`Dynamic skill resolver (${s.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}e.value!==null&&p.push({resolver:e.value.resolver,skills:e.value.named.map(({name:e,entry:t})=>normalizeSkillPackage({...t,name:e}))})}if(p.length===0)return;let h={...f};for(let{resolver:e,skills:t}of p)t.length===0?delete h[e.slug]:h[e.slug]=t.map(e=>({description:e.description,name:e.name}));let g=new Map;for(let[e,t]of Object.entries(h))for(let{name:n}of t){if(d.has(n))throw Error(`Dynamic skill "${n}" from resolver "${e}" conflicts with an authored skill.`);let t=g.get(n);if(t!==void 0)throw Error(`Dynamic skill "${n}" from resolver "${e}" conflicts with dynamic resolver "${t}".`);g.set(n,e)}let _=await a.require(SandboxKey).get();if(_!==null)for(let{skills:e}of p)for(let t of e)await writeSkillPackageToSandbox({sandbox:_,skill:t});a.set(DynamicSkillManifestKey,h),a.setVirtualContext(PendingSkillAnnouncementKey,formatDynamicSkillAnnouncement(h))}export{PendingSkillAnnouncementKey,dispatchDynamicSkillEvent};
|
|
@@ -12,16 +12,10 @@ import type { DurableDynamicToolMetadata } from "#context/keys.js";
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function replayDynamicSessionTools(metadata: readonly DurableDynamicToolMetadata[], _resolvers: readonly ResolvedDynamicToolResolver[]): readonly HarnessToolDefinition[];
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* the virtual key is empty (workflow step boundary crossed).
|
|
20
|
-
* 2. **Resolve phase**: run resolver handlers for the current event,
|
|
21
|
-
* capture closures as durable metadata, produce live tools.
|
|
22
|
-
*
|
|
23
|
-
* The tool-loop reads {@link DynamicToolsKey} right before each model
|
|
24
|
-
* call. Events update it; the tool-loop picks up whatever is current.
|
|
15
|
+
* Dispatches a stream event to dynamic tool resolvers. Each
|
|
16
|
+
* resolver's metadata replaces its slot (by slug) in the
|
|
17
|
+
* scope-appropriate durable key. The tool-loop calls
|
|
18
|
+
* {@link buildDynamicTools} to assemble the effective toolset.
|
|
25
19
|
*/
|
|
26
20
|
export declare function dispatchDynamicToolEvent(input: {
|
|
27
21
|
readonly ctx: ContextContainer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{LiveStepToolsKey,SessionDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{ALLOWED_DYNAMIC_TOOL_EVENTS,isBrandedToolEntry}from"#shared/dynamic-tool-definition.js";import{jsonSchema,zodSchema}from"ai";import{buildCallbackContext}from"#context/build-callback-context.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{normalizeJsonSchemaDefinition}from"#internal/json-schema.js";const log=createLogger(`dynamic-tools`);function toHarnessToolDefinition(e,t){return{description:t.description,execute:e=>t.execute(e,buildCallbackContext()),inputSchema:convertInputSchema(t.inputSchema),name:e,...t.toModelOutput===void 0?{}:{toModelOutput:t.toModelOutput}}}function convertInputSchema(e){return typeof e==`object`&&e&&`~standard`in e?zodSchema(e):jsonSchema(e)}function qualifyDynamicToolNames(e,t,n){let r=Object.keys(n),i=[];if(r.length===0)return i;if(t)return i.push({name:e,entryKey:r[0],entry:n[r[0]]}),i;for(let t of r)i.push({name:`${e}__${t}`,entryKey:t,entry:n[t]});return i}function replayDynamicSessionTools(e,t){let n=[];for(let t of e){if(!t.executeStepFnName||!t.closureVars){log.warn(`Dynamic tool "${t.name}" has no registered step function — skipping on this step. The bundler transform may not have processed this tool file.`);continue}let e=lookupStepFunction(t.executeStepFnName);if(!e){log.warn(`Dynamic tool "${t.name}" references step function "${t.executeStepFnName}" which is not registered — skipping on this step.`);continue}n.push({description:t.description,execute:n=>e(t.closureVars,n,buildCallbackContext()),inputSchema:jsonSchema(t.inputSchema),name:t.name})}return n}function lookupStepFunction(e){try{let t=globalThis[Symbol.for(`@workflow/core//registeredSteps`)];return t===void 0?null:t.get(e)||null}catch{return null}}function safeSerialize(e){try{return JSON.parse(JSON.stringify(e))}catch{return{}}}function durableKeyForEvent(e){switch(e){case`session.started`:return SessionDynamicToolMetadataKey;case`turn.started`:return TurnDynamicToolMetadataKey;default:return}}async function resolveToolsFromEvent(e,t,n,r){let a=await Promise.allSettled(t.map(async t=>{let i=t.events[n.type];if(i===void 0)return null;let a=await i(n,buildResolveContext(e,r));if(a==null)return null;let s,c;return isBrandedToolEntry(a)?(s={_single:a},c=!0):(s=a,c=!1),{resolver:t,entries:s,isSingle:c}})),s=[],c=[];for(let e of a){if(e.status===`rejected`){log.error(`Dynamic tool resolver (${n.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}if(e.value===null)continue;let{resolver:t,entries:r,isSingle:a}=e.value,o=qualifyDynamicToolNames(t.slug,a,r);for(let{name:e,entryKey:n,entry:r}of o){c.push(toHarnessToolDefinition(e,r));let i=`__executeStepFn`in r?r.__executeStepFn:void 0,a=`__closureVars`in r?r.__closureVars:void 0;s.push({name:e,description:r.description,inputSchema:normalizeJsonSchemaDefinition(r.inputSchema),resolverSlug:t.slug,entryKey:n,executeStepFnName:i?.stepId,closureVars:a===void 0?void 0:safeSerialize(a)})}}return{metadata:s,liveTools:c}}async function dispatchDynamicToolEvent(e){let{ctx:n,resolvers:r,event:i,messages:o}=e;if(!ALLOWED_DYNAMIC_TOOL_EVENTS.has(i.type))return;let s=r.filter(e=>e.eventNames.includes(i.type));if(s.length===0)return;let{metadata:c,liveTools:l}=await resolveToolsFromEvent(n,s,i,o);if(i.type===`step.started`){n.setVirtualContext(LiveStepToolsKey,l);return}let u=durableKeyForEvent(i.type);if(u===void 0)return;let d=new Set(s.map(e=>e.slug)),f=(n.get(u)??[]).filter(e=>!d.has(e.resolverSlug));n.set(u,[...f,...c])}export{dispatchDynamicToolEvent,replayDynamicSessionTools};
|
|
@@ -5,7 +5,7 @@ import type { RuntimeHookRegistry } from "#runtime/hooks/registry.js";
|
|
|
5
5
|
import type { ContextContainer } from "./container.js";
|
|
6
6
|
/**
|
|
7
7
|
* Outcome of {@link dispatchHookLifecycle}. `proceed` carries the
|
|
8
|
-
* input augmented with merged
|
|
8
|
+
* input augmented with merged context. `turn-failed` means a
|
|
9
9
|
* `lifecycle.turn` hook threw; the recoverable `turn.failed` cascade
|
|
10
10
|
* has already been emitted.
|
|
11
11
|
*/
|
|
@@ -35,7 +35,7 @@ export interface DispatchHookLifecycleInput {
|
|
|
35
35
|
* runs so a thrown hook does not retry. A throw re-propagates and
|
|
36
36
|
* the runtime escalates to terminal `session.failed`.
|
|
37
37
|
* - `lifecycle.turn` runs once per fresh delivery. Each hook may
|
|
38
|
-
* return `{
|
|
38
|
+
* return `{ context }`; context contributions are
|
|
39
39
|
* concatenated in registry order. A thrown hook emits the recoverable
|
|
40
40
|
* `turn.failed` cascade and returns `kind: "turn-failed"`.
|
|
41
41
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ContinuationTokenKey,SessionPreparedKey}from"./keys.js";import{createLogger}from"#internal/logging.js";import{getAdapterKind}from"#channel/adapter.js";import{toErrorMessage}from"#shared/errors.js";import{
|
|
1
|
+
import{ContinuationTokenKey,SessionPreparedKey}from"./keys.js";import{createLogger}from"#internal/logging.js";import{getAdapterKind}from"#channel/adapter.js";import{toErrorMessage}from"#shared/errors.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{emitRecoverableFailedTurn,emitTurnPreamble,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";const log=createLogger(`hooks.lifecycle`);async function dispatchHookLifecycle(e){let{ctx:n,registry:r,emit:a}=e,o=getHarnessEmissionState(e.session.state),s=buildHookContext(n),u=e.session;if(r.session.length>0&&n.get(SessionPreparedKey)!==!0){n.set(SessionPreparedKey,!0);for(let e of r.session)await e.handler(s)}let d=!1,f=o;try{for(let e of r.turn)await e.handler(s)}catch(t){let n=toErrorMessage(t);try{return d||=(f=await emitTurnPreamble(a,{message:e.input.message},o,e.runtimeIdentity),!0),{kind:`turn-failed`,message:n,nextSession:setHarnessEmissionState(u,await emitRecoverableFailedTurn(a,f,{code:`HOOK_TURN_FAILED`,message:n}))}}catch(e){throw log.error(`Event hook threw while emitting the turn.failed cascade for a lifecycle.turn failure — escalating to session.failed.`,{error:toErrorMessage(e)}),e}}return{kind:`proceed`,input:e.input,nextSession:u}}async function dispatchStreamEventHooks(e){let t=e.registry.streamEventsByType.get(e.event.type)??[],n=e.registry.streamEventsWildcard;if(t.length===0&&n.length===0)return;let r=buildHookContext(e.ctx);for(let n of t)await n.handler(e.event,r);for(let t of n)await t.handler(e.event,r)}function buildHookContext(t){let n=t.require(BundleKey),i=t.get(ChannelKey),c=t.get(ContinuationTokenKey),l=i===void 0?void 0:getAdapterKind(i);return{...buildCallbackContext(),agent:{name:n.resolvedAgent.config.name??`agent`,nodeId:n.nodeId},channel:{kind:l,continuationToken:c}}}async function runHookLifecycleStep(e,t){let n=await dispatchHookLifecycle(e);return n.kind===`turn-failed`?{next:e.mode===`conversation`?null:{done:!0,output:n.message},session:n.nextSession}:t(n.nextSession,n.input)}export{dispatchHookLifecycle,dispatchStreamEventHooks,runHookLifecycleStep};
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* tier. Codec-carrying keys (`ChannelKey`, `BundleKey`) live in
|
|
4
4
|
* `#runtime/sessions/runtime-context-keys.ts`.
|
|
5
5
|
*/
|
|
6
|
+
import type { SystemModelMessage } from "ai";
|
|
7
|
+
import type { JsonObject } from "#shared/json.js";
|
|
6
8
|
import type { ChannelInstrumentationProjection, SessionAuthContext, SessionCallback, SessionCapabilities, SessionParent, SessionTurn } from "#channel/types.js";
|
|
7
9
|
import { ContextKey } from "#context/key.js";
|
|
8
10
|
import type { SandboxAccess } from "#sandbox/state.js";
|
|
@@ -56,37 +58,32 @@ export declare const SessionCallbackKey: ContextKey<SessionCallback>;
|
|
|
56
58
|
export declare const SessionPreparedKey: ContextKey<boolean>;
|
|
57
59
|
export declare const SessionKey: ContextKey<Session>;
|
|
58
60
|
export declare const SandboxKey: ContextKey<SandboxAccess>;
|
|
59
|
-
/**
|
|
60
|
-
* Virtual (non-serialized) live dynamic tool definitions. Updated by
|
|
61
|
-
* {@link dispatchDynamicToolEvent} whenever a subscribed stream event
|
|
62
|
-
* fires. Read by the tool-loop when building the effective toolset.
|
|
63
|
-
*/
|
|
64
|
-
export declare const DynamicToolsKey: ContextKey<import("#harness/execute-tool.js").HarnessToolDefinition[]>;
|
|
65
|
-
/**
|
|
66
|
-
* Durable (serialized) metadata for session-scoped dynamic tools.
|
|
67
|
-
* Set on the first step when resolvers run. Read on subsequent steps
|
|
68
|
-
* to reconstruct tool definitions with lazy execute wrappers.
|
|
69
|
-
*/
|
|
70
61
|
export interface DurableDynamicToolMetadata {
|
|
71
62
|
readonly name: string;
|
|
72
63
|
readonly description: string;
|
|
73
|
-
readonly inputSchema:
|
|
64
|
+
readonly inputSchema: JsonObject;
|
|
74
65
|
readonly resolverSlug: string;
|
|
75
66
|
readonly entryKey: string;
|
|
76
|
-
/**
|
|
77
|
-
* Name of the hoisted execute step function (e.g.
|
|
78
|
-
* `__ash_dynamic_exec_0`). Used to look up the registered step
|
|
79
|
-
* function via `getStepFunction` on replay.
|
|
80
|
-
*/
|
|
81
67
|
readonly executeStepFnName?: string;
|
|
82
|
-
/**
|
|
83
|
-
* Serialized closure variables captured from the resolver scope on
|
|
84
|
-
* the first run. Passed as the `__vars` parameter to the hoisted
|
|
85
|
-
* step function on replay.
|
|
86
|
-
*/
|
|
87
68
|
readonly closureVars?: Record<string, unknown>;
|
|
88
69
|
}
|
|
89
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Session-scoped dynamic tool metadata (from `session.started`).
|
|
72
|
+
* Persists for the session lifetime.
|
|
73
|
+
*/
|
|
74
|
+
export declare const SessionDynamicToolMetadataKey: ContextKey<readonly DurableDynamicToolMetadata[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Turn-scoped dynamic tool metadata (from `turn.started`).
|
|
77
|
+
* Replaced each turn.
|
|
78
|
+
*/
|
|
79
|
+
export declare const TurnDynamicToolMetadataKey: ContextKey<readonly DurableDynamicToolMetadata[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Virtual (non-serialized) live step-scoped tool definitions from
|
|
82
|
+
* `step.started` resolvers. Carries original execute closures so
|
|
83
|
+
* framework tools (which lack bundler step-function metadata) work.
|
|
84
|
+
* Re-resolved every step — no cross-step persistence needed.
|
|
85
|
+
*/
|
|
86
|
+
export declare const LiveStepToolsKey: ContextKey<import("#harness/execute-tool.js").HarnessToolDefinition[]>;
|
|
90
87
|
/**
|
|
91
88
|
* Durable metadata for one session-scoped dynamic skill.
|
|
92
89
|
*/
|
|
@@ -100,3 +97,13 @@ export interface DurableDynamicSkillMetadata {
|
|
|
100
97
|
* and rebuild the model-visible announcement across turns.
|
|
101
98
|
*/
|
|
102
99
|
export declare const DynamicSkillManifestKey: ContextKey<Record<string, readonly DurableDynamicSkillMetadata[]>>;
|
|
100
|
+
/**
|
|
101
|
+
* Durable session-scoped instruction messages (from `session.started`
|
|
102
|
+
* resolvers). Keyed by resolver slug. Persists for the session lifetime.
|
|
103
|
+
*/
|
|
104
|
+
export declare const SessionDynamicInstructionsKey: ContextKey<Record<string, readonly SystemModelMessage[]>>;
|
|
105
|
+
/**
|
|
106
|
+
* Durable turn-scoped instruction messages (from `turn.started`
|
|
107
|
+
* resolvers). Keyed by resolver slug. Replaced each turn.
|
|
108
|
+
*/
|
|
109
|
+
export declare const TurnDynamicInstructionsKey: ContextKey<Record<string, readonly SystemModelMessage[]>>;
|
package/dist/src/context/keys.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ContextKey}from"#context/key.js";const AuthKey=new ContextKey(`ash.auth`),InitiatorAuthKey=new ContextKey(`ash.initiatorAuth`),SessionIdKey=new ContextKey(`ash.sessionId`),ContinuationTokenKey=new ContextKey(`ash.continuationToken`),ChannelInstrumentationKey=new ContextKey(`ash.channelInstrumentation`),ModeKey=new ContextKey(`ash.mode`),ParentSessionKey=new ContextKey(`ash.parentSession`),CapabilitiesKey=new ContextKey(`ash.capabilities`),SessionCallbackKey=new ContextKey(`ash.sessionCallback`),SessionPreparedKey=new ContextKey(`ash.sessionPrepared`),SessionKey=new ContextKey(`ash.session`),SandboxKey=new ContextKey(`ash.sandbox`),
|
|
1
|
+
import{ContextKey}from"#context/key.js";const AuthKey=new ContextKey(`ash.auth`),InitiatorAuthKey=new ContextKey(`ash.initiatorAuth`),SessionIdKey=new ContextKey(`ash.sessionId`),ContinuationTokenKey=new ContextKey(`ash.continuationToken`),ChannelInstrumentationKey=new ContextKey(`ash.channelInstrumentation`),ModeKey=new ContextKey(`ash.mode`),ParentSessionKey=new ContextKey(`ash.parentSession`),CapabilitiesKey=new ContextKey(`ash.capabilities`),SessionCallbackKey=new ContextKey(`ash.sessionCallback`),SessionPreparedKey=new ContextKey(`ash.sessionPrepared`),SessionKey=new ContextKey(`ash.session`),SandboxKey=new ContextKey(`ash.sandbox`),SessionDynamicToolMetadataKey=new ContextKey(`ash.sessionDynamicToolMetadata`),TurnDynamicToolMetadataKey=new ContextKey(`ash.turnDynamicToolMetadata`),LiveStepToolsKey=new ContextKey(`ash.liveStepTools`),DynamicSkillManifestKey=new ContextKey(`ash.dynamicSkillManifest`),SessionDynamicInstructionsKey=new ContextKey(`ash.sessionDynamicInstructions`),TurnDynamicInstructionsKey=new ContextKey(`ash.turnDynamicInstructions`);export{AuthKey,CapabilitiesKey,ChannelInstrumentationKey,ContinuationTokenKey,DynamicSkillManifestKey,InitiatorAuthKey,LiveStepToolsKey,ModeKey,ParentSessionKey,SandboxKey,SessionCallbackKey,SessionDynamicInstructionsKey,SessionDynamicToolMetadataKey,SessionIdKey,SessionKey,SessionPreparedKey,TurnDynamicInstructionsKey,TurnDynamicToolMetadataKey};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { RuntimeCompiledArtifactsSource } from "#runtime/compiled-artifacts-source.js";
|
|
2
2
|
import { type DurableSessionSnapshot, type DurableSessionState } from "#execution/durable-session-store.js";
|
|
3
|
+
import type { JsonObject } from "#shared/json.js";
|
|
3
4
|
/**
|
|
4
5
|
* Result returned by {@link createSessionStep}.
|
|
5
6
|
*
|
|
@@ -30,6 +31,7 @@ export declare function createSessionStep(input: {
|
|
|
30
31
|
* spends a standalone `__builtin_set_attributes` step.
|
|
31
32
|
*/
|
|
32
33
|
readonly inputMessage: unknown;
|
|
34
|
+
readonly outputSchema?: JsonObject;
|
|
33
35
|
readonly nodeId?: string;
|
|
34
36
|
readonly rootSessionId?: string;
|
|
35
37
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{writeDurableSession}from"#execution/durable-session-store.js";import{createSession}from"#execution/session.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentSessionId}from"#execution/ash-workflow-attributes.js";import{setAshAttributes}from"#runtime/attributes/emit.js";async function createSessionStep(e){"use step";let t=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId}),n=await writeDurableSession({session:createSession({compactionOverrides:{thresholdPercent:t.resolvedAgent.config.compaction?.thresholdPercent},continuationToken:e.continuationToken,rootSessionId:e.rootSessionId,sessionId:e.sessionId,turnAgent:t.turnAgent}),writable:e.sessionWritable}),r={nodeId:t.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},i=readParentSessionId(e.serializedContext);return i===void 0?await setAshAttributes(buildSessionAttributes({inputMessage:e.inputMessage,serializedContext:e.serializedContext})):await setAshAttributes(buildSubagentRootAttributes({identity:r,parentSessionId:i,rootSessionId:e.rootSessionId??i,serializedContext:e.serializedContext})),{state:n}}export{createSessionStep};
|
|
1
|
+
import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{writeDurableSession}from"#execution/durable-session-store.js";import{createSession}from"#execution/session.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentSessionId}from"#execution/ash-workflow-attributes.js";import{setAshAttributes}from"#runtime/attributes/emit.js";async function createSessionStep(e){"use step";let t=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId}),n=await writeDurableSession({session:createSession({compactionOverrides:{thresholdPercent:t.resolvedAgent.config.compaction?.thresholdPercent},continuationToken:e.continuationToken,outputSchema:e.outputSchema,rootSessionId:e.rootSessionId,sessionId:e.sessionId,turnAgent:t.turnAgent}),writable:e.sessionWritable}),r={nodeId:t.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},i=readParentSessionId(e.serializedContext);return i===void 0?await setAshAttributes(buildSessionAttributes({inputMessage:e.inputMessage,serializedContext:e.serializedContext})):await setAshAttributes(buildSubagentRootAttributes({identity:r,parentSessionId:i,rootSessionId:e.rootSessionId??i,serializedContext:e.serializedContext})),{state:n}}export{createSessionStep};
|
|
@@ -19,6 +19,7 @@ import type { ModelMessage } from "ai";
|
|
|
19
19
|
import { type HarnessEmissionState } from "#harness/emission.js";
|
|
20
20
|
import type { HarnessSession, SessionStateMap } from "#harness/types.js";
|
|
21
21
|
import type { SandboxState } from "#sandbox/state.js";
|
|
22
|
+
import type { JsonObject } from "#shared/json.js";
|
|
22
23
|
/** Workflow stream namespace where every session snapshot lands. */
|
|
23
24
|
export declare const ASH_SESSION_STREAM_NAMESPACE = "ash.session";
|
|
24
25
|
/** Current wire version for {@link DurableSessionState} and {@link DurableSessionSnapshot}. */
|
|
@@ -65,6 +66,7 @@ export interface DurableSession {
|
|
|
65
66
|
readonly rootSessionId?: string;
|
|
66
67
|
readonly continuationToken: string;
|
|
67
68
|
readonly history: ModelMessage[];
|
|
69
|
+
readonly outputSchema?: JsonObject;
|
|
68
70
|
readonly state?: SessionStateMap;
|
|
69
71
|
readonly sandboxState?: SandboxState;
|
|
70
72
|
readonly agent: {
|
|
@@ -16,6 +16,7 @@ import type { DurableSessionState } from "#execution/durable-session-store.js";
|
|
|
16
16
|
export type NextDriverAction = {
|
|
17
17
|
readonly kind: "done";
|
|
18
18
|
readonly output: string;
|
|
19
|
+
readonly isError?: boolean;
|
|
19
20
|
readonly sessionState: DurableSessionState;
|
|
20
21
|
readonly serializedContext: Record<string, unknown>;
|
|
21
22
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createAshCallbackRoutePath}from"#protocol/routes.js";import{ASH_SESSION_ID_HEADER}from"#protocol/message.js";import{createWorkflowCallbackUrl}from"#execution/workflow-callback-url.js";import{formatSubagentInvocation}from"#execution/subagent-invocation.js";async function startRemoteAgentSession(n){let r=n.session.continuationToken;if(!r)throw Error(`Cannot dispatch remote agent without a parent continuation token.`);if(!n.callbackBaseUrl)throw Error(`Cannot dispatch remote agent without a callback base URL.`);let i=await resolveRemoteAgentRequestHeaders(n.remote),a=await fetch(createRemoteAgentSessionUrl(n.remote),{body:JSON.stringify({callback:{callId:n.action.callId,subagentName:n.action.remoteAgentName,token:r,url:createWorkflowCallbackUrl(n.callbackBaseUrl,createAshCallbackRoutePath(r))},message:formatRemoteAgentCallInputMessage(n.action),mode:`task
|
|
1
|
+
import{createAshCallbackRoutePath}from"#protocol/routes.js";import{ASH_SESSION_ID_HEADER}from"#protocol/message.js";import{createWorkflowCallbackUrl}from"#execution/workflow-callback-url.js";import{formatSubagentInvocation}from"#execution/subagent-invocation.js";async function startRemoteAgentSession(n){let r=n.session.continuationToken;if(!r)throw Error(`Cannot dispatch remote agent without a parent continuation token.`);if(!n.callbackBaseUrl)throw Error(`Cannot dispatch remote agent without a callback base URL.`);let i=await resolveRemoteAgentRequestHeaders(n.remote),a=await fetch(createRemoteAgentSessionUrl(n.remote),{body:JSON.stringify({callback:{callId:n.action.callId,subagentName:n.action.remoteAgentName,token:r,url:createWorkflowCallbackUrl(n.callbackBaseUrl,createAshCallbackRoutePath(r))},message:formatRemoteAgentCallInputMessage(n.action),mode:`task`,outputSchema:n.remote.outputSchema}),headers:{"content-type":`application/json`,...i},method:`POST`});if(!a.ok)throw Error(`Remote agent "${n.action.remoteAgentName}" create-session request failed with HTTP ${a.status}.`);let o=a.headers.get(ASH_SESSION_ID_HEADER);if(o!==null&&o.length>0)return o;try{let e=await a.json();if(typeof e.sessionId==`string`&&e.sessionId.length>0)return e.sessionId}catch{}throw Error(`Remote agent "${n.action.remoteAgentName}" create-session response did not include a session id.`)}function resolveRemoteAgentForAction(e){let t=e.registry.get(e.nodeId)?.definition;if(t?.kind!==`remote`)throw Error(`Missing remote agent "${e.remoteAgentName}" in runtime registry.`);return t}function createRemoteAgentSessionUrl(e){return new URL(e.path,`${trimTrailingSlash(e.url)}/`).toString()}async function resolveRemoteAgentRequestHeaders(e){let t={};return e.headers!==void 0&&Object.assign(t,typeof e.headers==`function`?await e.headers():e.headers),e.auth!==void 0&&Object.assign(t,(await e.auth()).headers),t}function formatRemoteAgentCallInputMessage(e){let t=typeof e.input.message==`string`?e.input.message:``;return formatSubagentInvocation({description:e.description,message:t,name:e.remoteAgentName}).message}function trimTrailingSlash(e){return e.endsWith(`/`)?e.slice(0,-1):e}export{resolveRemoteAgentForAction,startRemoteAgentSession};
|
|
@@ -31,6 +31,7 @@ export interface CreateSessionInput {
|
|
|
31
31
|
readonly rootSessionId?: string;
|
|
32
32
|
readonly sessionId: string;
|
|
33
33
|
readonly turnAgent: RuntimeTurnAgent;
|
|
34
|
+
readonly outputSchema?: HarnessSession["outputSchema"];
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
36
37
|
* Creates a fresh {@link HarnessSession}. The only site that derives
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
function createCompactionConfig(e={}){let t=e.thresholdPercent??.9,n={recentWindowSize:10,threshold:e.contextWindowTokens===void 0?1e5:Math.max(1,Math.floor(e.contextWindowTokens*t))};return e.lastKnownInputTokens===void 0?n:{...n,lastKnownInputTokens:e.lastKnownInputTokens,lastKnownPromptMessageCount:e.lastKnownPromptMessageCount}}function createSession(e){let{turnAgent:t}=e,n=createSessionToolDefinitions(t),r={agent:{compactionModelReference:t.compactionModel,modelReference:t.model,system:t.instructions.join(`
|
|
2
2
|
|
|
3
|
-
`),tools:n},compaction:createCompactionConfig({contextWindowTokens:t.model.contextWindowTokens,thresholdPercent:e.compactionOverrides?.thresholdPercent}),continuationToken:e.continuationToken,history:[],sessionId:e.sessionId};return e.rootSessionId!==void 0&&(r.rootSessionId=e.rootSessionId),r}function refreshSessionFromTurnAgent(e){return{...e.session,agent:{compactionModelReference:e.turnAgent.compactionModel,modelReference:e.turnAgent.model,system:e.session.agent.system,tools:createSessionToolDefinitions(e.turnAgent)},compaction:createCompactionConfig({contextWindowTokens:e.turnAgent.model.contextWindowTokens,lastKnownInputTokens:e.session.compaction.lastKnownInputTokens,lastKnownPromptMessageCount:e.session.compaction.lastKnownPromptMessageCount,thresholdPercent:e.compactionOverrides?.thresholdPercent})}}function mintSubagentContinuationToken(e){return`subagent:${e??crypto.randomUUID()}`}function projectToDurableSession(e){let t={agent:{system:e.agent.system},continuationToken:e.continuationToken,history:e.history,sessionId:e.sessionId};return(e.compaction.lastKnownInputTokens!==void 0||e.compaction.lastKnownPromptMessageCount!==void 0)&&(t.compaction={lastKnownInputTokens:e.compaction.lastKnownInputTokens,lastKnownPromptMessageCount:e.compaction.lastKnownPromptMessageCount}),e.rootSessionId!==void 0&&(t.rootSessionId=e.rootSessionId),e.sandboxState!==void 0&&(t.sandboxState=e.sandboxState),e.state!==void 0&&(t.state=e.state),t}function hydrateDurableSession(e){let{durable:t,turnAgent:n}=e,r=createSessionToolDefinitions(n),i={agent:{compactionModelReference:n.compactionModel,modelReference:n.model,system:t.agent.system,tools:r},compaction:createCompactionConfig({contextWindowTokens:n.model.contextWindowTokens,lastKnownInputTokens:t.compaction?.lastKnownInputTokens,lastKnownPromptMessageCount:t.compaction?.lastKnownPromptMessageCount,thresholdPercent:e.compactionOverrides?.thresholdPercent}),continuationToken:t.continuationToken,history:t.history,sessionId:t.sessionId};return t.rootSessionId!==void 0&&(i.rootSessionId=t.rootSessionId),t.sandboxState!==void 0&&(i.sandboxState=t.sandboxState),t.state!==void 0&&(i.state=t.state),i}function createSessionToolDefinitions(e){return e.tools.map(e=>({description:e.description??``,inputSchema:e.inputSchema,name:e.name}))}export{createCompactionConfig,createSession,hydrateDurableSession,mintSubagentContinuationToken,projectToDurableSession,refreshSessionFromTurnAgent};
|
|
3
|
+
`),tools:n},compaction:createCompactionConfig({contextWindowTokens:t.model.contextWindowTokens,thresholdPercent:e.compactionOverrides?.thresholdPercent}),continuationToken:e.continuationToken,history:[],sessionId:e.sessionId};return e.rootSessionId!==void 0&&(r.rootSessionId=e.rootSessionId),e.outputSchema!==void 0&&(r.outputSchema=e.outputSchema),r}function refreshSessionFromTurnAgent(e){return{...e.session,agent:{compactionModelReference:e.turnAgent.compactionModel,modelReference:e.turnAgent.model,system:e.session.agent.system,tools:createSessionToolDefinitions(e.turnAgent)},compaction:createCompactionConfig({contextWindowTokens:e.turnAgent.model.contextWindowTokens,lastKnownInputTokens:e.session.compaction.lastKnownInputTokens,lastKnownPromptMessageCount:e.session.compaction.lastKnownPromptMessageCount,thresholdPercent:e.compactionOverrides?.thresholdPercent})}}function mintSubagentContinuationToken(e){return`subagent:${e??crypto.randomUUID()}`}function projectToDurableSession(e){let t={agent:{system:e.agent.system},continuationToken:e.continuationToken,history:e.history,sessionId:e.sessionId};return(e.compaction.lastKnownInputTokens!==void 0||e.compaction.lastKnownPromptMessageCount!==void 0)&&(t.compaction={lastKnownInputTokens:e.compaction.lastKnownInputTokens,lastKnownPromptMessageCount:e.compaction.lastKnownPromptMessageCount}),e.rootSessionId!==void 0&&(t.rootSessionId=e.rootSessionId),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.sandboxState!==void 0&&(t.sandboxState=e.sandboxState),e.state!==void 0&&(t.state=e.state),t}function hydrateDurableSession(e){let{durable:t,turnAgent:n}=e,r=createSessionToolDefinitions(n),i={agent:{compactionModelReference:n.compactionModel,modelReference:n.model,system:t.agent.system,tools:r},compaction:createCompactionConfig({contextWindowTokens:n.model.contextWindowTokens,lastKnownInputTokens:t.compaction?.lastKnownInputTokens,lastKnownPromptMessageCount:t.compaction?.lastKnownPromptMessageCount,thresholdPercent:e.compactionOverrides?.thresholdPercent}),continuationToken:t.continuationToken,history:t.history,sessionId:t.sessionId};return t.rootSessionId!==void 0&&(i.rootSessionId=t.rootSessionId),t.outputSchema!==void 0&&(i.outputSchema=t.outputSchema),t.sandboxState!==void 0&&(i.sandboxState=t.sandboxState),t.state!==void 0&&(i.state=t.state),i}function createSessionToolDefinitions(e){return e.tools.map(e=>({description:e.description??``,inputSchema:e.inputSchema,name:e.name}))}export{createCompactionConfig,createSession,hydrateDurableSession,mintSubagentContinuationToken,projectToDurableSession,refreshSessionFromTurnAgent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{normalizeSerializableError}from"#execution/workflow-errors.js";import{turnStep}from"#execution/workflow-steps.js";async function turnWorkflow(n){"use workflow";let r=n.sessionState,i=n.serializedContext,a=n.delivery,o=n.parentWritable,s=n.sessionWritable;try{for(;;){let e=await turnStep({input:a,parentWritable:o,serializedContext:i,sessionState:r,sessionWritable:s});if(r=e.sessionState,i=e.serializedContext,e.action===`done`){await notifyDriverStep({completionToken:n.completionToken,payload:{action:{kind:`done`,output:e.output??``,serializedContext:i,sessionState:r},kind:`turn-result`}});return}if(e.action===`park`){let t=e.pendingRuntimeActionKeys;if(!(t!==void 0||e.hasPendingAuthorization||e.hasPendingInputBatch&&n.capabilities?.requestInput===!0||n.mode===`conversation`))throw Error("Task mode cannot wait for follow-up input (`next: null`).");let a=t===void 0?{kind:`park`,serializedContext:i,sessionState:r,authorizationNames:e.authorizationNames}:{kind:`dispatch-runtime-actions`,pendingActionKeys:t,serializedContext:i,sessionState:r};await notifyDriverStep({completionToken:n.completionToken,payload:{action:a,kind:`turn-result`}});return}a=void 0}}catch(t){throw await notifyDriverStep({completionToken:n.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}async function notifyDriverStep(e){"use step";let{resumeHook:t}=await import(`#compiled/@workflow/core/runtime.js`);await t(e.completionToken,e.payload)}export{notifyDriverStep,turnWorkflow};
|
|
1
|
+
import{normalizeSerializableError}from"#execution/workflow-errors.js";import{turnStep}from"#execution/workflow-steps.js";async function turnWorkflow(n){"use workflow";let r=n.sessionState,i=n.serializedContext,a=n.delivery,o=n.parentWritable,s=n.sessionWritable;try{for(;;){let e=await turnStep({input:a,parentWritable:o,serializedContext:i,sessionState:r,sessionWritable:s});if(r=e.sessionState,i=e.serializedContext,e.action===`done`){await notifyDriverStep({completionToken:n.completionToken,payload:{action:{kind:`done`,output:e.output??``,isError:e.isError,serializedContext:i,sessionState:r},kind:`turn-result`}});return}if(e.action===`park`){let t=e.pendingRuntimeActionKeys;if(!(t!==void 0||e.hasPendingAuthorization||e.hasPendingInputBatch&&n.capabilities?.requestInput===!0||n.mode===`conversation`))throw Error("Task mode cannot wait for follow-up input (`next: null`).");let a=t===void 0?{kind:`park`,serializedContext:i,sessionState:r,authorizationNames:e.authorizationNames}:{kind:`dispatch-runtime-actions`,pendingActionKeys:t,serializedContext:i,sessionState:r};await notifyDriverStep({completionToken:n.completionToken,payload:{action:a,kind:`turn-result`}});return}a=void 0}}catch(t){throw await notifyDriverStep({completionToken:n.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}async function notifyDriverStep(e){"use step";let{resumeHook:t}=await import(`#compiled/@workflow/core/runtime.js`);await t(e.completionToken,e.payload)}export{notifyDriverStep,turnWorkflow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ASH_SESSION_STREAM_NAMESPACE}from"#execution/durable-session-store.js";import{readRootSessionId}from"#execution/ash-workflow-attributes.js";import{accumulateRuntimeActionResults}from"#harness/runtime-actions.js";import{resolveVercelProductionCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{normalizeSerializableError,rebuildSerializableError}from"#execution/workflow-errors.js";import{dispatchTurnStep,emitTerminalSessionFailureStep,routeProxiedDeliverStep,runProxyInputRequestStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{coalesceDeliveries}from"#harness/messages.js";import{notifyDelegatedParentStep}from"#execution/delegated-parent-notification.js";import{createDelegatedSubagentErrorResult,createDelegatedSubagentSuccessResult}from"#execution/delegated-parent-result.js";import{createSessionStep}from"#execution/create-session-step.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{fireSessionCallbackStep}from"#execution/session-callback-step.js";async function workflowEntry(n){"use workflow";let{workflowRunId:r}=getWorkflowMetadata(),a=n.serializedContext[`ash.continuationToken`]||``,o=n.serializedContext[`ash.mode`],c=n.serializedContext[`ash.capabilities`],l=n.serializedContext[`ash.bundle`];n.serializedContext[`ash.sessionId`]=r;let u=getWritable(),d=getWritable({namespace:ASH_SESSION_STREAM_NAMESPACE});try{let e=readRootSessionId(n.serializedContext),{state:i}=await createSessionStep({compiledArtifactsSource:l.source,continuationToken:a,inputMessage:n.input.message,nodeId:l.nodeId,rootSessionId:e,serializedContext:n.serializedContext,sessionId:r,sessionWritable:d});return await runDriverLoop({capabilities:c,driverWritable:u,initialInput:{kind:`deliver`,payloads:[{message:n.input.message,
|
|
1
|
+
import{ASH_SESSION_STREAM_NAMESPACE}from"#execution/durable-session-store.js";import{readRootSessionId}from"#execution/ash-workflow-attributes.js";import{accumulateRuntimeActionResults}from"#harness/runtime-actions.js";import{resolveVercelProductionCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{normalizeSerializableError,rebuildSerializableError}from"#execution/workflow-errors.js";import{dispatchTurnStep,emitTerminalSessionFailureStep,routeProxiedDeliverStep,runProxyInputRequestStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{coalesceDeliveries}from"#harness/messages.js";import{notifyDelegatedParentStep}from"#execution/delegated-parent-notification.js";import{createDelegatedSubagentErrorResult,createDelegatedSubagentSuccessResult}from"#execution/delegated-parent-result.js";import{createSessionStep}from"#execution/create-session-step.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{fireSessionCallbackStep}from"#execution/session-callback-step.js";async function workflowEntry(n){"use workflow";let{workflowRunId:r}=getWorkflowMetadata(),a=n.serializedContext[`ash.continuationToken`]||``,o=n.serializedContext[`ash.mode`],c=n.serializedContext[`ash.capabilities`],l=n.serializedContext[`ash.bundle`];n.serializedContext[`ash.sessionId`]=r;let u=getWritable(),d=getWritable({namespace:ASH_SESSION_STREAM_NAMESPACE});try{let e=readRootSessionId(n.serializedContext),{state:i}=await createSessionStep({compiledArtifactsSource:l.source,continuationToken:a,inputMessage:n.input.message,nodeId:l.nodeId,outputSchema:n.input.outputSchema,rootSessionId:e,serializedContext:n.serializedContext,sessionId:r,sessionWritable:d});return await runDriverLoop({capabilities:c,driverWritable:u,initialInput:{kind:`deliver`,payloads:[{message:n.input.message,context:n.input.context,outputSchema:n.input.outputSchema}]},mode:o,serializedContext:n.serializedContext,sessionState:i,sessionWritable:d})}catch(e){throw await emitTerminalSessionFailureStep({error:normalizeSerializableError(e),parentWritable:u,serializedContext:n.serializedContext}),await fireSessionCallbackStep({error:normalizeSerializableError(e),serializedContext:n.serializedContext,status:`failed`}),await notifyDelegatedParentStep({result:createDelegatedSubagentErrorResult(n.serializedContext,e),serializedContext:n.serializedContext}),e}}async function runDriverLoop(e){let t=createHook({token:`${e.sessionState.sessionId}:auth`}),n=t[Symbol.asyncIterator](),i=e.sessionState.continuationToken,a=createHook({token:i}),o=a[Symbol.asyncIterator](),s=null,c=[],getNextPromise=()=>(s??=o.next(),s),consumeNext=()=>{s=null},rekeyHook=async e=>{e===i||!e||(await closeHookIterator(o),await disposeHook(a),i=e,a=createHook({token:i}),o=a[Symbol.asyncIterator](),s=null)},l=await dispatchAndAwaitTurn({capabilities:e.capabilities,delivery:e.initialInput,mode:e.mode,parentWritable:e.driverWritable,serializedContext:e.serializedContext,sessionState:e.sessionState,sessionWritable:e.sessionWritable});if(l.kind===`done`)return await closeHookIterator(n),await disposeHook(t),await closeHookIterator(o),await disposeHook(a),await finalizeDone({action:l,driverWritable:e.driverWritable});if(!l.sessionState.continuationToken)throw Error("Cannot park: no continuation token available. The channel must post the first message during the initial turn (anchoring the session) or `send()` must be called with an explicit continuationToken.");await rekeyHook(l.sessionState.continuationToken);try{for(;;)switch(l.kind){case`done`:return await finalizeDone({action:l,driverWritable:e.driverWritable});case`dispatch-runtime-actions`:{let t=await dispatchRuntimeActionsStep({callbackBaseUrl:resolveVercelProductionCallbackBaseUrl()??getWorkflowMetadata().url,parentWritable:e.driverWritable,serializedContext:l.serializedContext,sessionState:l.sessionState,sessionWritable:e.sessionWritable}),n=await waitForPendingRuntimeActionResults({bufferedDeliveries:c,consumeNext,getNextPromise,initialResults:t.results,parentWritable:e.driverWritable,pendingActionKeys:l.pendingActionKeys,rekeyHook,serializedContext:l.serializedContext,sessionState:t.sessionState,sessionWritable:e.sessionWritable});if(n===null)return{output:``};l=await dispatchAndAwaitTurn({capabilities:e.capabilities,delivery:{kind:`runtime-action-result`,results:n.results},mode:e.mode,parentWritable:e.driverWritable,serializedContext:n.serializedContext,sessionState:n.sessionState,sessionWritable:e.sessionWritable}),await rekeyHook(l.sessionState.continuationToken);break}case`park`:{if(l.authorizationNames&&l.authorizationNames.length>0){let t=l.authorizationNames.length,r=[];for(;r.length<t;){let e=await n.next();if(e.done)break;e.value.kind===`deliver`&&r.push(...e.value.payloads)}l=await dispatchAndAwaitTurn({capabilities:e.capabilities,delivery:{kind:`deliver`,payloads:r},mode:e.mode,parentWritable:e.driverWritable,serializedContext:l.serializedContext,sessionState:l.sessionState,sessionWritable:e.sessionWritable}),await rekeyHook(l.sessionState.continuationToken);break}let t=await waitForNextDeliver({bufferedDeliveries:c,consumeNext,getNextPromise});if(t===null)return{output:``};let r=await routeDeliverForChildren({auth:t.auth,parentWritable:e.driverWritable,payloads:t.payloads,sessionState:l.sessionState});if(r===void 0)continue;l=await dispatchAndAwaitTurn({capabilities:e.capabilities,delivery:{auth:t.auth,kind:`deliver`,payloads:[r]},mode:e.mode,parentWritable:e.driverWritable,serializedContext:l.serializedContext,sessionState:l.sessionState,sessionWritable:e.sessionWritable}),await rekeyHook(l.sessionState.continuationToken);break}}}finally{await closeHookIterator(o),await disposeHook(a),await closeHookIterator(n),await disposeHook(t)}}async function finalizeDone(e){let{output:t,serializedContext:n}=e.action,r=e.action.isError===!0;return await fireSessionCallbackStep({error:r?t:void 0,output:r?void 0:t,serializedContext:n,status:r?`failed`:`completed`}),await notifyDelegatedParentStep({result:r?createDelegatedSubagentErrorResult(n,t):createDelegatedSubagentSuccessResult(n,t),serializedContext:n}),{output:t}}async function dispatchAndAwaitTurn(e){let t=createHook(),n=t.token;try{await dispatchTurnStep({capabilities:e.capabilities,completionToken:n,delivery:e.delivery,mode:e.mode,parentWritable:e.parentWritable,serializedContext:e.serializedContext,sessionState:e.sessionState,sessionWritable:e.sessionWritable});let r=await awaitHookPayload(t);if(r.kind===`turn-error`)throw rebuildSerializableError(r.error);return r.action}finally{await disposeHook(t)}}async function awaitHookPayload(e){for await(let t of e)return t;throw Error(`Turn completion hook closed before delivering a result.`)}async function waitForPendingRuntimeActionResults(e){let t=e.sessionState,r=e.serializedContext,i=await accumulateRuntimeActionResults({bufferedDeliveries:e.bufferedDeliveries,async getNext(){for(;;){let n=await e.getNextPromise();if(e.consumeNext(),n.done)return null;let i=n.value;if(i.kind===`deliver`){let n=await routeDeliverForChildren({auth:i.auth,parentWritable:e.parentWritable,payloads:i.payloads,sessionState:t});if(n===void 0)continue;return{kind:`deliver`,value:{...i,payloads:[n]}}}if(i.kind===`runtime-action-result`)return{kind:`runtime-action-result`,results:i.results};let a=await runProxyInputRequestStep({hookPayload:i,parentWritable:e.parentWritable,serializedContext:r,sessionState:t,sessionWritable:e.sessionWritable});t=a.sessionState,r=a.serializedContext,await e.rekeyHook(t.continuationToken)}},initialResults:e.initialResults,pendingActionKeys:e.pendingActionKeys});return i===null?null:{results:i,serializedContext:r,sessionState:t}}async function routeDeliverForChildren(e){let t=coalescePayloads(e.payloads);return e.sessionState.hasProxyInputRequests?(await routeProxiedDeliverStep({auth:e.auth,parentWritable:e.parentWritable,payload:t,sessionState:e.sessionState})).remainder:t}async function waitForNextDeliver(e){if(e.bufferedDeliveries.length>0)return coalesceDeliveries(e.bufferedDeliveries.splice(0));for(;;){let t=await e.getNextPromise();if(e.consumeNext(),t.done)return null;if(t.value.kind!==`deliver`)continue;let n=t.value;for(;;){let t=await takeReadyPayload(e.getNextPromise());if(t===NO_READY_MESSAGE||(e.consumeNext(),t.done))break;t.value.kind===`deliver`&&(n=coalesceDeliveries([n,t.value]))}return n}}function coalescePayloads(e){if(e.length===0)return{};if(e.length===1)return e[0]??{};let t={},n=[];for(let r of e){for(let[e,n]of Object.entries(r))e!==`inputResponses`&&n!==void 0&&(t[e]=n);r.inputResponses!==void 0&&n.push(...r.inputResponses)}return n.length>0&&(t.inputResponses=n),t}const NO_READY_MESSAGE=Symbol(`no-ready-message`);async function takeReadyPayload(e){return await Promise.resolve(),await Promise.race([e,Promise.resolve(NO_READY_MESSAGE)])}async function closeHookIterator(e){typeof e.return==`function`&&await e.return(void 0)}async function disposeHook(e){let t=e.dispose;if(typeof t==`function`){await t.call(e);return}let n=e[Symbol.dispose];typeof n==`function`&&await n.call(e)}export{workflowEntry};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { DeliverPayload, HookPayload, SessionAuthContext, SubagentInputRequestHookPayload } from "#channel/types.js";
|
|
2
2
|
import { deserializeContext } from "#context/serialize.js";
|
|
3
|
-
import type { HarnessSession } from "#harness/types.js";
|
|
3
|
+
import type { HarnessSession, StepInput } from "#harness/types.js";
|
|
4
|
+
import type { JsonObject } from "#shared/json.js";
|
|
5
|
+
import type { RunMode } from "#shared/run-mode.js";
|
|
4
6
|
import { type DurableSessionSnapshot, type DurableSessionState } from "#execution/durable-session-store.js";
|
|
5
7
|
import { type TurnWorkflowInput } from "#execution/turn-workflow.js";
|
|
6
8
|
/**
|
|
@@ -14,6 +16,7 @@ import { type TurnWorkflowInput } from "#execution/turn-workflow.js";
|
|
|
14
16
|
export type DurableStepResult = {
|
|
15
17
|
readonly action: "continue" | "done";
|
|
16
18
|
readonly output?: string;
|
|
19
|
+
readonly isError?: boolean;
|
|
17
20
|
readonly serializedContext: Record<string, unknown>;
|
|
18
21
|
readonly sessionState: DurableSessionState;
|
|
19
22
|
} | {
|
|
@@ -43,6 +46,24 @@ export declare function turnStep(input: TurnStepInput): Promise<DurableStepResul
|
|
|
43
46
|
* token is unchanged.
|
|
44
47
|
*/
|
|
45
48
|
export declare function reconcileSessionContinuationToken(ctx: Awaited<ReturnType<typeof deserializeContext>>, session: HarnessSession): HarnessSession;
|
|
49
|
+
/**
|
|
50
|
+
* Resolves the single output schema in effect for this turn, decoupling schema
|
|
51
|
+
* enforcement from {@link RunMode}: downstream the harness reads
|
|
52
|
+
* `session.outputSchema` unconditionally and never re-derives it from mode.
|
|
53
|
+
*
|
|
54
|
+
* A run-scoped (client-supplied) schema on the turn's {@link StepInput} always
|
|
55
|
+
* wins. With no run-scoped schema, a task run adopts the agent's declared
|
|
56
|
+
* return schema — its function-output contract, which only applies when the
|
|
57
|
+
* agent is invoked as a function (subagent / schedule / job), i.e. task mode.
|
|
58
|
+
* A conversation run with no run-scoped schema enforces nothing. Continuation
|
|
59
|
+
* steps (no new `StepInput`) preserve whatever is already in effect.
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveEffectiveOutputSchema(input: {
|
|
62
|
+
readonly agentOutputSchema: JsonObject | undefined;
|
|
63
|
+
readonly input: StepInput | undefined;
|
|
64
|
+
readonly mode: RunMode;
|
|
65
|
+
readonly session: HarnessSession;
|
|
66
|
+
}): HarnessSession;
|
|
46
67
|
/** Emits a terminal `session.failed` to the adapter and durable stream. */
|
|
47
68
|
export declare function emitTerminalSessionFailureStep(input: {
|
|
48
69
|
readonly error: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ContinuationTokenKey,ModeKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionFailedEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState,isHarnessBetweenTurns}from"#harness/emission.js";import{readDurableSession,writeDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{buildTurnAttributes,readRootSessionId}from"#execution/ash-workflow-attributes.js";import{setAshAttributes}from"#runtime/attributes/emit.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{createWorkflowRuntime,startWorkflowPreferLatest}from"#execution/workflow-runtime.js";import{upsertProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{coalesceTurnInputs}from"#harness/messages.js";import{dispatchStreamEventHooks,runHookLifecycleStep}from"#context/hook-lifecycle.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent}from"#context/dynamic-tool-lifecycle.js";import{runStep,withContextScope}from"#context/run-step.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,getPendingAuthorization}from"#harness/authorization.js";import{createExecutionNodeStep}from"#execution/node-step.js";import{emitProxiedInputRequest,routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{turnWorkflow}from"#execution/turn-workflow.js";async function turnStep(e){"use step";await setAshAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}));let t=await readDurableSession(e.sessionState),o=await deserializeContext(e.serializedContext),l=o.require(ChannelKey),f=o.require(BundleKey),p=hydrateDurableSession({compactionOverrides:{thresholdPercent:f.resolvedAgent.config.compaction?.thresholdPercent},durable:t,turnAgent:f.turnAgent});try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&o.set(CallbackBaseUrlKey,t.url.replace(/\/$/,``))}catch{}let m=getPendingAuthorization(t.state),h;if(m&&e.input?.kind===`deliver`){let t=[],n=[];for(let r of e.input.payloads){let e=r.authorizationCallback;if(e){let n=m.challenges.find(t=>t.name===e.connectionName);n&&t.push({name:n.name,state:n.state,callback:e.request,hookUrl:n.hookUrl})}else n.push(r)}t.length>0&&(o.set(PendingAuthorizationResultKey,t),h=t.map(e=>e.name),e=n.length>0?{...e,input:{...e.input,payloads:n}}:{...e,input:void 0})}e.input?.kind===`deliver`&&e.input.auth!==void 0&&o.set(AuthKey,e.input.auth??null);let g=buildAdapterContext(l,o),_;if(e.input?.kind===`deliver`){let t=[];for(let n of e.input.payloads){let e=l.deliver?await l.deliver(n,g):defaultDeliverResult(n);e!=null&&t.push(e)}_=t.length===0?void 0:t.reduce(coalesceTurnInputs)}else e.input?.kind===`runtime-action-result`&&(_={runtimeActionResults:e.input.results});if(e.input?.kind===`deliver`&&setChannelContext(o,{...l,state:{...g.state}}),e.input?.kind===`deliver`&&_===void 0){let t=reconcileSessionContinuationToken(o,p),n=serializeContext(o),r=t===p?e.sessionState:await writeDurableSession({session:t,writable:e.sessionWritable});return{action:`park`,...derivePendingState(t),serializedContext:n,sessionState:r}}let v=e.parentWritable.getWriter(),y=f.hookRegistry,b=f.resolvedAgent.dynamicInstructionsResolvers??[],x=f.resolvedAgent.dynamicSkillResolvers??[],S=f.resolvedAgent.dynamicToolResolvers??[],emit=async e=>{let t=await callAdapterEventHandler(l,e,g);return setChannelContext(o,{...l,state:{...g.state}}),await v.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t))),t},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:o,registry:y,event:n}),await dispatchDynamicToolEvent({ctx:o,resolvers:S,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:o,resolvers:x,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:o,resolvers:b,event:n,messages:t??[]})},C=await runStep(o,p,async e=>{if(h){let
|
|
1
|
+
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ContinuationTokenKey,ModeKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionFailedEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState,isHarnessBetweenTurns}from"#harness/emission.js";import{readDurableSession,writeDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{buildTurnAttributes,readRootSessionId}from"#execution/ash-workflow-attributes.js";import{setAshAttributes}from"#runtime/attributes/emit.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{createWorkflowRuntime,startWorkflowPreferLatest}from"#execution/workflow-runtime.js";import{upsertProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{coalesceTurnInputs}from"#harness/messages.js";import{dispatchStreamEventHooks,runHookLifecycleStep}from"#context/hook-lifecycle.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent}from"#context/dynamic-tool-lifecycle.js";import{runStep,withContextScope}from"#context/run-step.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,getPendingAuthorization}from"#harness/authorization.js";import{createExecutionNodeStep}from"#execution/node-step.js";import{emitProxiedInputRequest,routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{turnWorkflow}from"#execution/turn-workflow.js";async function turnStep(e){"use step";await setAshAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}));let t=await readDurableSession(e.sessionState),o=await deserializeContext(e.serializedContext),l=o.require(ChannelKey),f=o.require(BundleKey),p=hydrateDurableSession({compactionOverrides:{thresholdPercent:f.resolvedAgent.config.compaction?.thresholdPercent},durable:t,turnAgent:f.turnAgent});try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&o.set(CallbackBaseUrlKey,t.url.replace(/\/$/,``))}catch{}let m=getPendingAuthorization(t.state),h;if(m&&e.input?.kind===`deliver`){let t=[],n=[];for(let r of e.input.payloads){let e=r.authorizationCallback;if(e){let n=m.challenges.find(t=>t.name===e.connectionName);n&&t.push({name:n.name,state:n.state,callback:e.request,hookUrl:n.hookUrl})}else n.push(r)}t.length>0&&(o.set(PendingAuthorizationResultKey,t),h=t.map(e=>e.name),e=n.length>0?{...e,input:{...e.input,payloads:n}}:{...e,input:void 0})}e.input?.kind===`deliver`&&e.input.auth!==void 0&&o.set(AuthKey,e.input.auth??null);let g=buildAdapterContext(l,o),_;if(e.input?.kind===`deliver`){let t=[];for(let n of e.input.payloads){let e=l.deliver?await l.deliver(n,g):defaultDeliverResult(n);e!=null&&t.push(e)}_=t.length===0?void 0:t.reduce(coalesceTurnInputs)}else e.input?.kind===`runtime-action-result`&&(_={runtimeActionResults:e.input.results});if(e.input?.kind===`deliver`&&setChannelContext(o,{...l,state:{...g.state}}),e.input?.kind===`deliver`&&_===void 0){let t=reconcileSessionContinuationToken(o,p),n=serializeContext(o),r=t===p?e.sessionState:await writeDurableSession({session:t,writable:e.sessionWritable});return{action:`park`,...derivePendingState(t),serializedContext:n,sessionState:r}}let v=e.parentWritable.getWriter(),y=f.hookRegistry,b=f.resolvedAgent.dynamicInstructionsResolvers??[],x=f.resolvedAgent.dynamicSkillResolvers??[],S=f.resolvedAgent.dynamicToolResolvers??[],emit=async e=>{let t=await callAdapterEventHandler(l,e,g);return setChannelContext(o,{...l,state:{...g.state}}),await v.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t))),t},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:o,registry:y,event:n}),await dispatchDynamicToolEvent({ctx:o,resolvers:S,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:o,resolvers:x,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:o,resolvers:b,event:n,messages:t??[]})},C=o.require(ModeKey),w=await runStep(o,p,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:f.turnAgent.outputSchema,input:_,mode:C,session:e});if(h){let e=getHarnessEmissionState(t.state);for(let t of h)await handleEvent(createAuthorizationCompletedEvent({name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=o.get(CapabilitiesKey),runHarnessStep=async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:f.resolvedAgent.config.compaction?.thresholdPercent},session:e,turnAgent:f.turnAgent});return createExecutionNodeStep({capabilities:n,compiledArtifactsSource:f.compiledArtifactsSource,createRuntime:createWorkflowRuntime,handleEvent,mode:C,node:f.graph.root})(r,t)};return _!==void 0&&isHarnessBetweenTurns(t)?runHookLifecycleStep({ctx:o,emit:handleEvent,input:_,mode:C,registry:f.hookRegistry,session:t},runHarnessStep):runHarnessStep(t,_)}),T=reconcileSessionContinuationToken(o,w.session),E=serializeContext(o);w={...w,session:T};let D=await writeDurableSession({session:w.session,writable:e.sessionWritable});return w.next!==null&&typeof w.next==`object`&&`done`in w.next?(await v.close(),{action:`done`,output:w.next.output,isError:w.next.isError,serializedContext:E,sessionState:D}):w.next===null?(v.releaseLock(),{action:`park`,...derivePendingState(w.session),serializedContext:E,sessionState:D}):(v.releaseLock(),{action:`continue`,serializedContext:E,sessionState:D})}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function reconcileSessionContinuationToken(e,t){let n=e.get(ContinuationTokenKey);return n===void 0||n===t.continuationToken?t:{...t,continuationToken:n}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}const log=createLogger(`execution.workflow-entry`);async function emitTerminalSessionFailureStep(e){"use step";let r=formatError(e.error),i=typeof r.name==`string`?r.name:`WORKFLOW_EXECUTION_FAILED`,a=typeof r.message==`string`?r.message:String(e.error),o=e.serializedContext[`ash.sessionId`]??``;log.error(`workflow loop threw — emitting terminal session.failed`,{sessionId:o,errorId:typeof r.errorId==`string`?r.errorId:void 0,code:i,message:a,detail:typeof r.detail==`string`?r.detail:void 0});let s=createSessionFailedEvent({code:i,details:r,message:a,sessionId:o});try{let t=await deserializeContext(e.serializedContext),r=t.get(ChannelKey);r!==void 0&&await callAdapterEventHandler(r,s,buildAdapterContext(r,t))}catch(e){log.error(`adapter failed to handle terminal session.failed event`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}try{let t=e.parentWritable.getWriter();try{await t.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(s)))}finally{t.releaseLock()}}catch(e){log.error(`failed to write terminal session.failed event to durable stream`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}}async function runProxyInputRequestStep(e){"use step";let t=await readDurableSession(e.sessionState),r=await deserializeContext(e.serializedContext),i=r.require(ChannelKey),a=buildAdapterContext(i,r),o=r.require(ModeKey),c=r.require(BundleKey),l=hydrateDurableSession({compactionOverrides:{thresholdPercent:c.resolvedAgent.config.compaction?.thresholdPercent},durable:t,turnAgent:c.turnAgent}),u=e.parentWritable.getWriter(),d;try{let emit=async e=>{let t=await callAdapterEventHandler(i,e,a);await u.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t)))};d=await withContextScope(r,l,async t=>{let n=await emitProxiedInputRequest({emit,hookPayload:e.hookPayload,mode:o,session:t});return{result:n.entries,session:n.session}})}finally{u.releaseLock()}return setChannelContext(r,{...i,state:{...a.state}}),{serializedContext:serializeContext(r),sessionState:await writeDurableSession({session:reconcileSessionContinuationToken(r,upsertProxyInputRequests({entries:d.result,forChildContinuationToken:e.hookPayload.childContinuationToken,session:d.session})),writable:e.sessionWritable})}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state}),{resumeHook:r}=await import(`#compiled/@workflow/core/runtime.js`);for(let t of n.forChildren)await r(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return{remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflow,[e])).runId}}export{dispatchTurnStep,emitTerminalSessionFailureStep,reconcileSessionContinuationToken,resolveEffectiveOutputSchema,routeProxiedDeliverStep,runProxyInputRequestStep,turnStep};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{contextStorage}from"#context/container.js";import"ai";import{CODE_MODE_TOOL_NAME,loadCodeModeModule}from"#shared/code-mode.js";import{isAuthorizationSignal}from"#harness/authorization.js";import{CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,markCodeModeToolExecutionOptions,toCodeModeConnectionAuthArgs}from"#runtime/framework-tools/code-mode-connection-auth.js";import{buildDynamicTools}from"#context/build-dynamic-tools.js";import{buildToolSet}from"#harness/tools.js";function createAshCodeModeOptions(e={}){let t={approval:{mode:`interrupt`}};return e.lifecycle!==void 0&&(t.lifecycle=e.lifecycle),t}async function applyCodeModeToToolSet(e){let r={},i={};for(let[t,n]of Object.entries(e.tools)){if(isDirectTool(n,e.harnessTools.get(t))){i[t]=n;continue}r[t]=wrapHostToolForCodeMode(n)}if(Object.keys(r).length>0){let{createCodeModeTool:a}=await loadCodeModeModule();i[CODE_MODE_TOOL_NAME]=a(r,createAshCodeModeOptions({lifecycle:e.lifecycle}))}return{hostTools:r,modelTools:i}}async function buildCodeModeHostTools(t){let n=buildToolSet({approvedTools:t.approvedTools,capabilities:t.capabilities,tools:t.tools}),r=contextStorage.getStore();if(r!==void 0){let e=buildDynamicTools(r);for(let t of e)n[t.name]??={description:t.description,inputSchema:t.inputSchema,execute:t.execute}}return(await applyCodeModeToToolSet({harnessTools:t.tools,tools:n})).hostTools}function isDirectTool(e,t){return e.execute===void 0||t?.runtimeAction!==void 0}function wrapHostToolForCodeMode(e){let t=e.execute,o=e.toModelOutput;return t===void 0?e:{...e,execute:async(e,s)=>{let c=await resolveExecuteOutput(t(e,markCodeModeToolExecutionOptions(s)));if(isAuthorizationSignal(c)){let{requestCodeModeInterrupt:t}=await loadCodeModeModule(),r=c.challenges[0]?.name;r&&t({args:toCodeModeConnectionAuthArgs(e),challenges:c.challenges,connectionName:r,kind:CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND,toolName:``})}if(o===void 0)return c;let l=await o({output:c});return isModelOutput(l)?l.value:l}}}async function resolveExecuteOutput(e){if(isAsyncIterable(e)){let t;for await(let n of e)t=n;return t}return await e}function isAsyncIterable(e){return typeof e==`object`&&!!e&&Symbol.asyncIterator in e&&typeof e[Symbol.asyncIterator]==`function`}function isModelOutput(e){if(typeof e!=`object`||!e)return!1;let t=e;return(t.type===`json`||t.type===`text`)&&Object.hasOwn(t,`value`)}export{applyCodeModeToToolSet,buildCodeModeHostTools,createAshCodeModeOptions};
|