experimental-ash 0.42.0 → 0.44.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 +37 -0
- package/bin/ash.js +1 -0
- package/dist/docs/internals/mechanical-invariants.md +16 -0
- package/dist/docs/public/README.md +8 -8
- package/dist/docs/public/advanced/{auth-and-route-protection.md → auth-and-route-protection.mdx} +11 -0
- package/dist/docs/public/advanced/context-control.md +4 -4
- package/dist/docs/public/advanced/{evals.md → evals.mdx} +11 -1
- package/dist/docs/public/advanced/{hooks.md → hooks.mdx} +28 -40
- package/dist/docs/public/advanced/instrumentation.md +142 -3
- package/dist/docs/public/advanced/project-layout.md +5 -5
- package/dist/docs/public/advanced/runs-and-streaming.md +8 -2
- package/dist/docs/public/advanced/session-context.md +1 -1
- package/dist/docs/public/advanced/typescript-api.md +50 -7
- package/dist/docs/public/advanced/vercel-deployment.md +1 -1
- package/dist/docs/public/agent-ts.md +5 -5
- package/dist/docs/public/channels/{discord.md → discord.mdx} +11 -0
- package/dist/docs/public/channels/index.md +10 -10
- package/dist/docs/public/channels/{slack.md → slack.mdx} +11 -0
- package/dist/docs/public/channels/{teams.md → teams.mdx} +12 -0
- package/dist/docs/public/channels/{telegram.md → telegram.mdx} +11 -0
- package/dist/docs/public/channels/{twilio.md → twilio.mdx} +11 -0
- package/dist/docs/public/{connections.md → connections.mdx} +18 -6
- package/dist/docs/public/frontend/README.md +16 -0
- package/dist/docs/public/frontend/meta.json +3 -0
- package/dist/docs/public/frontend/nextjs.md +192 -0
- package/dist/docs/public/frontend/use-ash-agent.md +332 -0
- package/dist/docs/public/{getting-started.md → getting-started.mdx} +12 -1
- package/dist/docs/public/{human-in-the-loop.md → human-in-the-loop.mdx} +12 -1
- package/dist/docs/public/meta.json +1 -0
- package/dist/docs/public/sandbox.md +39 -1
- package/dist/docs/public/{schedules.md → schedules.mdx} +9 -0
- package/dist/docs/public/skills.md +2 -2
- package/dist/docs/public/{subagents.md → subagents.mdx} +10 -0
- package/dist/docs/public/{tools.md → tools.mdx} +41 -26
- package/dist/src/channel/adapter.d.ts +13 -0
- package/dist/src/channel/compiled-channel.d.ts +4 -1
- package/dist/src/channel/compiled-channel.js +1 -1
- package/dist/src/channel/instrumentation.d.ts +10 -0
- package/dist/src/channel/instrumentation.js +1 -0
- package/dist/src/channel/routes.d.ts +8 -10
- package/dist/src/channel/send.js +1 -1
- package/dist/src/channel/types.d.ts +16 -0
- package/dist/src/cli/commands/channels.d.ts +2 -1
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +12 -19
- package/dist/src/compiled/@vercel/sandbox/network-policy.d.ts +161 -0
- package/dist/src/compiled/just-bash/index.d.ts +15 -2
- package/dist/src/compiled/just-bash/network/types.d.ts +155 -0
- package/dist/src/compiler/artifacts.d.ts +1 -0
- package/dist/src/compiler/artifacts.js +1 -1
- package/dist/src/compiler/channel-instrumentation-types.d.ts +8 -0
- package/dist/src/compiler/channel-instrumentation-types.js +2 -0
- package/dist/src/compiler/manifest.d.ts +13 -1
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/module-map.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/normalize-skill.d.ts +15 -2
- package/dist/src/compiler/normalize-skill.js +1 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/dynamic-skill-lifecycle.d.ts +23 -0
- package/dist/src/context/dynamic-skill-lifecycle.js +1 -0
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +2 -0
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/hook-lifecycle.d.ts +4 -6
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +6 -4
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/providers/connection.d.ts +9 -0
- package/dist/src/context/providers/connection.js +1 -1
- package/dist/src/context/providers/sandbox.js +1 -1
- package/dist/src/execution/ash-workflow-attributes.d.ts +118 -0
- package/dist/src/execution/ash-workflow-attributes.js +1 -0
- package/dist/src/execution/channel-context.d.ts +5 -0
- package/dist/src/execution/channel-context.js +1 -0
- package/dist/src/execution/create-session-step.d.ts +28 -1
- package/dist/src/execution/create-session-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/durable-session-store.d.ts +7 -0
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/bindings/local.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/prewarm.js +1 -1
- package/dist/src/execution/sandbox/session.d.ts +6 -1
- package/dist/src/execution/sandbox/session.js +1 -1
- package/dist/src/execution/session.d.ts +6 -0
- package/dist/src/execution/session.js +2 -2
- package/dist/src/execution/skills/instructions.d.ts +3 -2
- package/dist/src/execution/subagent-tool.js +1 -1
- package/dist/src/execution/workflow-entry.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 +0 -5
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/emission.d.ts +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/instrumentation-config.d.ts +1 -1
- package/dist/src/harness/instrumentation-metadata.d.ts +23 -0
- package/dist/src/harness/instrumentation-metadata.js +1 -0
- package/dist/src/harness/otel-integration.d.ts +2 -2
- package/dist/src/harness/otel-integration.js +1 -1
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/turn-tag-state.d.ts +50 -0
- package/dist/src/harness/turn-tag-state.js +1 -0
- package/dist/src/harness/types.d.ts +11 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.d.ts +0 -1
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/internal/instrumentation.d.ts +39 -0
- package/dist/src/internal/instrumentation.js +1 -0
- package/dist/src/internal/workflow/builtins.d.ts +32 -0
- package/dist/src/internal/workflow/builtins.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +34 -0
- package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-transformer.js +1 -1
- package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
- package/dist/src/packages/ash-scaffold/src/steps/run-add-to-agent.js +2 -2
- package/dist/src/packages/ash-scaffold/src/web-template.js +1 -0
- package/dist/src/public/channels/discord/discordChannel.d.ts +5 -2
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/slack/attachments.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +12 -8
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +5 -2
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +5 -2
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/index.d.ts +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +12 -3
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/definitions/defineChannel.d.ts +17 -4
- package/dist/src/public/definitions/defineChannel.js +1 -1
- package/dist/src/public/definitions/hook.d.ts +3 -11
- package/dist/src/public/definitions/instrumentation.d.ts +1 -66
- package/dist/src/public/definitions/instrumentation.js +1 -1
- package/dist/src/public/definitions/skill.d.ts +5 -0
- package/dist/src/public/definitions/tool.d.ts +25 -66
- package/dist/src/public/definitions/tool.js +1 -1
- package/dist/src/public/instrumentation/index.d.ts +175 -1
- package/dist/src/public/instrumentation/index.js +1 -1
- package/dist/src/public/sandbox/index.d.ts +1 -0
- package/dist/src/public/skills/index.d.ts +2 -0
- package/dist/src/public/skills/index.js +1 -1
- package/dist/src/public/tools/index.d.ts +2 -2
- package/dist/src/public/tools/index.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +4 -7
- package/dist/src/runtime/agent/mock-model-skill-selection.d.ts +9 -0
- package/dist/src/runtime/agent/mock-model-skill-selection.js +4 -0
- package/dist/src/runtime/attributes/emit.d.ts +73 -0
- package/dist/src/runtime/attributes/emit.js +1 -0
- package/dist/src/runtime/channels/registry.js +1 -1
- package/dist/src/runtime/connections/mcp-client.js +1 -1
- package/dist/src/runtime/framework-tools/code-mode-connection-auth.d.ts +2 -0
- package/dist/src/runtime/framework-tools/connection-search-dynamic.d.ts +34 -0
- package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -0
- package/dist/src/runtime/framework-tools/index.d.ts +7 -5
- package/dist/src/runtime/framework-tools/index.js +1 -1
- package/dist/src/runtime/prompt/connections.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-channel.js +1 -1
- package/dist/src/runtime/resolve-dynamic-skill.d.ts +8 -0
- package/dist/src/runtime/resolve-dynamic-skill.js +1 -0
- package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/runtime/sessions/runtime-context-keys.js +1 -1
- package/dist/src/runtime/types.d.ts +13 -4
- package/dist/src/shared/dynamic-tool-definition.d.ts +51 -76
- package/dist/src/shared/dynamic-tool-definition.js +1 -1
- package/dist/src/shared/guards.d.ts +14 -0
- package/dist/src/shared/guards.js +1 -1
- package/dist/src/shared/sandbox-network-policy.d.ts +23 -0
- package/dist/src/shared/sandbox-network-policy.js +1 -0
- package/dist/src/shared/sandbox-session.d.ts +15 -0
- package/dist/src/shared/skill-definition.d.ts +5 -4
- package/dist/src/shared/tool-definition.d.ts +12 -0
- package/package.json +2 -1
- package/dist/src/runtime/framework-tools/connection-search.d.ts +0 -57
- package/dist/src/runtime/framework-tools/connection-search.js +0 -1
- package/dist/src/runtime/framework-tools/connection-tools.d.ts +0 -55
- package/dist/src/runtime/framework-tools/connection-tools.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{getChannelInstrumentationKind}from"#channel/compiled-channel.js";function defineInstrumentation(e){return e}function isChannel(t,n){return t.kind===getChannelInstrumentationKind(n)}export{defineInstrumentation,isChannel};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { defineSandbox, type SandboxBootstrapContext, type SandboxBootstrapUseFn, type SandboxCommandResult, type SandboxDefinition, type SandboxProcess, type SandboxReadBinaryFileOptions, type SandboxReadFileOptions, type SandboxReadTextFileOptions, type SandboxRunOptions, type SandboxSession, type SandboxSpawnOptions, type SandboxSessionContext, type SandboxSessionUseFn, type SandboxWriteBinaryFileOptions, type SandboxWriteFileOptions, type SandboxWriteTextFileOptions, } from "#public/definitions/sandbox.js";
|
|
6
6
|
export type { SandboxBackend, SandboxBackendCreateInput, SandboxBackendHandle, SandboxBackendPrewarmInput, SandboxBackendRuntimeContext, SandboxBackendSessionState, SandboxSeedFile, } from "#public/definitions/sandbox-backend.js";
|
|
7
|
+
export type { SandboxNetworkPolicy } from "#shared/sandbox-network-policy.js";
|
|
7
8
|
export { SandboxTemplateNotProvisionedError } from "#public/definitions/sandbox-backend.js";
|
|
8
9
|
export { defaultBackend } from "#public/sandbox/backends/default.js";
|
|
9
10
|
export { localBackend } from "#public/sandbox/backends/local.js";
|
|
@@ -3,3 +3,5 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export type { SkillFile, SkillHandle } from "#execution/skills/types.js";
|
|
5
5
|
export { defineSkill, type NamedSkillDefinition, type SkillDefinition, type SkillFileContent, type SkillPackageDefinition, } from "#public/definitions/skill.js";
|
|
6
|
+
export { defineDynamic } from "#public/definitions/tool.js";
|
|
7
|
+
export type { DynamicResolveContext, DynamicSentinel } from "#shared/dynamic-tool-definition.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineSkill}from"#public/definitions/skill.js";export{defineSkill};
|
|
1
|
+
import{defineDynamic}from"#public/definitions/tool.js";import{defineSkill}from"#public/definitions/skill.js";export{defineDynamic,defineSkill};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool authoring helpers for `agent/tools/*.ts` files.
|
|
3
3
|
*/
|
|
4
|
-
export { type CompactionInput, type CompactionHookResult, type DisabledToolSentinel,
|
|
5
|
-
export type { DynamicToolEntry, DynamicToolEvents,
|
|
4
|
+
export { type CompactionInput, type CompactionHookResult, type DisabledToolSentinel, defineDynamic, defineTool, disableTool, isDisabledToolSentinel, type NeedsApprovalContext, type RetentionSummary, type ToolDefinition, type ToolContext, type ToolModelOutput, type ToolRetentionPolicy, } from "#public/definitions/tool.js";
|
|
5
|
+
export type { DynamicToolEntry, DynamicEvents, DynamicToolEvents, DynamicResolveContext, DynamicSentinel, DynamicToolSet, DynamicToolResult, } from "#shared/dynamic-tool-definition.js";
|
|
6
6
|
export { type SessionContext } from "#public/definitions/callback-context.js";
|
|
7
7
|
export { toolResultFrom, type MatchedConnectionResult, type MatchedToolResult, type ToolResultFromFn, } from "#public/tool-result-narrowing.js";
|
|
8
8
|
export { type DefineBashToolInput, defineBashTool } from "#public/tools/define-bash-tool.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineTool,
|
|
1
|
+
import{defineDynamic,defineTool,disableTool,isDisabledToolSentinel}from"#public/definitions/tool.js";import{toolResultFrom}from"#public/tool-result-narrowing.js";import{defineBashTool}from"#public/tools/define-bash-tool.js";import{defineGlobTool}from"#public/tools/define-glob-tool.js";import{defineGrepTool}from"#public/tools/define-grep-tool.js";import{defineReadFileTool}from"#public/tools/define-read-file-tool.js";import{defineWriteFileTool}from"#public/tools/define-write-file-tool.js";export{defineBashTool,defineDynamic,defineGlobTool,defineGrepTool,defineReadFileTool,defineTool,defineWriteFileTool,disableTool,isDisabledToolSentinel,toolResultFrom};
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";import{CODE_MODE_TOOL_NAME}from"#shared/code-mode.js";import{MockLanguageModelV3}from"ai/test";import{BOOTSTRAP_RUNTIME_MODEL_ID,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT}from"#runtime/agent/bootstrap.js";import{createBootstrapGenerateResult,createBootstrapStreamResult,estimateTokenCount,getLastUserPromptText,getPromptContentText,getPromptText}from"#runtime/agent/bootstrap-model-utils.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";const authoredRuntimeModelMocks=new Map,bootstrapWeatherPayloadSchema=z.object({city:z.string(),condition:z.string(),summary:z.string(),temperatureF:z.number().finite()}).strict(),ASH_MOCK_AUTHORED_MODELS_ENV=`ASH_MOCK_AUTHORED_MODELS`;function shouldMockAuthoredRuntimeModels(){return process.env.ASH_MOCK_AUTHORED_MODELS===`1`||process.env.NODE_ENV===`test`}function createMockAuthoredRuntimeModel(e){let t=authoredRuntimeModelMocks.get(e.id);if(t!==void 0)return t;let r=new MockLanguageModelV3({modelId:e.id,provider:`ash-runtime-mock`,doGenerate:async t=>createMockModelResult(t,e.id),doStream:async t=>createBootstrapStreamResult(createMockModelResult(t,e.id))});return authoredRuntimeModelMocks.set(e.id,r),r}function createMockModelResult(e,t){let n=getLastAuthoredToolResult(e.prompt);if(n!==null){let r=formatToolResultReply(n,e.prompt);return createBootstrapGenerateResult({inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{CODE_MODE_TOOL_NAME}from"#shared/code-mode.js";import{MockLanguageModelV3}from"ai/test";import{BOOTSTRAP_RUNTIME_MODEL_ID,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT}from"#runtime/agent/bootstrap.js";import{createBootstrapGenerateResult,createBootstrapStreamResult,estimateTokenCount,getLastUserPromptText,getPromptContentText,getPromptText}from"#runtime/agent/bootstrap-model-utils.js";import{findRelevantSkill,getActivatedSkillIds,getAvailableSkills}from"#runtime/agent/mock-model-skill-selection.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";const authoredRuntimeModelMocks=new Map,bootstrapWeatherPayloadSchema=z.object({city:z.string(),condition:z.string(),summary:z.string(),temperatureF:z.number().finite()}).strict(),ASH_MOCK_AUTHORED_MODELS_ENV=`ASH_MOCK_AUTHORED_MODELS`;function shouldMockAuthoredRuntimeModels(){return process.env.ASH_MOCK_AUTHORED_MODELS===`1`||process.env.NODE_ENV===`test`}function createMockAuthoredRuntimeModel(e){let t=authoredRuntimeModelMocks.get(e.id);if(t!==void 0)return t;let r=new MockLanguageModelV3({modelId:e.id,provider:`ash-runtime-mock`,doGenerate:async t=>createMockModelResult(t,e.id),doStream:async t=>createBootstrapStreamResult(createMockModelResult(t,e.id))});return authoredRuntimeModelMocks.set(e.id,r),r}function createMockModelResult(e,t){let n=getLastAuthoredToolResult(e.prompt);if(n!==null){let r=createFollowUpToolCallResult({modelId:t,options:e,result:n});if(r!==null)return r;let i=formatToolResultReply(n,e.prompt);return createBootstrapGenerateResult({inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(i),text:i})}let r=createSkillLoadResult(e.prompt,t);if(r!==null)return r;let i=createAuthoredToolCallResult(e,t);if(i!==null)return i;let o=createAssistantMessage(e.prompt);return createBootstrapGenerateResult({inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(o),text:o})}function resolveMockAuthoredRuntimeModel(e){return!shouldMockAuthoredRuntimeModels()||e.id===BOOTSTRAP_RUNTIME_MODEL_ID?null:createMockAuthoredRuntimeModel(e)}function createSkillLoadResult(e,t){let n=getLastUserPromptText(e);if(n===null||getActivatedSkillIds(e).length>0)return null;let r=findRelevantSkill(getAvailableSkills(e),n);return r===null?null:createToolCallGenerateResult({input:{skill:r.name},inputTokens:estimateTokenCount(getPromptText(e)),modelId:t,outputTokens:estimateTokenCount(r.name),toolCallId:`call_load_skill`,toolName:LOAD_SKILL_TOOL_NAME})}function createAuthoredToolCallResult(e,n){let r=getLastUserPromptText(e.prompt);if(r===null)return null;let i=findRelevantTool(getAvailableTools(e),r);if(i===null)return null;let a=resolveWeatherCity(r),o=createAuthoredToolInput(i,r,a);if(i.name===CODE_MODE_TOOL_NAME){let t=findRelevantCodeModeHostTool(i.description,r);if(t===null)return null;let o=`return await tools${formatCodeModeToolAccess(t)}({ city: ${JSON.stringify(a)} });`;return createToolCallGenerateResult({input:{js:o},inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:n,outputTokens:estimateTokenCount(o),toolCallId:createToolCallId(i.name),toolName:i.name})}return createToolCallGenerateResult({input:o,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:n,outputTokens:estimateTokenCount(Object.values(o).join(` `)),toolCallId:createToolCallId(i.name),toolName:i.name})}function createFollowUpToolCallResult(e){let t=findNextExplicitToolAfterResult({previousToolName:e.result.toolName,prompt:e.options.prompt,tools:getAvailableTools(e.options)});if(t===null)return null;let n=createFollowUpToolInput(e.result.output);return n===null?null:createToolCallGenerateResult({input:n,inputTokens:estimateTokenCount(getPromptText(e.options.prompt)),modelId:e.modelId,outputTokens:estimateTokenCount(Object.values(n).join(` `)),toolCallId:createToolCallId(t.name),toolName:t.name})}function createAuthoredToolInput(e,t,n){let r=getToolInputPropertyNames(e.inputSchema);return r.includes(`topic`)||/\btopic\b/u.test(normalizeText(t))?{topic:resolveLookupTopic(t)}:r.length===1&&r[0]===`message`?{message:t}:{city:n}}function createAssistantMessage(e){let t=getLastUserPromptText(e)??`Hello from Ash`,n=getSystemPromptLabels(e),r=resolveSystemProbe(e);return n.length>0?r===null?`Bootstrap reply [${n.join(`, `)}]: ${t}`:`Bootstrap reply [${n.join(`, `)}; probe=${r}]: ${t}`:r===null?`Bootstrap reply: ${t}`:`Bootstrap reply [probe=${r}]: ${t}`}function formatToolResultReply(e,t){if(e.isError)return`Local weather tool failed: ${formatToolOutput(e.output)}`;if(isWeatherPayload(e.output))return`Used local weather tool for ${e.output.city}: ${e.output.condition}, ${e.output.temperatureF}F. ${e.output.summary}`;let n=getLastUserPromptText(t)??`Hello from Ash`;return`Used ${e.toolName} for "${n}": ${formatToolOutput(e.output)}`}function createToolCallGenerateResult(e){return{content:[{input:JSON.stringify(e.input),toolCallId:e.toolCallId,toolName:e.toolName,type:`tool-call`}],finishReason:`tool-calls`,response:{id:`bootstrap-response`,modelId:e.modelId,timestamp:new Date(`2026-03-16T00:00:00.000Z`)},usage:{inputTokens:{cacheRead:0,cacheWrite:0,noCache:e.inputTokens,total:e.inputTokens},outputTokens:{reasoning:0,text:e.outputTokens,total:e.outputTokens}},warnings:[]}}function getAvailableTools(e){return(e.tools??[]).flatMap(e=>e.type===`function`?[{description:e.description,inputSchema:`inputSchema`in e?e.inputSchema:void 0,name:e.name}]:[])}function getLastAuthoredToolResult(e){for(let t of[...e].reverse()){if(t.role===`user`)return null;if(!(t.role!==`tool`&&t.role!==`assistant`)){for(let e of[...t.content].reverse())if(!(typeof e==`string`||e.type!==`tool-result`)&&e.toolName!==LOAD_SKILL_TOOL_NAME)return{isError:e.output.type===`error-json`||e.output.type===`error-text`||e.output.type===`execution-denied`,output:e.output.type===`execution-denied`?{reason:e.output.reason??null,type:e.output.type}:e.output.value,toolCallId:e.toolCallId,toolName:e.toolName}}}return null}function findNextExplicitToolAfterResult(e){let t=getLastUserPromptText(e.prompt);if(t===null)return null;let n=normalizeText(t),r=n.indexOf(normalizeText(e.previousToolName));return r<0?null:e.tools.filter(t=>t.name!==e.previousToolName).flatMap(e=>{let t=n.indexOf(normalizeText(e.name),r+1);return t<0?[]:[{index:t,tool:e}]}).sort((e,t)=>e.index-t.index)[0]?.tool??null}function createFollowUpToolInput(e){return isRecord(e)&&typeof e.stepKey==`string`?{stepKey:e.stepKey}:null}function getSystemPromptLabels(e){let t=e.filter(e=>e.role===`system`);if(t.length===0)return[];let n=t.flatMap(e=>{let t=getPromptContentText(e.content);if(t.startsWith(`Available skills
|
|
2
2
|
`))return[];let n=t.split(`
|
|
3
|
-
`).map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of n){if(e===BOOTSTRAP_RUNTIME_SYSTEM_PROMPT||e===`Available skills`)continue;let t=/^System \((.+)\)$/.exec(e);if(t?.[1]){r.push(t[1]);continue}let n=/^Skill \((.+)\)$/.exec(e);n?.[1]&&r.push(n[1])}if(r.length>0)return r;let a=n.find(e=>e!==BOOTSTRAP_RUNTIME_SYSTEM_PROMPT&&e!==`Available skills`);return a===void 0?[]:[a]});return[...new Set(n)]}function
|
|
4
|
-
`)
|
|
5
|
-
`))
|
|
6
|
-
`).slice(1)){let e=parseAvailableSkill(n);e!==null&&t.set(e.name,e)}}return[...t.values()]}function parseAvailableSkill(e){let t=/^- (.+?): (.+?)(?: \(path: (.+)\))?$/.exec(e.trim());return t?.[1]&&t[2]?{description:t[2],name:t[1]}:null}function findRelevantTool(e,t){let n=normalizeText(t);return/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(n)?e.find(e=>/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(normalizeText(`${e.name} ${e.description??``}`)))??null:null}function findRelevantCodeModeHostTool(e,t){return e===void 0?null:findRelevantTool(parseCodeModeHostTools(e),t)?.name??null}function parseCodeModeHostTools(e){let t=[],n;for(let r of e.split(`
|
|
7
|
-
`)){let e=/^\s*\/\*\*\s*(.*?)\s*\*\/\s*$/u.exec(r);if(e?.[1]!==void 0){n=e[1];continue}let i=/^\s*(?:([$A-Z_a-z][$\w]*)|(["'])(.*?)\2)\s*:\s*\(input:/u.exec(r),a=i?.[1]??i?.[3];a!==void 0&&(t.push({description:n,name:a}),n=void 0)}return t}function formatCodeModeToolAccess(e){return/^[$A-Z_a-z][$\w]*$/u.test(e)?`.${e}`:`[${JSON.stringify(e)}]`}function findRelevantSkill(e,t){let n=normalizeText(t);for(let t of e)if(n.includes(normalizeText(t.name)))return t;return/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(n)?e.find(e=>/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(normalizeText(`${e.name} ${e.description}`)))??null:null}function normalizeText(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,` `).trim()}function resolveSystemProbe(e){let t=e.filter(e=>e.role===`system`).map(e=>getPromptContentText(e.content)).join(`
|
|
8
|
-
`);return/hmr-probe:\s*([^\n]+)/iu.exec(t)?.[1]?.trim()||null}function resolveWeatherCity(e){let t=/"city"\s*:\s*"([^"]+)"/u.exec(e);return t?.[1]?t[1].trim():(/\b(?:in|for)\s+([A-Za-z][A-Za-z\s.-]*?)(?:[?.!,]|$)/u.exec(e)??/\b([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)\b/u.exec(e))?.[1]?.trim()||`Brooklyn`}function isWeatherPayload(e){return bootstrapWeatherPayloadSchema.safeParse(e).success}function formatToolOutput(e){if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}export{ASH_MOCK_AUTHORED_MODELS_ENV,createMockAuthoredRuntimeModel,resolveMockAuthoredRuntimeModel,shouldMockAuthoredRuntimeModels};
|
|
3
|
+
`).map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of n){if(e===BOOTSTRAP_RUNTIME_SYSTEM_PROMPT||e===`Available skills`)continue;let t=/^System \((.+)\)$/.exec(e);if(t?.[1]){r.push(t[1]);continue}let n=/^Skill \((.+)\)$/.exec(e);n?.[1]&&r.push(n[1])}if(r.length>0)return r;let a=n.find(e=>e!==BOOTSTRAP_RUNTIME_SYSTEM_PROMPT&&e!==`Available skills`);return a===void 0?[]:[a]});return[...new Set(n)]}function getToolInputPropertyNames(e){return!isRecord(e)||!isRecord(e.properties)?[]:Object.keys(e.properties)}function findRelevantTool(e,t){let n=normalizeText(t),r=e.find(e=>n.includes(normalizeText(e.name)));return r===void 0?/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(n)?e.find(e=>/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(normalizeText(`${e.name} ${e.description??``}`)))??null:null:r}function findRelevantCodeModeHostTool(e,t){return e===void 0?null:findRelevantTool(parseCodeModeHostTools(e),t)?.name??null}function parseCodeModeHostTools(e){let t=[],n;for(let r of e.split(`
|
|
4
|
+
`)){let e=/^\s*\/\*\*\s*(.*?)\s*\*\/\s*$/u.exec(r);if(e?.[1]!==void 0){n=e[1];continue}let i=/^\s*(?:([$A-Z_a-z][$\w]*)|(["'])(.*?)\2)\s*:\s*\(input:/u.exec(r),a=i?.[1]??i?.[3];a!==void 0&&(t.push({description:n,name:a}),n=void 0)}return t}function formatCodeModeToolAccess(e){return/^[$A-Z_a-z][$\w]*$/u.test(e)?`.${e}`:`[${JSON.stringify(e)}]`}function normalizeText(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,` `).trim()}function createToolCallId(e){return`call_${e.toLowerCase().replace(/[^a-z0-9]+/gu,`_`).replace(/^_+|_+$/gu,``)||`tool`}`}function resolveSystemProbe(e){let t=e.filter(e=>e.role===`system`).map(e=>getPromptContentText(e.content)).join(`
|
|
5
|
+
`);return/hmr-probe:\s*([^\n]+)/iu.exec(t)?.[1]?.trim()||null}function resolveWeatherCity(e){let t=/"city"\s*:\s*"([^"]+)"/u.exec(e);return t?.[1]?t[1].trim():(/\b(?:in|for)\s+([A-Za-z][A-Za-z\s.-]*?)(?:[?.!,]|$)/u.exec(e)??/\b([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)\b/u.exec(e))?.[1]?.trim()||`Brooklyn`}function resolveLookupTopic(e){return/\btopic\s+['"]?([A-Za-z0-9_.-]+)['"]?/u.exec(e)?.[1]??`demo`}function isWeatherPayload(e){return bootstrapWeatherPayloadSchema.safeParse(e).success}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function formatToolOutput(e){if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}export{ASH_MOCK_AUTHORED_MODELS_ENV,createMockAuthoredRuntimeModel,resolveMockAuthoredRuntimeModel,shouldMockAuthoredRuntimeModels};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BootstrapPrompt } from "#runtime/agent/bootstrap-model-utils.js";
|
|
2
|
+
interface AvailableBootstrapSkill {
|
|
3
|
+
readonly description: string;
|
|
4
|
+
readonly name: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getAvailableSkills(prompt: BootstrapPrompt): AvailableBootstrapSkill[];
|
|
7
|
+
export declare function findRelevantSkill(skills: readonly AvailableBootstrapSkill[], message: string): AvailableBootstrapSkill | null;
|
|
8
|
+
export declare function getActivatedSkillIds(prompt: BootstrapPrompt): string[];
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{getPromptContentText}from"#runtime/agent/bootstrap-model-utils.js";function getAvailableSkills(t){let n=new Map;for(let r of t){if(r.role!==`system`)continue;let t=getPromptContentText(r.content);if(t.startsWith(`Available skills
|
|
2
|
+
`))for(let e of t.split(`
|
|
3
|
+
`).slice(1)){let t=parseAvailableSkill(e);t!==null&&n.set(t.name,t)}}return[...n.values()]}function findRelevantSkill(e,t){let n=normalizeText(t);for(let t of e)if(n.includes(normalizeText(t.name)))return t;return/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(n)?e.find(e=>/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(normalizeText(`${e.name} ${e.description}`)))??null:null}function getActivatedSkillIds(t){return t.filter(e=>e.role===`system`).flatMap(t=>getPromptContentText(t.content).split(`
|
|
4
|
+
`).map(e=>e.trim()).flatMap(e=>{let t=/^Skill \((.+)\)$/.exec(e);return t?.[1]===void 0?[]:[t[1]]}))}function parseAvailableSkill(e){let t=/^- (.+?): (.+?)(?: \(path: (.+)\))?$/.exec(e.trim());return t?.[1]&&t[2]?{description:t[2],name:t[1]}:null}function normalizeText(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,` `).trim()}export{findRelevantSkill,getActivatedSkillIds,getAvailableSkills};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import "#internal/workflow/builtins.js";
|
|
2
|
+
/**
|
|
3
|
+
* Maximum byte size for an attribute value on a workflow run.
|
|
4
|
+
*
|
|
5
|
+
* Local mirror of `ATTRIBUTE_VALUE_MAX_BYTES` from `@workflow/world`
|
|
6
|
+
* (source of truth: `packages/world/src/attributes.ts` in the workflow
|
|
7
|
+
* repo). The value is duplicated rather than imported because
|
|
8
|
+
* `@workflow/core` — the only workflow surface bundled into the
|
|
9
|
+
* workflow body — does not re-export it, and pulling `@workflow/world`
|
|
10
|
+
* into the body bundle would drag in the full zod attribute validator
|
|
11
|
+
* (the same reason `workflow-core-shim.ts` skips runtime validation in
|
|
12
|
+
* its `experimental_setAttributes`).
|
|
13
|
+
*
|
|
14
|
+
* Strings emitted through {@link setAshAttributes} are truncated to this
|
|
15
|
+
* byte count before they reach the runtime so the validator never
|
|
16
|
+
* rejects a tag for length alone.
|
|
17
|
+
*
|
|
18
|
+
* Drift is conservative-by-construction: if workflow LOWERS the limit,
|
|
19
|
+
* over-long values are rejected and `setAshAttributes` swallows the
|
|
20
|
+
* failure (warn-once-per-process) — dashboards see a missing tag, never
|
|
21
|
+
* a broken agent; if workflow RAISES it, titles are merely shorter than
|
|
22
|
+
* necessary. `emit.drift.test.ts` asserts equality against the real
|
|
23
|
+
* `@workflow/world` export (a devDependency) so CI fails loudly the day
|
|
24
|
+
* the constants diverge.
|
|
25
|
+
*/
|
|
26
|
+
export declare const ASH_ATTRIBUTE_VALUE_MAX_BYTES = 256;
|
|
27
|
+
/**
|
|
28
|
+
* Attribute value the caller wants to write. `undefined` values are
|
|
29
|
+
* stripped before the runtime call; numbers are stringified; strings
|
|
30
|
+
* are truncated to {@link ASH_ATTRIBUTE_VALUE_MAX_BYTES}.
|
|
31
|
+
*/
|
|
32
|
+
export type AshAttributeValue = string | number | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Truncates a string so its UTF-8 byte length is at most `maxBytes`
|
|
35
|
+
* without splitting a multi-byte character.
|
|
36
|
+
*
|
|
37
|
+
* The workflow runtime measures attribute values in UTF-8 bytes, not
|
|
38
|
+
* code units, so `value.slice(0, maxBytes)` is not safe — a JS string
|
|
39
|
+
* with two-byte characters (e.g. emoji surrogate pairs) can serialize
|
|
40
|
+
* to twice as many bytes as code units. We re-encode the truncated
|
|
41
|
+
* candidate after each drop and shrink one code unit at a time when
|
|
42
|
+
* the candidate's last character straddles the byte budget.
|
|
43
|
+
*/
|
|
44
|
+
export declare function truncateForTag(value: string, maxBytes?: number): string;
|
|
45
|
+
/**
|
|
46
|
+
* Writes a batch of Ash-owned attributes to the active workflow run.
|
|
47
|
+
*
|
|
48
|
+
* Reserved-namespace contract:
|
|
49
|
+
* - All keys must use the `$ash.` prefix (the workflow runtime would
|
|
50
|
+
* otherwise reject them as user-space writes into the reserved `$`
|
|
51
|
+
* namespace).
|
|
52
|
+
* - The call always opts in via `{ allowReservedAttributes: true }`
|
|
53
|
+
* on behalf of the framework — authored code never calls this helper
|
|
54
|
+
* directly.
|
|
55
|
+
*
|
|
56
|
+
* Value normalization:
|
|
57
|
+
* - `undefined` entries are dropped so callers can build attribute
|
|
58
|
+
* maps with optional fields (`$ash.subagent` is only present on
|
|
59
|
+
* subagent roots, for example).
|
|
60
|
+
* - Numbers are stringified (the runtime stores all values as strings).
|
|
61
|
+
* - Strings are truncated to {@link ASH_ATTRIBUTE_VALUE_MAX_BYTES} via
|
|
62
|
+
* {@link truncateForTag} so a long free-form value (e.g. `$ash.title`)
|
|
63
|
+
* can never trip the runtime's per-value byte budget.
|
|
64
|
+
*
|
|
65
|
+
* Failure policy: tag writes are observability metadata, not load-bearing
|
|
66
|
+
* state. A failure inside the runtime (transient network, schema bug,
|
|
67
|
+
* missing world adapter) is logged once per process and then swallowed
|
|
68
|
+
* so the Ash session it tagged is unaffected.
|
|
69
|
+
*
|
|
70
|
+
* Must be called from inside a `"use workflow"` or `"use step"` body —
|
|
71
|
+
* the runtime throws a `FatalError` outside those contexts.
|
|
72
|
+
*/
|
|
73
|
+
export declare function setAshAttributes(attrs: Record<string, AshAttributeValue>): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"#internal/workflow/builtins.js";const ASH_ATTRIBUTE_VALUE_MAX_BYTES=256;let WARNED_ABOUT_TAG_FAILURE=!1;function truncateForTag(e,t=256){if(t<=0)return``;let n=new TextEncoder;if(n.encode(e).length<=t)return e;let r=e.length;for(;r>0;){let i=e.charCodeAt(r-1);if(i>=55296&&i<=56319){--r;continue}let a=e.slice(0,r);if(n.encode(a).length<=t)return a;--r}return``}async function setAshAttributes(e){let n={};for(let[t,r]of Object.entries(e))r!==void 0&&(n[t]=truncateForTag(typeof r==`number`?String(r):r));if(Object.keys(n).length!==0)try{let{experimental_setAttributes:e}=await import(`#compiled/@workflow/core/index.js`);await e(n,{allowReservedAttributes:!0})}catch(e){WARNED_ABOUT_TAG_FAILURE||(WARNED_ABOUT_TAG_FAILURE=!0,console.warn(`[ash] setAshAttributes failed; suppressing further warnings this process.`,{keys:Object.keys(n),error:e.message}))}}export{ASH_ATTRIBUTE_VALUE_MAX_BYTES,setAshAttributes,truncateForTag};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getAdapterKind}from"#channel/adapter.js";import{SUBAGENT_ADAPTER}from"#execution/subagent-adapter.js";import{SCHEDULE_ADAPTER}from"#channel/schedule.js";import{HTTP_ADAPTER}from"#channel/http.js";import{RuntimeRegistryError}from"#internal/runtime-registry.js";const FRAMEWORK_ADAPTERS=[HTTP_ADAPTER,SUBAGENT_ADAPTER,SCHEDULE_ADAPTER],ADAPTER_NON_EVENT_FIELDS=new Set([`kind`,`state`,`deliver`,`createAdapterContext`,`fetchFile`]);function createRuntimeAdapterRegistry(e){let t=new Map,n=new Set;for(let e of FRAMEWORK_ADAPTERS){let r=requireAdapterKind(e);n.add(r),t.set(r,e)}for(let r of e.channels){if(r.adapter===void 0)continue;let e={logicalPath:r.logicalPath,sourceId:r.sourceId},i=r.adapter,a=requireAdapterKind(i,e);if(n.has(a)){if(carriesAdapterBehavior(i))throw new RuntimeRegistryError(`adapter`,`Channel adapter kind "${a}" is reserved by the framework. A route-declared adapter may share a framework kind only as a pass-through with no \`deliver\` hook, event handlers, \`attachments\` resolver, or \`createAdapterContext\` factory. Use a custom \`kind\` to add channel-specific behavior.`,{...e,entryName:a});continue}t.set(a,i)}return{adaptersByKind:t}}function deserializeRuntimeAdapter(e,t){let n=t,r=e.adaptersByKind.get(n.kind);if(r===void 0)throw Error(`Unknown adapter kind: "${n.kind}". Declare the adapter on the route that starts this session so the runtime can rehydrate it.`);return{...r,state:n.state}}function requireAdapterKind(t,n){let r=getAdapterKind(t);if(typeof r!=`string`||r.length===0)throw new RuntimeRegistryError(`adapter`,"Adapters must declare a non-empty `kind` field.",{entryName:`unknown`,logicalPath:n?.logicalPath,sourceId:n?.sourceId});return r}function carriesAdapterBehavior(e){if(e.deliver!==void 0||e.fetchFile!==void 0||e.createAdapterContext!==void 0)return!0;for(let[t,n]of Object.entries(e))if(!ADAPTER_NON_EVENT_FIELDS.has(t)&&typeof n==`function`)return!0;return!1}export{createRuntimeAdapterRegistry,deserializeRuntimeAdapter};
|
|
1
|
+
import{getAdapterKind}from"#channel/adapter.js";import{SUBAGENT_ADAPTER}from"#execution/subagent-adapter.js";import{SCHEDULE_ADAPTER}from"#channel/schedule.js";import{HTTP_ADAPTER}from"#channel/http.js";import{RuntimeRegistryError}from"#internal/runtime-registry.js";const FRAMEWORK_ADAPTERS=[HTTP_ADAPTER,SUBAGENT_ADAPTER,SCHEDULE_ADAPTER],ADAPTER_NON_EVENT_FIELDS=new Set([`kind`,`state`,`deliver`,`createAdapterContext`,`fetchFile`,`instrumentation`]);function createRuntimeAdapterRegistry(e){let t=new Map,n=new Set;for(let e of FRAMEWORK_ADAPTERS){let r=requireAdapterKind(e);n.add(r),t.set(r,e)}for(let r of e.channels){if(r.adapter===void 0)continue;let e={logicalPath:r.logicalPath,sourceId:r.sourceId},i=r.adapter,a=requireAdapterKind(i,e);if(n.has(a)){if(carriesAdapterBehavior(i))throw new RuntimeRegistryError(`adapter`,`Channel adapter kind "${a}" is reserved by the framework. A route-declared adapter may share a framework kind only as a pass-through with no \`deliver\` hook, event handlers, \`attachments\` resolver, or \`createAdapterContext\` factory. Use a custom \`kind\` to add channel-specific behavior.`,{...e,entryName:a});continue}t.set(a,i)}return{adaptersByKind:t}}function deserializeRuntimeAdapter(e,t){let n=t,r=e.adaptersByKind.get(n.kind);if(r===void 0)throw Error(`Unknown adapter kind: "${n.kind}". Declare the adapter on the route that starts this session so the runtime can rehydrate it.`);return{...r,state:n.state}}function requireAdapterKind(t,n){let r=getAdapterKind(t);if(typeof r!=`string`||r.length===0)throw new RuntimeRegistryError(`adapter`,"Adapters must declare a non-empty `kind` field.",{entryName:`unknown`,logicalPath:n?.logicalPath,sourceId:n?.sourceId});return r}function carriesAdapterBehavior(e){if(e.deliver!==void 0||e.fetchFile!==void 0||e.createAdapterContext!==void 0)return!0;for(let[t,n]of Object.entries(e))if(!ADAPTER_NON_EVENT_FIELDS.has(t)&&typeof n==`function`)return!0;return!1}export{createRuntimeAdapterRegistry,deserializeRuntimeAdapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{contextStorage}from"#context/container.js";import{
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{contextStorage}from"#context/container.js";import{createMCPClient}from"#compiled/@ai-sdk/mcp/index.js";import{readCachedToken,writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";var McpConnectionClient=class{#e;#t;#n;#r;#i;constructor(e){this.#i=e}async connect(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#a();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#a(){let e=await resolveHeaders(this.#i),t=this.#i.url;try{return await createMCPClient({transport:{type:`http`,url:t,headers:e}})}catch(r){if(!isMcpHttpFallbackRetryableError(r))throw r;return await createMCPClient({transport:{type:`sse`,url:t,headers:e}})}}async getToolMetadata(){return(await this.#o()).metadata}async getTools(){return(await this.#o()).tools}async executeTool(e,t){let{tools:n}=await this.#o(),r=n[e];if(r?.execute===void 0)throw Error(`Tool "${e}" not found in connection "${this.#i.connectionName}".`);return r.execute(t,{})}async#o(){if(this.#r!==void 0)return this.#r;if(this.#n!==void 0)return this.#n;this.#n=this.#s();try{return this.#r=await this.#n,this.#r}catch(e){throw this.#n=void 0,e}}async#s(){let e=await this.connect(),t=await e.listTools(),n=this.#i.tools,r=n===void 0?t.tools:t.tools.filter(e=>passesToolFilter(e.name,n)),i=e.toolsFromDefinitions({tools:r});return{metadata:r.map(e=>({annotations:e.annotations,description:e.description??``,inputSchema:e.inputSchema??{},name:e.name})),tools:i}}async close(){this.#t!==void 0&&(await this.#t.close(),this.#t=void 0),this.#e=void 0,this.#n=void 0,this.#r=void 0}};function isMcpHttpFallbackRetryableError(e){let t=readHttpStatus(e);return t===400||t===404||t===405}function readHttpStatus(t){for(let n of walkErrorChain(t)){if(!isObject(n))continue;let t=readStatusField(n);if(t!==void 0)return t;let r=n.response;if(isObject(r)){let e=readStatusField(r);if(e!==void 0)return e}if(typeof n.message==`string`){let e=/\bHTTP\s+(\d{3})\b/u.exec(n.message);if(e?.[1]!==void 0)return Number(e[1])}}}function readStatusField(e){if(typeof e.status==`number`)return e.status;if(typeof e.statusCode==`number`)return e.statusCode}function*walkErrorChain(t){let n=t,r=new Set;for(;n!=null&&!r.has(n);){if(r.add(n),yield n,!isObject(n)||!(`cause`in n))return;n=n.cause}}function passesToolFilter(e,t){return t===void 0?!0:`allow`in t?t.allow.includes(e):!t.block.includes(e)}async function resolveHeaders(e){let t={};if(e.authorization!==void 0&&(t.Authorization=`Bearer ${(await resolveToken(e)).token}`),e.headers!==void 0){let n=await resolveHeadersDefinition(e.headers);for(let[r,i]of Object.entries(n)){if(e.authorization!==void 0&&r.toLowerCase()===`authorization`)throw Error(`Connection "${e.connectionName}" headers must not include an "Authorization" key when "authorization" is also provided.`);t[r]=i}}return t}async function resolveToken(e){if(e.authorization===void 0)throw Error(`Connection "${e.connectionName}" does not define authorization.`);let n=contextStorage.getStore(),a=resolveConnectionPrincipal(e.connectionName,e.authorization,n),o={url:e.url};if(n===void 0)return await e.authorization.getToken({principal:a,connection:o});let s=principalKey(a),c=readCachedToken(n,e.connectionName,s);if(c!==void 0)return c;let l=await e.authorization.getToken({principal:a,connection:o});return writeCachedToken(n,e.connectionName,s,l),l}async function resolveHeadersDefinition(e){if(typeof e==`function`)return await e();let t={},n=Object.entries(e);for(let[e,r]of n)t[e]=await resolveHeaderValue(r);return t}async function resolveHeaderValue(e){return typeof e==`function`?await e():await e}export{McpConnectionClient,passesToolFilter,resolveHeaders};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { CodeModeInterrupt, CodeModeInterruptExecutionContext, CodeModeInterruptPayload } from "#shared/code-mode.js";
|
|
2
|
+
import type { AuthorizationChallenge } from "#harness/authorization.js";
|
|
2
3
|
import type { JsonValue } from "#public/types/json.js";
|
|
3
4
|
export declare const CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND = "ash.connection-auth";
|
|
4
5
|
export interface CodeModeConnectionAuthPayload extends CodeModeInterruptPayload {
|
|
5
6
|
readonly kind: typeof CODE_MODE_CONNECTION_AUTH_INTERRUPT_KIND;
|
|
6
7
|
readonly args: JsonValue;
|
|
8
|
+
readonly challenges?: readonly AuthorizationChallenge[];
|
|
7
9
|
readonly connectionName: string;
|
|
8
10
|
readonly toolName: string;
|
|
9
11
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ResolvedDynamicToolResolver } from "#runtime/types.js";
|
|
2
|
+
import type { DynamicToolEvents } from "#shared/dynamic-tool-definition.js";
|
|
3
|
+
import type { ModelMessage } from "ai";
|
|
4
|
+
interface ConnectionSearchResultItem {
|
|
5
|
+
readonly connection: string;
|
|
6
|
+
readonly description: string;
|
|
7
|
+
readonly error?: string;
|
|
8
|
+
readonly inputSchema?: Record<string, unknown>;
|
|
9
|
+
readonly needsAuthorization?: boolean;
|
|
10
|
+
readonly tool?: string;
|
|
11
|
+
readonly qualifiedName?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Extracts connection search results from conversation history.
|
|
15
|
+
* Scans tool-result messages for `connection_search` results and
|
|
16
|
+
* returns deduplicated tool metadata (latest result wins per qualifiedName).
|
|
17
|
+
*/
|
|
18
|
+
export declare function extractDiscoveredTools(messages: readonly ModelMessage[]): ConnectionSearchResultItem[];
|
|
19
|
+
/**
|
|
20
|
+
* Creates the connection search dynamic tool resolver events.
|
|
21
|
+
*
|
|
22
|
+
* The resolver subscribes to `step.started` so it re-derives the tool
|
|
23
|
+
* set from conversation history on every step. After compaction, old
|
|
24
|
+
* `connection_search` results disappear from messages and discovered
|
|
25
|
+
* tools naturally drop from the toolset — no `onCompact` hook needed.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createConnectionSearchEvents(): DynamicToolEvents;
|
|
28
|
+
/**
|
|
29
|
+
* Creates a `ResolvedDynamicToolResolver` for the framework connection
|
|
30
|
+
* search tool. Used by graph resolution to register alongside authored
|
|
31
|
+
* dynamic tool resolvers.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createConnectionSearchResolver(): ResolvedDynamicToolResolver;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{ConnectionRegistryKey}from"#context/providers/connection.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";const logger=createLogger(`framework.connection-search-dynamic`),ConnectionSearchResultsKey=new ContextKey(`ash.connectionSearchResults`);function qualifiedConnectionToolName(e,t){return`${e}__${t}`}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}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)}}async function executeConnectionSearch(e){let n=loadContext(),i=n.get(ConnectionRegistryKey);if(i===void 0)return[];await completePendingAuthorizations(i);let s=e.limit??10,l=tokenize(e.keywords),u=[],p=[],m=e.connection!==void 0&&e.connection!==``?i.getConnections().filter(t=>t.connectionName===e.connection):i.getConnections(),h=[];for(let e of m){let t;try{t=await i.getClient(e.connectionName).getToolMetadata()}catch(t){if(isConnectionAuthorizationRequiredError(t)){let t=resolveInteractiveAuth(i,e.connectionName);if(t){let n=getHookUrl(e.connectionName);if(n){let r=resolveConnectionPrincipal(e.connectionName,t);try{let{challenge:i,state:a}=await t.startAuthorization({callbackUrl:n,connection:{url:e.url??``},principal:r});h.push({name:e.connectionName,challenge:i,hookUrl:n,state:a})}catch(t){logger.warn(`startAuthorization failed`,{connection:e.connectionName,error:t instanceof Error?t:Error(String(t))})}}}p.push({connection:e.connectionName,description:e.description,needsAuthorization:!0});continue}if(isConnectionAuthorizationFailedError(t)){logger.warn(`connection authorization failed`,{connection:e.connectionName,reason:t.reason,retryable:t.retryable,error:t}),p.push({connection:e.connectionName,description:e.description,error:`Authorization failed for ${e.connectionName}: ${t.message}`});continue}let n=t instanceof Error?t.message:`unknown error`;logger.warn(`failed to load connection tools`,{connection:e.connectionName,error:t instanceof Error?t:Error(n)}),p.push({connection:e.connectionName,description:e.description,error:`Failed to load tools for "${e.connectionName}": ${n}`});continue}for(let n of t){let t=scoreMatch(l,n);t>0&&u.push({item:{connection:e.connectionName,description:n.description,inputSchema:n.inputSchema,qualifiedName:`connection__${qualifiedConnectionToolName(e.connectionName,n.name)}`,tool:n.name},score:t})}}if(h.length>0)return requestAuthorization(h);u.sort((e,t)=>t.score-e.score);let g=u.slice(0,s).map(e=>e.item);if(g.length>0){let e=[...g,...p],t=n.get(ConnectionSearchResultsKey)??[],r=new Map(t.map(e=>[e.qualifiedName,e]));for(let e of g)e.qualifiedName&&r.set(e.qualifiedName,e);return n.set(ConnectionSearchResultsKey,[...r.values()]),e}return m.map(e=>p.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}function extractDiscoveredTools(e){let t=new Map;for(let n of e){if(n.role!==`tool`)continue;let e=n.content;for(let n of e){if(n.type!==`tool-result`||n.toolName!==`connection__search`)continue;let e=n.output;if(e==null)continue;let r=typeof e==`object`&&`type`in e&&`value`in e?e.value:e;if(Array.isArray(r))for(let e of r)e.tool&&e.qualifiedName&&t.set(e.qualifiedName,e)}}return[...t.values()]}function createConnectionSearchEvents(){return{"step.started":async(e,n)=>{let c=loadContext().get(ConnectionRegistryKey);if(!c||c.getConnections().length===0)return null;let d=c.getConnections().map(e=>e.connectionName),p=extractDiscoveredTools(n.messages),m=loadContext().get(ConnectionSearchResultsKey)??[],h=new Map;for(let e of m)e.qualifiedName&&h.set(e.qualifiedName,e);for(let e of p)e.qualifiedName&&h.set(e.qualifiedName,e);let g=[...h.values()],_={};_.search={description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. \`connection__linear__list_issues\`) in your next response. Available connections: ${d.join(`, `)}.`,inputSchema:{type:`object`,additionalProperties:!1,properties:{keywords:{description:`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`,type:`string`},connection:{description:`Optional: limit search to a specific connection name.`,type:`string`},limit:{description:`Max results to return. Default 10.`,type:`number`}},required:[`keywords`]},async execute(e){return executeConnectionSearch(e)}};for(let e of g){let n=e.connection,c=e.tool;_[qualifiedConnectionToolName(n,c)]={description:e.description,inputSchema:e.inputSchema??{type:`object`},async execute(e){let d=loadContext().get(ConnectionRegistryKey),f=d.getConnections().find(e=>e.connectionName===n),p=f?.authorization&&supportsInteractiveAuthorization(f.authorization)?f.authorization:void 0;if(p){let e=getAuthorizationResult(n);if(e){let r=loadContext(),i=resolveConnectionPrincipal(n,p),a=await p.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:f?.url??``},principal:i,request:e.callback,state:e.state});writeCachedToken(r,n,principalKey(i),a)}}try{let t=(await d.getClient(n).getTools())[c];if(!t?.execute)throw Error(`Connection tool "${qualifiedConnectionToolName(n,c)}" has no execute function.`);return t.execute(e,{})}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!p)throw e;let t=getHookUrl(n);if(!t)throw e;let r=resolveConnectionPrincipal(n,p),{challenge:i,state:s}=await p.startAuthorization({callbackUrl:t,connection:{url:f?.url??``},principal:r});return requestAuthorization([{name:n,challenge:i,hookUrl:t,state:s}])}}}}return _}}}function createConnectionSearchResolver(){let e=createConnectionSearchEvents();return{slug:`connection`,eventNames:Object.keys(e),events:e,sourceId:`ash:connection-search-dynamic`,sourceKind:`module`,logicalPath:`ash:framework/connection-search-dynamic`}}export{createConnectionSearchEvents,createConnectionSearchResolver,extractDiscoveredTools};
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
export { ConnectionRegistryKey } from "#
|
|
1
|
+
export { ConnectionRegistryKey } from "#context/providers/connection.js";
|
|
2
2
|
export type { ReadFileStamp, ReadFileState } from "#runtime/framework-tools/file-state.js";
|
|
3
3
|
export { ReadFileStateKey } from "#runtime/framework-tools/file-state.js";
|
|
4
4
|
export type { TodoItem, TodoState } from "#runtime/framework-tools/todo.js";
|
|
5
5
|
export { TodoStateKey } from "#runtime/framework-tools/todo.js";
|
|
6
6
|
import type { ResolvedToolDefinition } from "#runtime/types.js";
|
|
7
|
-
interface FrameworkToolConfig {
|
|
8
|
-
readonly hasConnections: boolean;
|
|
9
|
-
}
|
|
10
7
|
/**
|
|
11
8
|
* Returns framework-owned tool definitions registered in the tool registry
|
|
12
9
|
* alongside authored tools during graph resolution.
|
|
10
|
+
*
|
|
11
|
+
* `connection_search` is no longer in this list — it is registered as a
|
|
12
|
+
* framework dynamic tool resolver in the graph resolution path.
|
|
13
13
|
*/
|
|
14
|
-
export declare function getFrameworkToolDefinitions(
|
|
14
|
+
export declare function getFrameworkToolDefinitions(_config?: {
|
|
15
|
+
readonly hasConnections?: boolean;
|
|
16
|
+
}): readonly ResolvedToolDefinition[];
|
|
15
17
|
/**
|
|
16
18
|
* Returns the names of every framework-provided tool the framework knows
|
|
17
19
|
* about, regardless of whether the current agent gates any of them on
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{ConnectionRegistryKey}from"#context/providers/connection.js";import{ReadFileStateKey}from"#runtime/framework-tools/file-state.js";import{ASK_QUESTION_TOOL_DEFINITION}from"#runtime/framework-tools/ask-question.js";import{WEB_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-search.js";import{BASH_TOOL_DEFINITION}from"#runtime/framework-tools/bash.js";import{GLOB_TOOL_DEFINITION}from"#runtime/framework-tools/glob.js";import{GREP_TOOL_DEFINITION}from"#runtime/framework-tools/grep.js";import{READ_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/read-file.js";import{SKILL_TOOL_DEFINITION}from"#runtime/framework-tools/skill.js";import{TODO_TOOL_DEFINITION,TodoStateKey}from"#runtime/framework-tools/todo.js";import{WEB_FETCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-fetch.js";import{WRITE_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/write-file.js";const ALL_FRAMEWORK_TOOLS=[ASK_QUESTION_TOOL_DEFINITION,BASH_TOOL_DEFINITION,GLOB_TOOL_DEFINITION,GREP_TOOL_DEFINITION,READ_FILE_TOOL_DEFINITION,WRITE_FILE_TOOL_DEFINITION,TODO_TOOL_DEFINITION,WEB_FETCH_TOOL_DEFINITION,WEB_SEARCH_TOOL_DEFINITION,SKILL_TOOL_DEFINITION];function getFrameworkToolDefinitions(e){return ALL_FRAMEWORK_TOOLS}function getAllFrameworkToolNames(){return new Set(ALL_FRAMEWORK_TOOLS.map(e=>e.name))}export{ConnectionRegistryKey,ReadFileStateKey,TodoStateKey,getAllFrameworkToolNames,getFrameworkToolDefinitions};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
function formatConnectionsSection(e){return[`## Connections`,``,`You have direct access to the following external services through connected MCP servers.`,`When the user's request relates to any of these services, use them instead of web search or general knowledge.`,``,`Available connections:`,...e.map(e=>`- ${e.connectionName}: ${e.description}`),``,`Use connection__search to discover specific tools within a connection. Discovered tools become directly callable by their qualified name (e.g. connection__linear__list_issues) in your next response.`].join(`
|
|
2
2
|
`)}export{formatConnectionsSection};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{expectObjectRecord}from"#internal/authored-module.js";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{
|
|
1
|
+
import{expectObjectRecord}from"#internal/authored-module.js";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{CODE_MODE_TOOL_NAME}from"#shared/code-mode.js";import{createRuntimeToolRegistry}from"#runtime/tools/registry.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{createConnectionSearchResolver}from"#runtime/framework-tools/connection-search-dynamic.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=new Set(o.map(e=>e.name)),c=getAllFrameworkToolNames(),l=new Set(n.tools.map(e=>e.name));for(let r of n.disabledFrameworkTools)if(!c.has(r))throw new ResolveRuntimeAgentGraphError(`agent/tools/${r}.ts exports disableTool() but "${r}" is not a framework tool. Rename the file to one of: ${[...c].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let u=new Set(n.disabledFrameworkTools),d=await createRuntimeToolRegistry({tools:[...o.filter(e=>!l.has(e.name)&&!u.has(e.name)),...n.tools]},{reservedToolNames:[CODE_MODE_TOOL_NAME,...s.has(LOAD_SKILL_TOOL_NAME)||l.has(LOAD_SKILL_TOOL_NAME)?[]:[LOAD_SKILL_TOOL_NAME]]}),f=new Set(n.channels.map(e=>e.name)),p=getAllFrameworkChannelNames();for(let r of n.disabledFrameworkChannels)if(!p.has(r))throw new ResolveRuntimeAgentGraphError(`agent/channels/${r}.ts exports disableRoute() but "${r}" is not a framework channel. Rename the file to one of: ${[...p].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let m=new Set(n.disabledFrameworkChannels),h=[...getFrameworkChannelDefinitions().filter(e=>!f.has(e.name)&&!m.has(e.name)),...n.channels],g=createRuntimeSandboxRegistry({authoredSandbox:n.sandbox,workspaceResourceRoot:n.workspaceResourceRoot}),_=createRuntimeSubagentRegistry({reservedToolNames:[LOAD_SKILL_TOOL_NAME,...d.preparedTools.map(e=>e.name)],subagents:await resolveRuntimeSubagents({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.manifest,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,parentNodeId:e.nodeId,subagentNodesById:e.subagentNodesById})}),v=a?{...n,dynamicToolResolvers:[...n.dynamicToolResolvers,createConnectionSearchResolver()]}:n,y={agent:v,channels:h,hookRegistry:createRuntimeHookRegistry(v.hooks),nodeId:t,sandboxRegistry:g,sourceId:e.sourceId,subagentRegistry:_,toolRegistry:d,turnAgent:createResolvedRuntimeTurnAgent({agent:v,nodeId:t,tools:[...d.preparedTools,..._.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}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{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))),
|
|
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{resolveDynamicSkillDefinition}from"#runtime/resolve-dynamic-skill.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.dynamicSkills??[]).map(t=>resolveDynamicSkillDefinition(t,e.moduleMap,e.nodeId))),s=await Promise.all(e.manifest.dynamicTools.map(t=>resolveDynamicToolDefinition(t,e.moduleMap,e.nodeId))),c=await Promise.all(e.manifest.hooks.map(t=>resolveHookDefinition(t,e.moduleMap,e.nodeId))),l=await Promise.all(e.manifest.connections.map(t=>resolveConnectionDefinition(t,e.moduleMap,e.nodeId))),u=e.manifest.sandbox===null?null:await resolveSandboxDefinition(e.manifest.sandbox,e.moduleMap,e.nodeId),d=createResolvedInstructions(e.manifest.instructions),f=e.manifest.workspaceResourceRoot,p={channels:r,config:createResolvedAgentConfig(e.manifest),connections:l,disabledFrameworkChannels:i,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],dynamicSkillResolvers:o,dynamicToolResolvers:s,hooks:c,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:u,workspaceResourceRoot:f,skills:t,tools:a,workspaceSpec:{rootEntries:[...f.rootEntries]}};return d===void 0?p:{...p,instructions:d}}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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toErrorMessage}from"#shared/errors.js";import{normalizeChannelDefinition}from"#internal/authored-definition/channel.js";import{ResolveAgentError,createResolvedModuleSourceRef,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";async function resolveChannelDefinition(r,i,a){try{let
|
|
1
|
+
import{setChannelInstrumentationKind}from"#channel/compiled-channel.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeChannelDefinition}from"#internal/authored-definition/channel.js";import{ResolveAgentError,createResolvedModuleSourceRef,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";async function resolveChannelDefinition(r,i,a){try{let t=normalizeChannelDefinition(await loadResolvedModuleExport({definition:r,kindLabel:`channel`,moduleMap:i,nodeId:a}),`Expected the channel export "${r.exportName??`default`}" from "${r.logicalPath}" to match the public Ash shape.`),n=createResolvedModuleSourceRef({exportName:r.exportName,logicalPath:r.logicalPath,sourceId:r.sourceId}),o=t.routes.find(e=>e.method.toUpperCase()===r.method.toUpperCase()&&e.path===r.urlPath),s=`channel:${r.name}`;setChannelInstrumentationKind(t,s);let c=t.adapter;return c&&c.kind!==HTTP_ADAPTER_KIND&&(c.kind=s),{name:r.name,method:r.method,urlPath:r.urlPath,fetch:async(e,t)=>o?o.handler(e,t):Response.json({error:`No matching route handler.`,ok:!1},{status:404}),handler:o?.handler,receive:t.receive,definition:t,adapter:c,...n}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the channel definition from "${r.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:r.logicalPath,sourceId:r.sourceId})}}export{resolveChannelDefinition};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CompiledDynamicSkillDefinition } from "#compiler/manifest.js";
|
|
2
|
+
import type { CompiledModuleMap } from "#compiler/module-map.js";
|
|
3
|
+
import type { ResolvedDynamicSkillResolver } from "#runtime/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Resolves one compiled dynamic skill entry into a runtime-owned resolver
|
|
6
|
+
* with live event handler functions reattached from the authored module.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveDynamicSkillDefinition(definition: CompiledDynamicSkillDefinition, moduleMap: CompiledModuleMap, nodeId: string | undefined): Promise<ResolvedDynamicSkillResolver>;
|
|
@@ -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";async function resolveDynamicSkillDefinition(i,a,o){try{let n=expectObjectRecord(expectObjectRecord(await loadResolvedModuleExport({definition:i,kindLabel:`dynamic-skill`,moduleMap:a,nodeId:o}),describe(i,`to return an object`)).events,describe(i,`to provide an events object`)),r={};for(let t of i.eventNames)r[t]=expectFunction(n[t],describe(i,`to provide a handler for event "${t}"`));return{eventNames:[...i.eventNames],events:r,exportName:i.exportName,logicalPath:i.logicalPath,slug:i.slug,sourceId:i.sourceId,sourceKind:`module`}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to resolve dynamic skill from "${i.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:i.logicalPath,sourceId:i.sourceId})}}function describe(e,t){return`Expected the dynamic skill export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}export{resolveDynamicSkillDefinition};
|
|
@@ -1 +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,
|
|
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,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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{getRuntimeCompiledArtifactsCacheKey}from"#runtime/compiled-artifacts-source.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{resolveRuntimeAgentGraph}from"#runtime/resolve-agent-graph.js";import{pathToFileURL}from"node:url";import{loadCompiledModuleMap}from"#runtime/loaders/module-map.js";import{getActiveRuntimeSession}from"#runtime/sessions/runtime-session.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{createRuntimeAdapterRegistry}from"#runtime/channels/registry.js";const isCacheDisabled=process.env.ASH_DISABLE_AGENT_CACHE===`1`;async function loadFullBundle(e){let[t,i]=await Promise.all([loadCompiledManifest({compiledArtifactsSource:e}),loadRuntimeCompiledModuleMap(e)]),a=await resolveRuntimeAgentGraph({manifest:t,moduleMap:i}),o=a.root;return{adapterRegistry:createRuntimeAdapterRegistry({channels:collectResolvedChannels(a)}),compiledArtifactsSource:e,graph:a,hookRegistry:o.hookRegistry,moduleMap:i,resolvedAgent:o.agent,subagentRegistry:o.subagentRegistry,toolRegistry:o.toolRegistry,turnAgent:o.turnAgent}}async function loadRuntimeCompiledModuleMap(e){return e.kind===`disk`&&e.moduleMapLoaderPath!==void 0?await loadAuthoredSourceCompiledModuleMap(e):await loadCompiledModuleMap({compiledArtifactsSource:e})}async function loadAuthoredSourceCompiledModuleMap(e){if(e.moduleMapLoaderPath===void 0)throw Error(`Authored-source module map loading requires "moduleMapLoaderPath" in the compiled artifacts source.`);return await(await import(pathToFileURL(e.moduleMapLoaderPath).href)).loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:e})}async function getOrLoadFullBundle(e){if(isCacheDisabled)return loadFullBundle(e);let n=getActiveRuntimeSession(),r=getRuntimeCompiledArtifactsCacheKey(e),i=await resolveRuntimeCompiledArtifactsVersionedCacheKey(e),a=n.bundleCacheKeyBySourceKey.get(r);a!==void 0&&a!==i&&n.bundleCache.delete(a),n.bundleCacheKeyBySourceKey.set(r,i);let s=n.bundleCache.get(i);if(s!==void 0)return s;let c=loadFullBundle(e).catch(e=>{throw n.bundleCache.delete(i),n.bundleCacheKeyBySourceKey.get(r)===i&&n.bundleCacheKeyBySourceKey.delete(r),e});return n.bundleCache.set(i,c),c}async function getCompiledRuntimeAgentBundle(t){let n=await getOrLoadFullBundle(t.compiledArtifactsSource);if(t.nodeId===void 0)return n;let r=getResolvedRuntimeAgentNode(n.graph,t.nodeId);return{adapterRegistry:n.adapterRegistry,compiledArtifactsSource:n.compiledArtifactsSource,graph:{nodesByNodeId:n.graph.nodesByNodeId,root:r},hookRegistry:r.hookRegistry,moduleMap:n.moduleMap,nodeId:t.nodeId,resolvedAgent:r.agent,subagentRegistry:r.subagentRegistry,toolRegistry:r.toolRegistry,turnAgent:r.turnAgent}}function clearCompiledRuntimeAgentBundleCache(){let e=getActiveRuntimeSession();e.bundleCache.clear(),e.bundleCacheKeyBySourceKey.clear()}function collectResolvedChannels(e){let t=new Map;for(let n of e.nodesByNodeId.values())for(let e of n.channels)t.set(`${e.sourceId}:${e.name}`,e);return[...t.values()]}export{clearCompiledRuntimeAgentBundleCache,getCompiledRuntimeAgentBundle};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{getAdapterKind}from"#channel/adapter.js";import{ContextKey}from"#context/key.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{deserializeRuntimeAdapter}from"#runtime/channels/registry.js";const ChannelKey=new ContextKey(`ash.channel`,{codec:{serialize(t){return{kind:getAdapterKind(t),state:t.state?{...t.state}:{}}},deserialize(e,t){let n=t.get(BundleKey);if(n===void 0)throw Error(`Cannot deserialize "ash.channel" before "ash.bundle". The runtime bundle must be present in context.`);return deserializeRuntimeAdapter(n.adapterRegistry,e)}}}),BundleKey=new ContextKey(`ash.bundle`,{codec:{serialize:e=>({nodeId:e.nodeId,source:e.compiledArtifactsSource}),deserialize:e=>{let{source:t,nodeId:r}=e;return getCompiledRuntimeAgentBundle({compiledArtifactsSource:t,nodeId:r})}}});export{BundleKey,ChannelKey};
|
|
@@ -255,13 +255,21 @@ interface ResolvedAgentMetadata {
|
|
|
255
255
|
readonly diagnosticsSummary: DiscoverDiagnosticsSummary;
|
|
256
256
|
}
|
|
257
257
|
/**
|
|
258
|
-
* Runtime resolver for dynamic tools declared via `
|
|
259
|
-
*
|
|
260
|
-
* loaded from the compiled module.
|
|
258
|
+
* Runtime resolver for dynamic tools declared via `defineDynamic({ events })`.
|
|
259
|
+
* Carries the live event handler functions loaded from the compiled module.
|
|
261
260
|
*/
|
|
262
261
|
export interface ResolvedDynamicToolResolver extends Readonly<ModuleSourceRef> {
|
|
263
262
|
readonly slug: string;
|
|
264
|
-
readonly
|
|
263
|
+
readonly eventNames: readonly string[];
|
|
264
|
+
readonly events: Readonly<Record<string, (event: unknown, ctx: unknown) => unknown | Promise<unknown>>>;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Runtime resolver for dynamic skills declared via `defineDynamic({ events })`
|
|
268
|
+
* in `agent/skills/`. Carries the live event handler functions loaded from the
|
|
269
|
+
* compiled module.
|
|
270
|
+
*/
|
|
271
|
+
export interface ResolvedDynamicSkillResolver extends Readonly<ModuleSourceRef> {
|
|
272
|
+
readonly slug: string;
|
|
265
273
|
readonly eventNames: readonly string[];
|
|
266
274
|
readonly events: Readonly<Record<string, (event: unknown, ctx: unknown) => unknown | Promise<unknown>>>;
|
|
267
275
|
}
|
|
@@ -286,6 +294,7 @@ export interface ResolvedAgent {
|
|
|
286
294
|
* filter the framework default tool set.
|
|
287
295
|
*/
|
|
288
296
|
readonly disabledFrameworkTools: readonly string[];
|
|
297
|
+
readonly dynamicSkillResolvers: readonly ResolvedDynamicSkillResolver[];
|
|
289
298
|
readonly dynamicToolResolvers: readonly ResolvedDynamicToolResolver[];
|
|
290
299
|
readonly metadata: ResolvedAgentMetadata;
|
|
291
300
|
/**
|