experimental-ash 0.35.0 → 0.37.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 +33 -0
- package/README.md +7 -7
- package/dist/docs/internals/context.md +6 -5
- package/dist/docs/internals/core-beliefs.md +2 -2
- package/dist/docs/internals/hooks.md +16 -11
- package/dist/docs/internals/mechanical-invariants.md +4 -4
- package/dist/docs/internals/testing.md +1 -1
- package/dist/docs/public/README.md +11 -11
- package/dist/docs/public/{auth-and-route-protection.md → advanced/auth-and-route-protection.md} +5 -4
- package/dist/docs/public/{cli-build-and-debugging.md → advanced/cli-build-and-debugging.md} +2 -1
- package/dist/docs/public/{context-control.md → advanced/context-control.md} +1 -0
- package/dist/docs/public/{evals.md → advanced/evals.md} +1 -0
- package/dist/docs/public/{faqs.md → advanced/faqs.md} +5 -5
- package/dist/docs/public/{hooks.md → advanced/hooks.md} +19 -23
- package/dist/docs/public/{instrumentation.md → advanced/instrumentation.md} +1 -0
- package/dist/docs/public/advanced/meta.json +19 -0
- package/dist/docs/public/{project-layout.md → advanced/project-layout.md} +1 -0
- package/dist/docs/public/{runs-and-streaming.md → advanced/runs-and-streaming.md} +1 -0
- package/dist/docs/public/{session-context.md → advanced/session-context.md} +26 -27
- package/dist/docs/public/{typescript-api.md → advanced/typescript-api.md} +11 -11
- package/dist/docs/public/{vercel-deployment.md → advanced/vercel-deployment.md} +1 -0
- package/dist/docs/public/{workspace.md → advanced/workspace.md} +1 -0
- package/dist/docs/public/channels/{README.md → index.md} +2 -2
- package/dist/docs/public/channels/slack.md +3 -3
- package/dist/docs/public/meta.json +1 -14
- package/dist/docs/public/sandbox.md +9 -11
- package/dist/docs/public/schedules.md +1 -1
- package/dist/docs/public/skills.md +3 -4
- package/dist/docs/public/subagents.md +1 -1
- package/dist/docs/public/tools.md +13 -17
- package/dist/src/channel/session.d.ts +3 -29
- package/dist/src/channel/session.js +1 -1
- package/dist/src/context/accessors.d.ts +0 -25
- package/dist/src/context/accessors.js +1 -1
- package/dist/src/context/build-callback-context.d.ts +8 -0
- package/dist/src/context/build-callback-context.js +1 -0
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +2 -2
- package/dist/src/evals/define-eval-suite.d.ts +3 -2
- package/dist/src/evals/types.d.ts +38 -12
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/sandbox/bash-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/bash-tool.js +1 -1
- package/dist/src/execution/sandbox/glob-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/glob-tool.js +3 -3
- package/dist/src/execution/sandbox/grep-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/grep-tool.js +3 -3
- package/dist/src/execution/sandbox/read-file-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/read-file-tool.js +1 -1
- package/dist/src/execution/sandbox/write-file-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/write-file-tool.js +1 -1
- package/dist/src/execution/skills/types.d.ts +1 -1
- package/dist/src/execution/tool-compaction.js +1 -1
- package/dist/src/harness/code-mode-approval.js +1 -1
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/step-hooks.d.ts +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/workflow-bundle/builder.js +2 -2
- package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/index.js +1 -1
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/manager.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/worker-source.js +408 -0
- package/dist/src/packages/ash-scaffold/src/channels.js +2 -12
- package/dist/src/packages/ash-scaffold/src/pnpm-workspace.js +11 -0
- package/dist/src/packages/ash-scaffold/src/project.js +1 -1
- package/dist/src/public/channels/discord/defaults.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.d.ts +4 -4
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/slack/defaults.js +4 -4
- package/dist/src/public/channels/slack/slackChannel.d.ts +4 -4
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/defaults.js +3 -3
- package/dist/src/public/channels/teams/teamsChannel.d.ts +4 -4
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/defaults.js +2 -2
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +4 -4
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/defaults.js +2 -2
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +4 -4
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/context/index.d.ts +3 -2
- package/dist/src/public/context/index.js +1 -1
- package/dist/src/public/definitions/agent.d.ts +2 -1
- package/dist/src/public/definitions/callback-context.d.ts +22 -0
- package/dist/src/public/definitions/callback-context.js +1 -0
- package/dist/src/public/definitions/defineChannel.d.ts +16 -4
- package/dist/src/public/definitions/defineChannel.js +1 -1
- package/dist/src/public/definitions/exact.d.ts +7 -0
- package/dist/src/public/definitions/exact.js +1 -0
- package/dist/src/public/definitions/hook.d.ts +10 -49
- package/dist/src/public/definitions/instructions.d.ts +2 -1
- package/dist/src/public/definitions/instrumentation.d.ts +2 -1
- package/dist/src/public/definitions/schedule.d.ts +12 -2
- package/dist/src/public/definitions/skill.d.ts +2 -1
- package/dist/src/public/definitions/tool.d.ts +14 -15
- package/dist/src/public/hooks/index.d.ts +1 -1
- package/dist/src/public/sandbox/index.d.ts +0 -1
- package/dist/src/public/sandbox/index.js +1 -1
- package/dist/src/public/skills/index.d.ts +0 -1
- package/dist/src/public/skills/index.js +1 -1
- package/dist/src/public/tools/defaults.js +1 -1
- package/dist/src/public/tools/define-bash-tool.js +1 -1
- package/dist/src/public/tools/define-glob-tool.js +1 -1
- package/dist/src/public/tools/define-grep-tool.js +1 -1
- package/dist/src/public/tools/define-read-file-tool.js +1 -1
- package/dist/src/public/tools/define-write-file-tool.js +1 -1
- package/dist/src/public/tools/index.d.ts +2 -1
- package/dist/src/public/tools/internal.d.ts +4 -0
- package/dist/src/public/tools/internal.js +1 -1
- package/dist/src/runtime/framework-tools/bash.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search.js +1 -1
- package/dist/src/runtime/framework-tools/connection-tools.js +1 -1
- package/dist/src/runtime/framework-tools/file-state.d.ts +2 -2
- package/dist/src/runtime/framework-tools/file-state.js +1 -1
- package/dist/src/runtime/framework-tools/glob.js +1 -1
- package/dist/src/runtime/framework-tools/grep.js +1 -1
- package/dist/src/runtime/framework-tools/read-file.js +2 -2
- package/dist/src/runtime/framework-tools/skill.js +1 -1
- package/dist/src/runtime/framework-tools/todo.js +1 -1
- package/dist/src/runtime/framework-tools/write-file.js +1 -1
- package/dist/src/runtime/governance/auth/types.d.ts +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/sandbox/state.d.ts +1 -1
- package/package.json +2 -2
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/manager.js +0 -1
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/worker-source.js +0 -1153
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime-assets.js +0 -1
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/approval-continuation.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/approval-response.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/code-mode-tool.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/continuation-capability.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/errors.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/fetch-policy.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/host-interrupt.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/interrupt-continuation.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/options.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/run-code-mode.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/runtime/max-workers.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/serialization.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/source-cache.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/telemetry.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/tool-invocation.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/tool-prompt.js +0 -0
|
@@ -84,28 +84,39 @@ export interface AshEvalScorerArgs {
|
|
|
84
84
|
* Return `null` to skip scoring for a case (e.g. when expected is absent).
|
|
85
85
|
*/
|
|
86
86
|
export type AshEvalScorer = (args: AshEvalScorerArgs) => AshEvalScorerResult | Promise<AshEvalScorerResult | null> | null;
|
|
87
|
+
export interface AshEvalTaskFields {
|
|
88
|
+
readonly messages?: (testCase: AshEvalCase) => string[];
|
|
89
|
+
readonly parseOutput?: (result: AshEvalTaskResult) => unknown;
|
|
90
|
+
readonly prompt?: (testCase: AshEvalCase) => string;
|
|
91
|
+
}
|
|
87
92
|
/**
|
|
88
93
|
* Declarative task configuration for a suite. The runner owns session
|
|
89
94
|
* lifecycle, stream capture, and derived metadata. Suites only declare how
|
|
90
95
|
* to derive messages and parse outputs.
|
|
91
96
|
*/
|
|
92
|
-
export
|
|
93
|
-
/**
|
|
94
|
-
* Derive a single prompt string from one eval case.
|
|
95
|
-
* Mutually exclusive with `messages`.
|
|
96
|
-
*/
|
|
97
|
-
readonly prompt?: (testCase: AshEvalCase) => string;
|
|
97
|
+
export type AshEvalTask = (AshEvalTaskFields & {
|
|
98
98
|
/**
|
|
99
99
|
* Derive an ordered list of messages for a multi-turn eval.
|
|
100
100
|
* Mutually exclusive with `prompt`.
|
|
101
101
|
*/
|
|
102
|
-
readonly messages
|
|
102
|
+
readonly messages: (testCase: AshEvalCase) => string[];
|
|
103
|
+
readonly prompt?: never;
|
|
104
|
+
}) | (AshEvalTaskFields & {
|
|
105
|
+
readonly messages?: never;
|
|
106
|
+
/**
|
|
107
|
+
* Derive a single prompt string from one eval case.
|
|
108
|
+
* Mutually exclusive with `messages`.
|
|
109
|
+
*/
|
|
110
|
+
readonly prompt: (testCase: AshEvalCase) => string;
|
|
111
|
+
}) | {
|
|
112
|
+
readonly messages?: never;
|
|
103
113
|
/**
|
|
104
114
|
* Transform the raw task result into the scored output value.
|
|
105
115
|
* When omitted, `result.output` defaults to `result.finalMessage`.
|
|
106
116
|
*/
|
|
107
117
|
readonly parseOutput?: (result: AshEvalTaskResult) => unknown;
|
|
108
|
-
|
|
118
|
+
readonly prompt?: never;
|
|
119
|
+
};
|
|
109
120
|
/**
|
|
110
121
|
* Eval target descriptor.
|
|
111
122
|
*/
|
|
@@ -159,6 +170,18 @@ interface AshEvalSuiteBase {
|
|
|
159
170
|
*/
|
|
160
171
|
readonly thresholds?: Readonly<Record<string, number>>;
|
|
161
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Complete top-level key set accepted by {@link defineEvalSuite}.
|
|
175
|
+
*
|
|
176
|
+
* Used by the definition helper to reject unknown authored keys while the
|
|
177
|
+
* stricter {@link AshEvalSuiteInput} union enforces `load`/`cases`
|
|
178
|
+
* exclusivity.
|
|
179
|
+
*/
|
|
180
|
+
export interface AshEvalSuiteInputFields extends Omit<AshEvalSuiteBase, "task"> {
|
|
181
|
+
readonly cases?: readonly AshEvalCase[];
|
|
182
|
+
readonly task?: AshEvalTaskFields;
|
|
183
|
+
load?(): Promise<AshEvalCase[]>;
|
|
184
|
+
}
|
|
162
185
|
/**
|
|
163
186
|
* Full suite input. Authors pass this to `defineEvalSuite()`.
|
|
164
187
|
*
|
|
@@ -167,12 +190,15 @@ interface AshEvalSuiteBase {
|
|
|
167
190
|
* function internally. Suite identity is derived from the file path —
|
|
168
191
|
* authors do not specify an `id` or `name`.
|
|
169
192
|
*/
|
|
170
|
-
export
|
|
193
|
+
export type AshEvalSuiteInput = (AshEvalSuiteBase & {
|
|
194
|
+
readonly cases?: never;
|
|
171
195
|
/** Load cases dynamically. Mutually exclusive with `cases`. */
|
|
172
|
-
load
|
|
196
|
+
load(): Promise<AshEvalCase[]>;
|
|
197
|
+
}) | (AshEvalSuiteBase & {
|
|
173
198
|
/** Static inline cases. Mutually exclusive with `load`. */
|
|
174
|
-
readonly cases
|
|
175
|
-
|
|
199
|
+
readonly cases: readonly AshEvalCase[];
|
|
200
|
+
load?: never;
|
|
201
|
+
});
|
|
176
202
|
/**
|
|
177
203
|
* Suite returned by `defineEvalSuite()`. Carries no `id` yet — discovery
|
|
178
204
|
* stamps the path-derived id on at import time to produce a full
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{jsonSchema}from"ai";import{createToolLoopHarness}from"#harness/tool-loop.js";import{resolveRuntimeModelReference}from"#runtime/agent/resolve-model.js";import{findRegisteredRuntimeTool}from"#runtime/tools/registry.js";import{createToolCompactionHandler}from"#execution/tool-compaction.js";const log=createLogger(`execution.node-step`);function createExecutionNodeStep(e){let t=createRuntimeModelResolver(e.compiledArtifactsSource),n=createNodeHarnessTools({node:e.node}),
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{jsonSchema}from"ai";import{createToolLoopHarness}from"#harness/tool-loop.js";import{resolveRuntimeModelReference}from"#runtime/agent/resolve-model.js";import{findRegisteredRuntimeTool}from"#runtime/tools/registry.js";import{createToolCompactionHandler}from"#execution/tool-compaction.js";const log=createLogger(`execution.node-step`);function createExecutionNodeStep(e){let t=createRuntimeModelResolver(e.compiledArtifactsSource),n=createNodeHarnessTools({node:e.node}),r=collectResolvedTools(e.node),a=createToolCompactionHandler(r),o=collectRetentionPolicies(r);return createToolLoopHarness({capabilities:e.capabilities,emit:e.emit,mode:e.mode,onCompaction:a,resolveModel:t,retentionPolicies:o,runtimeIdentity:buildRuntimeIdentity(e.node),tools:n})}function buildRuntimeIdentity(e){let n=resolveInstalledPackageInfo(),r={agentId:e.turnAgent.id,agentName:e.agent.config?.name,ashVersion:n.version,modelId:e.turnAgent.model.id},i=process.env.VERCEL_GIT_COMMIT_SHA?.trim(),a=process.env.VERCEL_GIT_COMMIT_REF?.trim(),o=process.env.VERCEL_DEPLOYMENT_CREATED_AT?.trim();return i||a||o?{...r,build:{deployedAt:o||void 0,gitBranch:a||void 0,gitSha:i||void 0}}:r}function createRuntimeModelResolver(e){return t=>resolveRuntimeModelReference(t,{compiledArtifactsSource:e})}function collectResolvedTools(e){return[...e.toolRegistry.toolsByName.values()].map(e=>e.definition)}function collectRetentionPolicies(e){let t=new Map;for(let n of e){let e=n.retentionPolicy;e===void 0||e===`auto`||t.set(n.name,e)}return t}function createNodeHarnessTools(e){let t=new Map;for(let n of e.node.turnAgent.tools){let r=resolveHarnessToolDefinition({node:e.node,tool:n});r!==null&&t.set(n.name,r)}return t}function resolveHarnessToolDefinition(e){if(e.tool.kind===`subagent`)return{description:e.tool.description??``,inputSchema:jsonSchema(e.tool.inputSchema??{}),name:e.tool.name,runtimeAction:{kind:`subagent-call`,nodeId:e.tool.nodeId,subagentName:e.tool.name}};if(e.tool.kind===`remote`)return{description:e.tool.description??``,inputSchema:jsonSchema(e.tool.inputSchema??{}),name:e.tool.name,runtimeAction:{kind:`remote-agent-call`,nodeId:e.tool.nodeId,remoteAgentName:e.tool.name,subagentName:e.tool.name}};let t=findRegisteredRuntimeTool(e.node.toolRegistry,e.tool.name);if(t===null)return log.warn(`declared tool is not registered — omitting from toolset`,{toolName:e.tool.name,nodeId:e.node.nodeId}),null;let i=t.definition,a=i.sourceId.startsWith(`ash:`),s=i.execute;return{approvalKey:i.approvalKey,description:i.description,execute:s===void 0?void 0:a?s:e=>s(e,buildCallbackContext()),inputSchema:i.inputStandardSchema??jsonSchema(i.inputSchema??{}),name:i.name,needsApproval:i.needsApproval,toModelOutput:i.toModelOutput}}export{createExecutionNodeStep,createNodeHarnessTools};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SandboxSession } from "#shared/sandbox-session.js";
|
|
1
2
|
/**
|
|
2
3
|
* Typed input accepted by {@link executeBashOnSandbox}.
|
|
3
4
|
*/
|
|
@@ -26,4 +27,4 @@ export interface BashResult {
|
|
|
26
27
|
* `defineBashTool`. Centralizing the executor here keeps the error
|
|
27
28
|
* messages and result shape identical across all bash-style tools.
|
|
28
29
|
*/
|
|
29
|
-
export declare function executeBashOnSandbox(args: BashInput): Promise<BashResult>;
|
|
30
|
+
export declare function executeBashOnSandbox(sandbox: SandboxSession, args: BashInput): Promise<BashResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{truncateTail}from"#execution/sandbox/truncate-output.js";async function executeBashOnSandbox(e,t){let n=await e.run({command:t.command}),r=truncateTail(n.stdout),i=truncateTail(n.stderr),a=r.truncated||i.truncated,o=r.output;r.truncated&&(o=`[stdout truncated: showing last ${r.outputLines} of ${r.totalLines} lines]\n`+o);let s=i.output;return i.truncated&&(s=`[stderr truncated: showing last ${i.outputLines} of ${i.totalLines} lines]\n`+s),{exitCode:n.exitCode,stderr:s,stdout:o,truncated:a}}export{executeBashOnSandbox};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SandboxSession } from "#shared/sandbox-session.js";
|
|
1
2
|
/**
|
|
2
3
|
* Typed input accepted by {@link executeGlobOnSandbox}.
|
|
3
4
|
*/
|
|
@@ -18,4 +19,4 @@ export interface GlobResult {
|
|
|
18
19
|
/**
|
|
19
20
|
* Searches for files matching a glob pattern inside the sandbox.
|
|
20
21
|
*/
|
|
21
|
-
export declare function executeGlobOnSandbox(args: GlobInput): Promise<GlobResult>;
|
|
22
|
+
export declare function executeGlobOnSandbox(sandbox: SandboxSession, args: GlobInput): Promise<GlobResult>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`).filter(e=>e.length>0),f=d.length>
|
|
3
|
-
`),count:m.length,path:
|
|
1
|
+
import{MAX_OUTPUT_BYTES}from"#execution/sandbox/truncate-output.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{normalizeModelPath}from"#runtime/framework-tools/file-state.js";import{validateAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{ripgrepIsAvailable}from"#execution/sandbox/ripgrep-probe.js";async function executeGlobOnSandbox(t,a){let o=a.path??`/workspace`;validateAbsoluteFilePath(o);let s=normalizeModelPath(o),c=Math.min(Math.max(1,a.limit??100),1e3),l=await ripgrepIsAvailable(t)?buildRipgrepCommand({normalizedPath:s,pattern:a.pattern}):buildPosixFindCommand({normalizedPath:s,pattern:a.pattern}),u=await t.run({command:l});if(u.exitCode!==0&&u.exitCode!==1)throw buildGlobExecutionError(l,u.exitCode,u.stderr);let d=u.stdout.split(`
|
|
2
|
+
`).filter(e=>e.length>0),f=d.length>c,p=f?d.slice(0,c):d,m=[],h=0,g=!1;for(let t of p){let r=normalizeModelPath(t),i=Buffer.byteLength(r,`utf8`)+1;if(h+i>MAX_OUTPUT_BYTES&&m.length>0){g=!0;break}m.push(r),h+=i}if(m.length===0)return{content:`No files found`,count:0,path:s,truncated:!1};let _=f||g,v=[...m];return _&&(v.push(``),v.push(`(Results truncated: showing first ${m.length} results out of more. Use a more specific path or pattern to narrow results.)`)),{content:v.join(`
|
|
3
|
+
`),count:m.length,path:s,truncated:_}}function buildRipgrepCommand(e){return[`rg --files --hidden`,`--glob '!.git/*'`,`--glob ${shellQuote(e.pattern)}`,`-- ${shellQuote(e.normalizedPath)}`].join(` `)}function buildPosixFindCommand(e){let n=translateGlobToFindPattern(e.pattern),r=n.includes(`/`)?`-path ${shellQuote(`*/${n}`)}`:`-name ${shellQuote(n)}`;return[`find ${shellQuote(e.normalizedPath)}`,`-type f`,`-not -path '*/.git/*'`,r].join(` `)}function translateGlobToFindPattern(e){let t=e.replaceAll(`**`,`*`);for(;t.startsWith(`*/`);)t=t.slice(2);return t}function buildGlobExecutionError(e,t,n){let r=n.trim(),i=r.length>0?r:`no stderr output`;return Error(`glob failed (exit ${t}): ${i}\nCommand: ${e}`)}export{executeGlobOnSandbox};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SandboxSession } from "#shared/sandbox-session.js";
|
|
1
2
|
/**
|
|
2
3
|
* Typed input accepted by {@link executeGrepOnSandbox}.
|
|
3
4
|
*/
|
|
@@ -22,4 +23,4 @@ export interface GrepResult {
|
|
|
22
23
|
/**
|
|
23
24
|
* Searches file contents for a pattern inside the sandbox.
|
|
24
25
|
*/
|
|
25
|
-
export declare function executeGrepOnSandbox(args: GrepInput): Promise<GrepResult>;
|
|
26
|
+
export declare function executeGrepOnSandbox(sandbox: SandboxSession, args: GrepInput): Promise<GrepResult>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`),i=[],a=0,o=0,s=!1;for(let
|
|
3
|
-
`);if(c){let
|
|
1
|
+
import{MAX_OUTPUT_BYTES,capLineLength}from"#execution/sandbox/truncate-output.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{normalizeModelPath}from"#runtime/framework-tools/file-state.js";import{validateAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{ripgrepIsAvailable}from"#execution/sandbox/ripgrep-probe.js";async function executeGrepOnSandbox(e,t){let n=t.path??`/workspace`;validateAbsoluteFilePath(n);let o=normalizeModelPath(n),s=Math.min(Math.max(1,t.limit??100),1e3),c=t.context!==void 0&&t.context>0?t.context:0,l=await ripgrepIsAvailable(e)?buildRipgrepCommand({contextLines:c,effectiveLimit:s,glob:t.glob,ignoreCase:t.ignoreCase??!1,literal:t.literal??!1,normalizedPath:o,pattern:t.pattern}):buildPosixGrepCommand({contextLines:c,effectiveLimit:s,glob:t.glob,ignoreCase:t.ignoreCase??!1,literal:t.literal??!1,normalizedPath:o,pattern:t.pattern}),u=await e.run({command:l});if(u.exitCode!==0&&u.exitCode!==1)throw buildGrepExecutionError(l,u.exitCode,u.stderr);let d=u.stdout;return d.trim().length===0?{content:`No matches found`,matchCount:0,path:o,truncated:!1}:processOutput({effectiveLimit:s,normalizedPath:o,stdout:d})}function buildRipgrepCommand(e){let t=[`rg`,`--line-number`,`--color=never`,`--hidden`,`--glob '!.git/*'`];return e.ignoreCase&&t.push(`--ignore-case`),e.literal&&t.push(`--fixed-strings`),e.glob!==void 0&&t.push(`--glob ${shellQuote(e.glob)}`),e.contextLines>0&&t.push(`--context ${e.contextLines}`),t.push(`--max-count ${e.effectiveLimit}`),t.push(`--`),t.push(shellQuote(e.pattern)),t.push(shellQuote(e.normalizedPath)),t.join(` `)}function buildPosixGrepCommand(e){let t=[`grep`,`-r`,`-n`,`--color=never`,`--exclude-dir=.git`];return e.ignoreCase&&t.push(`-i`),e.literal?t.push(`-F`):t.push(`-E`),e.glob!==void 0&&t.push(`--include=${shellQuote(e.glob)}`),e.contextLines>0&&t.push(`-C ${e.contextLines}`),t.push(`-m ${e.effectiveLimit}`),t.push(`--`),t.push(shellQuote(e.pattern)),t.push(shellQuote(e.normalizedPath)),t.join(` `)}function processOutput(n){let r=n.stdout.split(`
|
|
2
|
+
`),i=[],a=0,o=0,s=!1;for(let n of r){if(n.length===0&&r.indexOf(n)===r.length-1)continue;n!==`--`&&n.length>0&&/^.+:\d+:/.test(n)&&o++;let c=capLineLength(n),l=Buffer.byteLength(c,`utf8`)+1;if(a+l>MAX_OUTPUT_BYTES&&i.length>0){s=!0;break}i.push(c),a+=l}let c=s||o>=n.effectiveLimit,l=i.join(`
|
|
3
|
+
`);if(c){let e=[];o>=n.effectiveLimit&&e.push(`Match limit reached (${n.effectiveLimit}). Use a larger limit or more specific pattern.`),s&&e.push(`Output truncated due to size. Use a more specific path or pattern.`),l+=`\n\n[${e.join(` `)}]`}return{content:l,matchCount:o,path:n.normalizedPath,truncated:c}}function buildGrepExecutionError(e,t,n){let r=n.trim(),i=r.length>0?r:`no stderr output`;return Error(`grep failed (exit ${t}): ${i}\nCommand: ${e}`)}export{executeGrepOnSandbox};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SandboxSession } from "#shared/sandbox-session.js";
|
|
1
2
|
/**
|
|
2
3
|
* Typed input accepted by {@link executeReadFileOnSandbox}.
|
|
3
4
|
*/
|
|
@@ -24,4 +25,4 @@ export interface ReadFileResult {
|
|
|
24
25
|
* Used by the framework `read_file` tool and by author tools constructed
|
|
25
26
|
* via `defineReadFileTool`.
|
|
26
27
|
*/
|
|
27
|
-
export declare function executeReadFileOnSandbox(args: ReadFileInput): Promise<ReadFileResult>;
|
|
28
|
+
export declare function executeReadFileOnSandbox(sandbox: SandboxSession, args: ReadFileInput): Promise<ReadFileResult>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{loadContext}from"#context/container.js";import{
|
|
1
|
+
import{loadContext}from"#context/container.js";import{MAX_OUTPUT_BYTES,capLineLength}from"#execution/sandbox/truncate-output.js";import{buildReadFileTargetKey,createReadFileStamp,normalizeModelPath,setReadFileStamp}from"#runtime/framework-tools/file-state.js";import{validateAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";async function executeReadFileOnSandbox(r,i){let{filePath:a,offset:o,limit:s}=i;validateAbsoluteFilePath(a);let c=normalizeModelPath(a),l=o??1,u=s??2e3;if(l<1)throw Error(`offset must be >= 1. Received: ${l}.`);let d=await r.readTextFile({path:a});if(d===null)throw Error(`File not found: ${a}. Verify the path exists and is accessible in the sandbox.`);if(d.includes(`\0`))throw Error(`File "${a}" contains NUL bytes and appears to be a binary file. read_file only supports text files.`);let f=d.split(`
|
|
2
2
|
`),p=f.length>0&&f[f.length-1]===``?f.length-1:f.length;if(p===0){if(l>1)throw Error(`offset ${l} is past the end of the file (0 lines). Use the default offset to read an empty file.`);return{content:``,path:c,totalLines:0,truncated:!1}}if(l>p)throw Error(`offset ${l} is past the end of the file (${p} lines).`);let m=createReadFileStamp({content:d,filePath:c}),h=buildReadFileTargetKey(c);setReadFileStamp(loadContext(),h,m);let g=l-1,_=Math.min(g+u,p),v=f.slice(g,_),y=[],b=0,x=!1;for(let e=0;e<v.length;e++){let t=`${l+e}: ${capLineLength(v[e]??``)}`,n=Buffer.byteLength(t,`utf8`)+1;if(b+n>MAX_OUTPUT_BYTES&&y.length>0){x=!0;break}y.push(t),b+=n}let S=y.join(`
|
|
3
3
|
`),C=l+y.length-1;return C<p||x?{content:S,nextOffset:C+1,path:c,totalLines:p,truncated:!0}:{content:S,path:c,totalLines:p,truncated:!1}}export{executeReadFileOnSandbox};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SandboxSession } from "#shared/sandbox-session.js";
|
|
1
2
|
/**
|
|
2
3
|
* Typed input accepted by {@link executeWriteFileOnSandbox}.
|
|
3
4
|
*/
|
|
@@ -19,4 +20,4 @@ export interface WriteFileResult {
|
|
|
19
20
|
* Used by the framework `write_file` tool and by author tools
|
|
20
21
|
* constructed via `defineWriteFileTool`.
|
|
21
22
|
*/
|
|
22
|
-
export declare function executeWriteFileOnSandbox(args: WriteFileInput): Promise<WriteFileResult>;
|
|
23
|
+
export declare function executeWriteFileOnSandbox(sandbox: SandboxSession, args: WriteFileInput): Promise<WriteFileResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{loadContext}from"#context/container.js";import{
|
|
1
|
+
import{loadContext}from"#context/container.js";import{ReadFileStateKey,buildReadFileTargetKey,createReadFileStamp,normalizeModelPath,setReadFileStamp}from"#runtime/framework-tools/file-state.js";import{validateAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";async function executeWriteFileOnSandbox(e,t){let{filePath:n,content:r}=t;validateAbsoluteFilePath(n);let i=loadContext(),a=normalizeModelPath(n),o=buildReadFileTargetKey(a),s=await e.readTextFile({path:n});if(s===null)return await e.writeTextFile({content:r,path:n}),setReadFileStamp(i,o,createReadFileStamp({content:r,filePath:a})),{existed:!1,path:a};let c=i.ensure(ReadFileStateKey,()=>({byTarget:{}})).byTarget[o];if(c===void 0)throw Error(`You must read file ${n} before overwriting it. Use the read_file tool first.`);let l=createReadFileStamp({content:s,filePath:a});if(l.contentHash!==c.contentHash||l.byteLength!==c.byteLength)throw Error(`File ${n} has been modified since it was last read. Please read the file again before modifying it.`);return await e.writeTextFile({content:r,path:n}),setReadFileStamp(i,o,createReadFileStamp({content:r,filePath:a})),{existed:!0,path:a}}export{executeWriteFileOnSandbox};
|
|
@@ -8,7 +8,7 @@ export interface SkillFile {
|
|
|
8
8
|
text(): Promise<string>;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Handle to one authored skill, returned by
|
|
11
|
+
* Handle to one authored skill, returned by `ctx.getSkill()`.
|
|
12
12
|
*
|
|
13
13
|
* Provides metadata and file access for skill packages.
|
|
14
14
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{buildCallbackContext}from"#context/build-callback-context.js";const log=createLogger(`execution.tool-compaction`);function createToolCompactionHandler(e){let n=e.filter(e=>e.onCompact!==void 0);return async e=>{if(n.length===0)return{messages:[],session:e};let r=buildCallbackContext(),i=new AbortController().signal,a=[],o=e.state??{},s=!1;for(let t of n){let n=t.onCompact;if(n===void 0)continue;let c;try{c=await n({history:e.history,signal:i},r)??{}}catch(e){log.warn(`compaction hook for tool "${t.name}" threw and was skipped`,{toolName:t.name,error:e});continue}c.messages!==void 0&&c.messages.length>0&&a.push(...c.messages),c.sessionPatch!==void 0&&(o={...o,...c.sessionPatch},s=!0)}return{messages:a,session:s?{...e,state:o}:e}}}export{createToolCompactionHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CodeModeProtocolError}from"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.
|
|
1
|
+
import{CodeModeProtocolError}from"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/errors.js";import{isCodeModeApprovalInterrupt}from"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/approval-continuation.js";import"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/index.js";const PENDING_CODE_MODE_APPROVAL_KEY=`ash.harness.pendingCodeModeApproval`;function getPendingCodeModeApproval(e){let r=e?.[PENDING_CODE_MODE_APPROVAL_KEY];if(isRecord(r)&&!(!isCodeModeApprovalInterrupt(r.interrupt)||!Array.isArray(r.responseMessages)))return{interrupt:r.interrupt,responseMessages:r.responseMessages}}function setPendingCodeModeApproval(e){return{...e.session,state:{...e.session.state,[PENDING_CODE_MODE_APPROVAL_KEY]:{interrupt:e.interrupt,responseMessages:e.responseMessages}}}}function clearPendingCodeModeApproval(e){if(e.state?.[PENDING_CODE_MODE_APPROVAL_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_CODE_MODE_APPROVAL_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function replaceCodeModeApprovalInterruptResult(t,n,r){let i=0,a=toModelToolOutput(r),o=t.map(t=>{let r=t;if(!Array.isArray(r.content))return t;let o=!1,s=r.content.map(t=>{if(!isRecord(t)||t.type!==`tool-result`||t.toolCallId!==n.continuation.outerToolCallId)return t;if(!toolResultOutputContainsApprovalInterrupt(t.output,n.approvalId))throw new CodeModeProtocolError(`Outer code_mode tool result ${n.continuation.outerToolCallId} does not contain pending approval ${n.approvalId}.`,{approvalId:n.approvalId,outerToolCallId:n.continuation.outerToolCallId});return i++,o=!0,{...t,output:a}});return o?{...t,content:s}:t});if(i!==1)throw new CodeModeProtocolError(`Expected one outer code_mode approval result replacement for ${n.approvalId}, found ${i}.`,{approvalId:n.approvalId,outerToolCallId:n.continuation.outerToolCallId,replacements:i});return o}function splitCodeModeOuterResponseMessages(e){let t=e.messages.findIndex(t=>messageContainsToolResult(t,e.outerToolCallId));if(t<0)return{promptMessages:e.messages,responseMessages:[]};let n=t-1,r=n>=0&&messageContainsToolCall(e.messages[n],e.outerToolCallId)?n:t;return{promptMessages:e.messages.slice(0,r),responseMessages:e.messages.slice(r)}}function messageContainsToolCall(e,t){return e?.role!==`assistant`||!Array.isArray(e.content)?!1:e.content.some(e=>typeof e==`object`&&!!e&&`type`in e&&e.type===`tool-call`&&`toolCallId`in e&&e.toolCallId===t)}function messageContainsToolResult(e,t){return e?.role!==`tool`||!Array.isArray(e.content)?!1:e.content.some(e=>e.type===`tool-result`&&`toolCallId`in e&&e.toolCallId===t)}function toolResultOutputContainsApprovalInterrupt(e,t){return readApprovalInterruptValue(e)?.approvalId===t}function readApprovalInterruptValue(e){if(isCodeModeApprovalInterrupt(e))return e;if(isRecord(e)&&(e.type===`json`||e.type===`text`)&&Object.hasOwn(e,`value`))return readApprovalInterruptValue(e.value)}function toModelToolOutput(e){return typeof e==`string`?{type:`text`,value:e}:{type:`json`,value:e===void 0?null:e}}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{clearPendingCodeModeApproval,getPendingCodeModeApproval,replaceCodeModeApprovalInterruptResult,setPendingCodeModeApproval,splitCodeModeOuterResponseMessages};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createCodeModeTool}from"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.
|
|
1
|
+
import{createCodeModeTool}from"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/code-mode-tool.js";import"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/index.js";import"ai";import{markCodeModeToolExecutionOptions}from"#runtime/framework-tools/code-mode-connection-auth.js";import{resolveConnectionToolsFromState}from"#runtime/framework-tools/connection-tools.js";import{CODE_MODE_TOOL_NAME}from"#shared/code-mode.js";import{buildToolSet}from"#harness/tools.js";function isCodeModeEnabled(e=process.env){return e.CODE_MODE===`1`}function createAshCodeModeOptions(e={}){let t={approval:{mode:`interrupt`}};return e.lifecycle!==void 0&&(t.lifecycle=e.lifecycle),t}function applyCodeModeToToolSet(t){let n={},i={};for(let[e,r]of Object.entries(t.tools)){if(isDirectTool(r,t.harnessTools.get(e))){i[e]=r;continue}n[e]=wrapHostToolForCodeMode(r)}return Object.keys(n).length>0&&(i[CODE_MODE_TOOL_NAME]=createCodeModeTool(n,createAshCodeModeOptions({lifecycle:t.lifecycle}))),{hostTools:n,modelTools:i}}async function buildCodeModeHostTools(e){let t=buildToolSet({approvedTools:e.approvedTools,capabilities:e.capabilities,tools:e.tools});if(e.registry!==void 0&&e.discovered!==void 0){let r=await resolveConnectionToolsFromState(e.registry,e.discovered,{approvedTools:e.approvedTools,authMode:`code-mode`,codeModeMetadataOnlyConnectionNames:e.codeModeMetadataOnlyConnectionNames,existingToolNames:new Set(Object.keys(t))});Object.assign(t,r)}return applyCodeModeToToolSet({harnessTools:e.tools,tools:t}).hostTools}function isDirectTool(e,t){return e.execute===void 0||t?.runtimeAction!==void 0}function wrapHostToolForCodeMode(e){let n=e.execute,r=e.toModelOutput;return n===void 0?e:{...e,execute:async(e,i)=>{let a=await resolveExecuteOutput(n(e,markCodeModeToolExecutionOptions(i)));if(r===void 0)return a;let o=await r({output:a});return isModelOutput(o)?o.value:o}}}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,isCodeModeEnabled};
|
|
@@ -71,7 +71,7 @@ interface StepHooks {
|
|
|
71
71
|
* own all step-internal work: emission, compaction, and prompt caching.
|
|
72
72
|
*
|
|
73
73
|
* The harness passes these hooks to `ToolLoopAgent` and reads the
|
|
74
|
-
* results via `
|
|
74
|
+
* results via `stepResult` after the agent finishes.
|
|
75
75
|
*/
|
|
76
76
|
export declare function buildStepHooks(input: StepHooksInput): StepHooks;
|
|
77
77
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{continueCodeModeApproval,getCodeModeApprovalResponse,isCodeModeApprovalInterrupt,toCodeModeApprovalMessages}from"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/approval-continuation.js";import{continueCodeModeInterrupt,getCodeModeInterrupt,replaceCodeModeInterruptResult,unwrapCodeModeResult}from"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/interrupt-continuation.js";import"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/index.js";import{createErrorId,createLogger,formatError,logError,recordErrorOnSpan}from"#internal/logging.js";import{createAuthorizationRequiredEvent,createCompactionCompletedEvent,createCompactionRequestedEvent,createInputRequestedEvent}from"#protocol/message.js";import{toErrorMessage}from"#shared/errors.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import"#shared/json.js";import{contextStorage}from"#context/container.js";import{advanceStep,emitFailedStep,emitRecoverableFailedTurn,emitStreamContent,emitTurnEpilogue,emitTurnPreamble,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{ConnectionRegistryKey,DiscoveredConnectionToolsKey}from"#runtime/framework-tools/connection-search.js";import{ToolLoopAgent,isStepCount}from"ai";import{createRuntimeActionRequestFromToolCall,resolvePendingRuntimeActions,setPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{resolveAssistantStepText}from"#harness/messages.js";import{consumeDeferredStepInput,getApprovedTools,hasDeferredStepInput,hasStepInput,resolvePendingInput,setPendingInputBatch}from"#harness/input-requests.js";import{getHookUrl,isAuthorizationSignal,setPendingAuthorization}from"#harness/authorization.js";import{isCodeModeConnectionAuthInterrupt}from"#runtime/framework-tools/code-mode-connection-auth.js";import{resolveConnectionToolsFromState}from"#runtime/framework-tools/connection-tools.js";import{CODE_MODE_TOOL_NAME}from"#shared/code-mode.js";import{buildToolSetWithProviderTools}from"#harness/tools.js";import{ASK_QUESTION_TOOL_NAME}from"#runtime/framework-tools/ask-question.js";import{WEB_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-search.js";import{extractQuestionInputRequests,extractToolApprovalInputRequests}from"#harness/input-extraction.js";import{applyLastToolCacheBreakpoint,detectPromptCachePath,getAnthropicCacheMarker}from"#harness/prompt-cache.js";import{resolveFrameworkToolFromUpstreamType,resolveGatewayPinForWebSearchBackend,resolveWebSearchBackend}from"#harness/provider-tools.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{resolveConnectionPrincipal}from"#runtime/connections/principal.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{hydrateSandboxAttachments,stageAttachmentsToSandbox}from"#harness/attachment-staging.js";import{applyCodeModeToToolSet,buildCodeModeHostTools,createAshCodeModeOptions,isCodeModeEnabled}from"#harness/code-mode.js";import{createCodeModeLifecycle}from"#harness/code-mode-lifecycle.js";import{clearPendingCodeModeApproval,getPendingCodeModeApproval,replaceCodeModeApprovalInterruptResult,setPendingCodeModeApproval}from"#harness/code-mode-approval.js";import{compactMessages,getInputTokenCount,resolveCompactionModel,shouldCompact}from"#harness/compaction.js";import{getInstrumentationConfig}from"#harness/instrumentation-config.js";import{clearPendingCodeModeConnectionAuth,getPendingCodeModeConnectionAuth,setPendingCodeModeConnectionAuth}from"#harness/code-mode-connection-auth-state.js";import{classifyModelCallError,extractModelCallErrorDetails,extractUnsupportedProviderToolTypes,summarizeKnownModelCallConfigError,summarizeKnownModelCallRequestError}from"#harness/model-call-error.js";import{ensureOtelIntegration}from"#harness/otel-integration.js";import{buildStepHooks,emitStepActions,isInvalidToolCall}from"#harness/step-hooks.js";import{pruneToolResults}from"#harness/tool-result-pruning.js";const environment=process.env.NODE_ENV??`unknown`,ashVersion=resolveInstalledPackageInfo().version,log=createLogger(`harness.tool-loop`);function logToolExecutionError(e){e.toolOutput.type===`tool-error`&&logError(log,`tool execution failed`,e.toolOutput.error,{toolName:e.toolCall.toolName,toolCallId:e.toolCall.toolCallId})}function enrichTelemetry(e,t){if(e!==void 0)return{functionId:e.functionId??t,isEnabled:!0,recordInputs:e.recordInputs??!0,recordOutputs:e.recordOutputs??!0}}function buildTelemetryRuntimeContext(e,t){if(e!==void 0)return{...e.metadata,"ash.continuation_token":t.continuationToken,"ash.environment":environment,"ash.session.id":t.sessionId,"ash.version":ashVersion}}function resolveGatewayPinForStep(e){if(e.cachePath.kind!==`gateway-auto`||e.tools[WEB_SEARCH_TOOL_DEFINITION.name]===void 0)return;let t=resolveWebSearchBackend(e.modelReference);return t===null?void 0:resolveGatewayPinForWebSearchBackend(t)??void 0}function buildGatewayAttributionHeaders(e,t){if(typeof e!=`string`)return;let n=t?.agentName??t?.agentId,r=process.env.VERCEL_PROJECT_PRODUCTION_URL||process.env.VERCEL_URL,i=r?`https://${r}`:void 0;if(!n&&!i)return;let a={};return n&&(a[`x-title`]=n),i&&(a[`http-referer`]=i),a}const TURN_TRACE_STATE_KEY=`ash.harness.turnTrace`;function getTurnTraceState(e){return e.state?.[TURN_TRACE_STATE_KEY]}function setTurnTraceState(e,t){let n={traceId:t.traceId,spanId:t.spanId,traceFlags:t.traceFlags};return{...e,state:{...e.state,[TURN_TRACE_STATE_KEY]:n}}}function resolveStepOtelContext(e,t,n){if(t)return trace.setSpan(context.active(),t);if(e){let e=getTurnTraceState(n);if(e){let t=trace.wrapSpanContext({traceId:e.traceId,spanId:e.spanId,traceFlags:e.traceFlags});return trace.setSpan(context.active(),t)}}}function createToolLoopHarness(e){let t=e.emit,n=getInstrumentationConfig();n!==void 0&&ensureOtelIntegration();let r=n===void 0?void 0:trace.getTracer(`ash`),i=e.runtimeIdentity?.agentName;async function runStep(e,t){let a;if(r&&hasStepInput(t)){let t=n?.functionId??i,o={"ash.version":ashVersion,"ash.environment":environment,"ash.session.id":e.sessionId,"ash.continuation_token":e.continuationToken};t&&(o[`ai.telemetry.functionId`]=t),a=r.startSpan(`ai.ash.turn`,{attributes:o})}let o=resolveStepOtelContext(r,a,e),executeStep=()=>executeStepBody(e,t,a);try{return o?await context.with(o,executeStep):await executeStep()}finally{a?.end()}}async function executeStepBody(r,a,o){let s=r;o&&(s=setTurnTraceState(s,o.spanContext()));let l=getHarnessEmissionState(s.state),u=consumeDeferredStepInput({input:a,session:s});s=u.session;let p=await resolvePendingRuntimeActions({emit:t,session:s,stepInput:u.input});if(p.outcome===`unresolved`)return{next:null,session:p.session};s=p.session;let m=resolvePendingInput({history:p.messages,resolveApprovalKey:resolveApprovalKeyFromTools(e.tools),session:s,stepInput:u.input});if(m.outcome===`unresolved`)return{next:null,session:m.session};t&&hasStepInput(a)&&(l=await emitTurnPreamble(t,a??{},l,e.runtimeIdentity),s=setHarnessEmissionState(s,l),o&&o.setAttribute(`ash.turn.id`,l.turnId)),s=m.session;let h=m.messages,g=await continuePendingCodeModeConnectionAuth({capabilities:e.capabilities,config:e,emit:t,emissionState:l,messages:h,runStep,session:s});if(g!==null)return g;let v=await continuePendingCodeModeApproval({capabilities:e.capabilities,config:e,emit:t,emissionState:l,messages:h,runStep,session:s});if(v!==null)return v;if(u.input?.message!==void 0&&!m.deferredMessage){let e=await stageAttachmentsToSandbox(u.input.message);h.push({content:e,role:`user`})}let y=await e.resolveModel(s.agent.modelReference),x=detectPromptCachePath(y),T=x.kind===`anthropic-direct`?getAnthropicCacheMarker():void 0,A=buildGatewayAttributionHeaders(y,e.runtimeIdentity);({messages:h,session:s}=await maybeCompact({emit:t,emissionState:l,headers:A,messages:h,model:y,onCompaction:e.onCompaction,resolveModel:e.resolveModel,session:s,telemetry:enrichTelemetry(n,i)??void 0}));let j=getApprovedTools(s),M=contextStorage.getStore(),N=M?.get(ConnectionRegistryKey),P=M?.get(DiscoveredConnectionToolsKey),F=await hydrateSandboxAttachments(h),I=u.input?.modelContext,L=[],R=[];for(let e of F)e.role===`system`?L.push(e):R.push(e);if(I!==void 0)for(let e of I)e.role===`system`?L.push(e):R.push(e);let z=R,runOneModelCall=async r=>{let a=isCodeModeEnabled(),o=await buildToolSetWithProviderTools({approvedTools:j,capabilities:e.capabilities,disabledProviderTools:r.disabledProviderTools,modelReference:s.agent.modelReference,tools:e.tools});if(N!==void 0&&P!==void 0){let e=await resolveConnectionToolsFromState(N,P,{approvedTools:j,authMode:a?`code-mode`:`direct`,existingToolNames:new Set(Object.keys(o))});Object.assign(o,e)}let c=a?applyCodeModeToToolSet({harnessTools:e.tools,lifecycle:t===void 0?void 0:createCodeModeLifecycle({emit:t,emissionState:l,tools:e.tools}),tools:o}).modelTools:o,u=T?applyLastToolCacheBreakpoint(c,T):c,f=resolveGatewayPinForStep({cachePath:x,modelReference:s.agent.modelReference,tools:u}),p=r.extraSystemNote?[{role:`system`,content:r.extraSystemNote}]:[],m=s.agent.system?[{role:`system`,content:s.agent.system}]:[],h=L.length>0||p.length>0?[...p,...m,...L]:s.agent.system||void 0,g=buildStepHooks({cachePath:x,emit:t,emissionState:l,emitStepStarted:r.suppressStepStartedEmission!==!0,gatewayPinProvider:f,marker:T,session:s}),_=new ToolLoopAgent({headers:A,instructions:h,model:y,onToolExecutionEnd:logToolExecutionError,onError(e){logError(log,`tool-loop stream error`,e.error)},onStepFinish:g.onStepFinish,prepareStep:g.prepareStep,runtimeContext:buildTelemetryRuntimeContext(n,s),stopWhen:isStepCount(1),telemetry:enrichTelemetry(n,i),tools:u});return runModelCallWithRetries(async()=>{if(t){let n=await _.stream({messages:z}),{inlineActionResultCallIds:r,inlineToolResultParts:i}=await emitStreamContent(t,l,n.fullStream),a=await g.stepResult;return await emitStepActions(t,l,a,{excludedActionToolNames:new Set([ASK_QUESTION_TOOL_NAME,CODE_MODE_TOOL_NAME]),inlineActionResultCallIds:r,tools:e.tools}),i.length>0?{content:a.content,finishReason:a.finishReason,response:{...a.response,messages:[{role:`tool`,content:[...i]},...a.response.messages]},text:a.text,toolCalls:a.toolCalls,toolResults:a.toolResults,usage:a.usage}:a}return await _.generate({messages:z}),await g.stepResult},{sessionId:s.sessionId,turnId:l.turnId})},B;try{B=await runOneModelCall({})}catch(e){let n=await attemptUnsupportedProviderToolRecovery({error:e,runOneModelCall,sessionId:s.sessionId,turnId:l.turnId});if(n.outcome===`recovered`)B=n.result;else{let e=n.error;if(o&&recordErrorOnSpan(o,e),!t)throw e;let r=classifyModelCallError(e),i=createErrorId(),a=r===`terminal`?summarizeKnownModelCallConfigError(e):null,u=a===null?summarizeKnownModelCallRequestError(e):null,d=a?.message??u?.message??toErrorMessage(e),p=extractModelCallErrorDetails(e),m=buildModelCallFailureDetails({configSummary:a,error:e,errorId:i,modelCallDetails:p,requestSummary:u}),h=buildModelCallFailureLogFields({error:e,errorId:i,modelCallDetails:p,requestSummary:u,sessionId:s.sessionId,turnId:l.turnId});return r===`terminal`?(a===null?log.error(u?.message??`model call failed terminally`,h):log.error(`${a.name}: ${a.message}`,{errorId:i,sessionId:s.sessionId,turnId:l.turnId}),await emitFailedStep(t,l,{code:`MODEL_CALL_FAILED`,details:m,message:d,sessionId:s.sessionId}),{next:{done:!0,output:``},session:s}):(log.error(u?.message??`model call failed — parking session for retry by the user`,h),l=await emitRecoverableFailedTurn(t,l,{code:`MODEL_CALL_FAILED`,details:m,message:d}),{next:null,session:setHarnessEmissionState(s,l)})}}return handleStepResult({config:e,emit:t,emissionState:l,promptMessages:h,result:B,runStep,session:s})}return runStep}function buildModelCallFailureDetails(e){let{configSummary:t,error:n,errorId:r,modelCallDetails:i,requestSummary:a}=e;return t===null?a===null?{...formatError(n,r),...i}:{errorId:r,message:toErrorMessage(n),name:a.name,...i}:{errorId:r,message:t.message,name:t.name,...i}}function buildModelCallFailureLogFields(e){let t={errorId:e.errorId,sessionId:e.sessionId,turnId:e.turnId};return e.requestSummary===null?{...t,error:e.error}:{...t,details:e.modelCallDetails}}async function attemptUnsupportedProviderToolRecovery(e){let t=extractUnsupportedProviderToolTypes(e.error);if(t.length===0)return{outcome:`failed`,error:e.error};let n=[];for(let e of t){let t=resolveFrameworkToolFromUpstreamType(e);t!==null&&!n.includes(t)&&n.push(t)}if(n.length===0)return{outcome:`failed`,error:e.error};log.warn(`disabling unsupported provider tool(s); retrying step once`,{disabled:n,sessionId:e.sessionId,turnId:e.turnId,upstreamTypes:t});try{return{outcome:`recovered`,result:await e.runOneModelCall({disabledProviderTools:new Set(n),extraSystemNote:buildDisabledToolNote(n),suppressStepStartedEmission:!0})}}catch(e){return{outcome:`failed`,error:e}}}function buildDisabledToolNote(e){let t=e.join(`, `);return`The following ${e.length===1?`tool is`:`tools are`} not available with the current model and has been removed: ${t}. Proceed using the remaining tools or your training knowledge.`}async function handleStepResult(e){let{config:t,emit:r,promptMessages:i,result:o,runStep:s}=e,{emissionState:c,session:l}=e,u=o.response.messages,d=resolveAssistantStepText(u,o.text),f={...l,compaction:createNextCompactionConfig(l.compaction,i,o)},m=getCodeModeInterrupt(o);if(m!==void 0){if(isCodeModeConnectionAuthInterrupt(m))return parkOnCodeModeConnectionAuth({baseSession:f,config:t,emit:r,emissionState:c,interrupt:m,promptMessages:i,responseMessages:u});if(isCodeModeApprovalInterrupt(m))return parkOnCodeModeApproval({baseSession:f,config:t,emit:r,emissionState:c,interrupt:m,promptMessages:i,responseMessages:u})}let h=extractToolApprovalInputRequests({content:o.content??[]}),_=new Set(h.map(e=>e.action.callId)),v=extractQuestionInputRequests({toolCalls:o.toolCalls,excludedCallIds:_}),y=[...h,...v],b=(o.toolCalls??[]).filter(e=>!isInvalidToolCall(e)).filter(e=>t.tools.get(e.toolName)?.runtimeAction!==void 0).map(e=>createRuntimeActionRequestFromToolCall({toolCall:e,tools:t.tools}));if(b.length>0)return{next:null,session:setPendingRuntimeActionBatch({actions:b,event:{sequence:c.sequence,stepIndex:c.stepIndex,turnId:c.turnId},responseMessages:u,session:{...f,history:[...i]}})};if(y.length>0){let e=setPendingInputBatch({requests:y,responseMessages:u,session:{...f,history:[...i]}});return r&&(await r(createInputRequestedEvent({requests:y,sequence:c.sequence,stepIndex:c.stepIndex,turnId:c.turnId})),t.mode===`conversation`&&(c=await emitTurnEpilogue(r,c,t.mode),e=setHarnessEmissionState(e,c))),{next:null,session:e}}let S=(o.toolResults??[]).find(e=>isAuthorizationSignal(e.output));if(S&&isAuthorizationSignal(S.output)){let{challenges:e}=S.output;if(r)for(let t of e)await r(createAuthorizationRequiredEvent({authorization:t.challenge,name:t.name,description:t.challenge.instructions??`Authorization required for ${t.name}`,webhookUrl:t.hookUrl,sequence:c.sequence,stepIndex:c.stepIndex,turnId:c.turnId}));return{next:null,session:setHarnessEmissionState({...f,history:[...i],state:setPendingAuthorization(f.state,{challenges:e})},c)}}let C=pruneToolResults(i,t.retentionPolicies),w=C!==i,E=f.compaction;w&&E.lastKnownInputTokens!==void 0&&(E={recentWindowSize:E.recentWindowSize,threshold:E.threshold});let D=[...C,...u],O={...f,compaction:E,history:D},k=u.at(-1)?.role===`tool`||hasDeferredStepInput(O);return r&&(c=k?advanceStep(c):await emitTurnEpilogue(r,c,t.mode),O=setHarnessEmissionState(O,c)),k?{next:s,session:O}:{next:t.mode===`task`?{done:!0,output:d??``}:null,session:O}}async function continuePendingCodeModeApproval(r){let i=getPendingCodeModeApproval(r.session.state);if(i===void 0)return null;let a=getCodeModeApprovalResponse([...r.messages],i.interrupt);if(a===void 0)return{next:null,session:r.session};let o=contextStorage.getStore(),c=await buildCodeModeHostTools({approvedTools:getApprovedTools(r.session),capabilities:r.capabilities,discovered:o?.get(DiscoveredConnectionToolsKey),registry:o?.get(ConnectionRegistryKey),tools:r.config.tools}),l;try{l=await continueCodeModeApproval({approvalResponse:a,interrupt:i.interrupt,options:createAshCodeModeOptions({lifecycle:r.emit===void 0?void 0:createCodeModeLifecycle({emit:r.emit,emissionState:r.emissionState,skipReplayed:!0,tools:r.config.tools})}),tools:c})}catch(e){logError(log,`code-mode approval continuation failed`,e),l={error:`code_mode_continuation_failed`,message:toErrorMessage(e),retryable:!1}}let u=unwrapCodeModeResult(l),f=u.status===`interrupted`?u.interrupt:u.output,p=replaceCodeModeApprovalInterruptResult([...r.session.history,...i.responseMessages],i.interrupt,f),m=clearPendingCodeModeApproval({...r.session,history:p});if(u.status===`interrupted`){if(isCodeModeConnectionAuthInterrupt(u.interrupt)){let e=r.session.history.length,t=p.slice(0,e),n=p.slice(e);return m={...m,history:t},parkOnCodeModeConnectionAuth({baseSession:m,config:r.config,emit:r.emit,emissionState:r.emissionState,interrupt:u.interrupt,promptMessages:t,responseMessages:n})}if(isCodeModeApprovalInterrupt(u.interrupt)){let e=r.session.history.length,t=p.slice(0,e),n=p.slice(e);return m={...m,history:t},parkOnCodeModeApproval({baseSession:m,config:r.config,emit:r.emit,emissionState:r.emissionState,interrupt:u.interrupt,promptMessages:t,responseMessages:n})}}return{next:r.runStep,session:m}}async function parkOnCodeModeConnectionAuth(e){let{connectionName:t}=e.interrupt.payload,n=(contextStorage.getStore()?.get(ConnectionRegistryKey))?.getConnections().find(e=>e.connectionName===t),r=n?.authorization&&supportsInteractiveAuthorization(n.authorization)?n.authorization:void 0,i=[];if(r){let e=getHookUrl(t);if(e){let a=resolveConnectionPrincipal(t,r),{challenge:o,state:s}=await r.startAuthorization({callbackUrl:e,connection:{url:n?.url??``},principal:a});i.push({name:t,challenge:o,hookUrl:e,state:s})}}if(e.emit)for(let t of i)await e.emit(createAuthorizationRequiredEvent({authorization:t.challenge,name:t.name,description:t.challenge.instructions??`Authorization required for ${t.name}`,webhookUrl:t.hookUrl,sequence:e.emissionState.sequence,stepIndex:e.emissionState.stepIndex,turnId:e.emissionState.turnId}));return{next:null,session:setPendingCodeModeConnectionAuth({interrupt:e.interrupt,responseMessages:e.responseMessages,session:{...e.baseSession,history:[...e.promptMessages],state:setPendingAuthorization(e.baseSession.state,{challenges:i})}})}}async function continuePendingCodeModeConnectionAuth(e){let t=getPendingCodeModeConnectionAuth(e.session.state);if(t===void 0)return null;let r=contextStorage.getStore(),a=new Set,{connectionName:c}=t.interrupt.payload;a.add(c);let l=await buildCodeModeHostTools({approvedTools:getApprovedTools(e.session),capabilities:e.capabilities,codeModeMetadataOnlyConnectionNames:a,discovered:r?.get(DiscoveredConnectionToolsKey),registry:r?.get(ConnectionRegistryKey),tools:e.config.tools}),u=e.emit===void 0?void 0:createCodeModeLifecycle({emit:e.emit,emissionState:e.emissionState,skipReplayed:!0,tools:e.config.tools}),f;try{f=await continueCodeModeInterrupt({interrupt:t.interrupt,resolution:{status:`authorized`},tools:l,options:createAshCodeModeOptions({lifecycle:u})})}catch(e){logError(log,`code-mode interrupt continuation failed`,e),f={error:`code_mode_continuation_failed`,message:toErrorMessage(e),retryable:!1}}let p=unwrapCodeModeResult(f),m=p.status===`interrupted`?p.interrupt:p.output,h=replaceCodeModeInterruptResult([...e.session.history,...t.responseMessages],t.interrupt.pendingContinuation,m),g=clearPendingCodeModeConnectionAuth({...e.session,history:h});if(p.status===`interrupted`){if(isCodeModeConnectionAuthInterrupt(p.interrupt)){let t=e.session.history.length,n=h.slice(0,t),r=h.slice(t);return g={...g,history:n},parkOnCodeModeConnectionAuth({baseSession:g,config:e.config,emit:e.emit,emissionState:e.emissionState,interrupt:p.interrupt,promptMessages:n,responseMessages:r})}if(isCodeModeApprovalInterrupt(p.interrupt)){let t=e.session.history.length,n=h.slice(0,t),r=h.slice(t);return g={...g,history:n},parkOnCodeModeApproval({baseSession:g,config:e.config,emit:e.emit,emissionState:e.emissionState,interrupt:p.interrupt,promptMessages:n,responseMessages:r})}}return{next:e.runStep,session:g}}async function parkOnCodeModeApproval(e){let t=toCodeModeApprovalMessages(e.interrupt),n=extractToolApprovalInputRequests({content:extractAssistantContent(t)}),i=setPendingInputBatch({requests:n,responseMessages:t,session:setPendingCodeModeApproval({interrupt:e.interrupt,responseMessages:e.responseMessages,session:{...e.baseSession,history:[...e.promptMessages]}})});if(e.emit&&(await e.emit(createInputRequestedEvent({requests:n,sequence:e.emissionState.sequence,stepIndex:e.emissionState.stepIndex,turnId:e.emissionState.turnId})),e.config.mode===`conversation`)){let t=await emitTurnEpilogue(e.emit,e.emissionState,e.config.mode);i=setHarnessEmissionState(i,t)}return{next:null,session:i}}function extractAssistantContent(e){let t=[];for(let n of e)n.role===`assistant`&&Array.isArray(n.content)&&t.push(...n.content);return t}function createNextCompactionConfig(e,t,n){let r={recentWindowSize:e.recentWindowSize,threshold:e.threshold};return n.usage?.inputTokens!==void 0&&(r.lastKnownInputTokens=n.usage.inputTokens,r.lastKnownPromptMessageCount=t.length),r}async function maybeCompact(e){let{emit:t,emissionState:n}=e,r=e.messages,i=e.session;if(!shouldCompact(r,i.compaction))return{messages:r,session:i};let a=await resolveCompactionModel({compactionModelReference:i.agent.compactionModelReference,model:e.model,modelReference:i.agent.modelReference,resolveModel:e.resolveModel});if(t&&await t(createCompactionRequestedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId,usageInputTokens:getInputTokenCount(r,i.compaction)})),r=await compactMessages(r,a.model,i.compaction,a.providerOptions,e.telemetry,e.headers),e.onCompaction){let t=await e.onCompaction(i);i=t.session;for(let e of t.messages)r.push(e)}return t&&await t(createCompactionCompletedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId})),{messages:r,session:i}}function resolveApprovalKeyFromTools(e){return t=>{let n=e.get(t.action.toolName);if(n?.approvalKey!==void 0)return n.approvalKey(t.action.input)}}async function runModelCallWithRetries(e,t){for(let n=1;;n++)try{return await e()}catch(e){if(n===3||classifyModelCallError(e)!==`retry`)throw e;let r=500*2**(n-1)+Math.floor(Math.random()*250);log.warn(`model call failed transiently — retrying`,{attempt:n,delayMs:r,sessionId:t.sessionId,turnId:t.turnId,error:e}),await new Promise(e=>setTimeout(e,r))}}export{createToolLoopHarness};
|
|
1
|
+
import{continueCodeModeApproval,getCodeModeApprovalResponse,isCodeModeApprovalInterrupt,toCodeModeApprovalMessages}from"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/approval-continuation.js";import{continueCodeModeInterrupt,getCodeModeInterrupt,replaceCodeModeInterruptResult,unwrapCodeModeResult}from"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/interrupt-continuation.js";import"../node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/index.js";import{createErrorId,createLogger,formatError,logError,recordErrorOnSpan}from"#internal/logging.js";import{createAuthorizationRequiredEvent,createCompactionCompletedEvent,createCompactionRequestedEvent,createInputRequestedEvent}from"#protocol/message.js";import{toErrorMessage}from"#shared/errors.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import"#shared/json.js";import{contextStorage}from"#context/container.js";import{advanceStep,emitFailedStep,emitRecoverableFailedTurn,emitStreamContent,emitTurnEpilogue,emitTurnPreamble,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{ConnectionRegistryKey,DiscoveredConnectionToolsKey}from"#runtime/framework-tools/connection-search.js";import{ToolLoopAgent,isStepCount}from"ai";import{createRuntimeActionRequestFromToolCall,resolvePendingRuntimeActions,setPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{resolveAssistantStepText}from"#harness/messages.js";import{consumeDeferredStepInput,getApprovedTools,hasDeferredStepInput,hasStepInput,resolvePendingInput,setPendingInputBatch}from"#harness/input-requests.js";import{getHookUrl,isAuthorizationSignal,setPendingAuthorization}from"#harness/authorization.js";import{isCodeModeConnectionAuthInterrupt}from"#runtime/framework-tools/code-mode-connection-auth.js";import{resolveConnectionToolsFromState}from"#runtime/framework-tools/connection-tools.js";import{CODE_MODE_TOOL_NAME}from"#shared/code-mode.js";import{buildToolSetWithProviderTools}from"#harness/tools.js";import{ASK_QUESTION_TOOL_NAME}from"#runtime/framework-tools/ask-question.js";import{WEB_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-search.js";import{extractQuestionInputRequests,extractToolApprovalInputRequests}from"#harness/input-extraction.js";import{applyLastToolCacheBreakpoint,detectPromptCachePath,getAnthropicCacheMarker}from"#harness/prompt-cache.js";import{resolveFrameworkToolFromUpstreamType,resolveGatewayPinForWebSearchBackend,resolveWebSearchBackend}from"#harness/provider-tools.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{resolveConnectionPrincipal}from"#runtime/connections/principal.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{hydrateSandboxAttachments,stageAttachmentsToSandbox}from"#harness/attachment-staging.js";import{applyCodeModeToToolSet,buildCodeModeHostTools,createAshCodeModeOptions,isCodeModeEnabled}from"#harness/code-mode.js";import{createCodeModeLifecycle}from"#harness/code-mode-lifecycle.js";import{clearPendingCodeModeApproval,getPendingCodeModeApproval,replaceCodeModeApprovalInterruptResult,setPendingCodeModeApproval}from"#harness/code-mode-approval.js";import{compactMessages,getInputTokenCount,resolveCompactionModel,shouldCompact}from"#harness/compaction.js";import{getInstrumentationConfig}from"#harness/instrumentation-config.js";import{clearPendingCodeModeConnectionAuth,getPendingCodeModeConnectionAuth,setPendingCodeModeConnectionAuth}from"#harness/code-mode-connection-auth-state.js";import{classifyModelCallError,extractModelCallErrorDetails,extractUnsupportedProviderToolTypes,summarizeKnownModelCallConfigError,summarizeKnownModelCallRequestError}from"#harness/model-call-error.js";import{ensureOtelIntegration}from"#harness/otel-integration.js";import{buildStepHooks,emitStepActions,isInvalidToolCall}from"#harness/step-hooks.js";import{pruneToolResults}from"#harness/tool-result-pruning.js";const environment=process.env.NODE_ENV??`unknown`,ashVersion=resolveInstalledPackageInfo().version,log=createLogger(`harness.tool-loop`);function logToolExecutionError(e){e.toolOutput.type===`tool-error`&&logError(log,`tool execution failed`,e.toolOutput.error,{toolName:e.toolCall.toolName,toolCallId:e.toolCall.toolCallId})}function enrichTelemetry(e,t){if(e!==void 0)return{functionId:e.functionId??t,isEnabled:!0,recordInputs:e.recordInputs??!0,recordOutputs:e.recordOutputs??!0}}function buildTelemetryRuntimeContext(e,t){if(e!==void 0)return{...e.metadata,"ash.continuation_token":t.continuationToken,"ash.environment":environment,"ash.session.id":t.sessionId,"ash.version":ashVersion}}function resolveGatewayPinForStep(e){if(e.cachePath.kind!==`gateway-auto`||e.tools[WEB_SEARCH_TOOL_DEFINITION.name]===void 0)return;let t=resolveWebSearchBackend(e.modelReference);return t===null?void 0:resolveGatewayPinForWebSearchBackend(t)??void 0}function buildGatewayAttributionHeaders(e,t){if(typeof e!=`string`)return;let n=t?.agentName??t?.agentId,r=process.env.VERCEL_PROJECT_PRODUCTION_URL||process.env.VERCEL_URL,i=r?`https://${r}`:void 0;if(!n&&!i)return;let a={};return n&&(a[`x-title`]=n),i&&(a[`http-referer`]=i),a}const TURN_TRACE_STATE_KEY=`ash.harness.turnTrace`;function getTurnTraceState(e){return e.state?.[TURN_TRACE_STATE_KEY]}function setTurnTraceState(e,t){let n={traceId:t.traceId,spanId:t.spanId,traceFlags:t.traceFlags};return{...e,state:{...e.state,[TURN_TRACE_STATE_KEY]:n}}}function resolveStepOtelContext(e,t,n){if(t)return trace.setSpan(context.active(),t);if(e){let e=getTurnTraceState(n);if(e){let t=trace.wrapSpanContext({traceId:e.traceId,spanId:e.spanId,traceFlags:e.traceFlags});return trace.setSpan(context.active(),t)}}}function createToolLoopHarness(e){let t=e.emit,n=getInstrumentationConfig();n!==void 0&&ensureOtelIntegration();let r=n===void 0?void 0:trace.getTracer(`ash`),i=e.runtimeIdentity?.agentName;async function runStep(e,t){let a;if(r&&hasStepInput(t)){let t=n?.functionId??i,o={"ash.version":ashVersion,"ash.environment":environment,"ash.session.id":e.sessionId,"ash.continuation_token":e.continuationToken};t&&(o[`ai.telemetry.functionId`]=t),a=r.startSpan(`ai.ash.turn`,{attributes:o})}let o=resolveStepOtelContext(r,a,e),executeStep=()=>executeStepBody(e,t,a);try{return o?await context.with(o,executeStep):await executeStep()}finally{a?.end()}}async function executeStepBody(r,a,o){let s=r;o&&(s=setTurnTraceState(s,o.spanContext()));let l=getHarnessEmissionState(s.state),u=consumeDeferredStepInput({input:a,session:s});s=u.session;let p=await resolvePendingRuntimeActions({emit:t,session:s,stepInput:u.input});if(p.outcome===`unresolved`)return{next:null,session:p.session};s=p.session;let m=resolvePendingInput({history:p.messages,resolveApprovalKey:resolveApprovalKeyFromTools(e.tools),session:s,stepInput:u.input});if(m.outcome===`unresolved`)return{next:null,session:m.session};t&&hasStepInput(a)&&(l=await emitTurnPreamble(t,a??{},l,e.runtimeIdentity),s=setHarnessEmissionState(s,l),o&&o.setAttribute(`ash.turn.id`,l.turnId)),s=m.session;let h=m.messages,g=await continuePendingCodeModeConnectionAuth({capabilities:e.capabilities,config:e,emit:t,emissionState:l,messages:h,runStep,session:s});if(g!==null)return g;let v=await continuePendingCodeModeApproval({capabilities:e.capabilities,config:e,emit:t,emissionState:l,messages:h,runStep,session:s});if(v!==null)return v;if(u.input?.message!==void 0&&!m.deferredMessage){let e=await stageAttachmentsToSandbox(u.input.message);h.push({content:e,role:`user`})}let y=await e.resolveModel(s.agent.modelReference),x=detectPromptCachePath(y),T=x.kind===`anthropic-direct`?getAnthropicCacheMarker():void 0,A=buildGatewayAttributionHeaders(y,e.runtimeIdentity);({messages:h,session:s}=await maybeCompact({emit:t,emissionState:l,headers:A,messages:h,model:y,onCompaction:e.onCompaction,resolveModel:e.resolveModel,session:s,telemetry:enrichTelemetry(n,i)??void 0}));let j=getApprovedTools(s),M=contextStorage.getStore(),N=M?.get(ConnectionRegistryKey),P=M?.get(DiscoveredConnectionToolsKey),F=await hydrateSandboxAttachments(h),I=u.input?.modelContext,L=[],R=[];for(let e of F)e.role===`system`?L.push(e):R.push(e);if(I!==void 0)for(let e of I)e.role===`system`?L.push(e):R.push(e);let z=R,runOneModelCall=async r=>{let a=isCodeModeEnabled(),o=await buildToolSetWithProviderTools({approvedTools:j,capabilities:e.capabilities,disabledProviderTools:r.disabledProviderTools,modelReference:s.agent.modelReference,tools:e.tools});if(N!==void 0&&P!==void 0){let e=await resolveConnectionToolsFromState(N,P,{approvedTools:j,authMode:a?`code-mode`:`direct`,existingToolNames:new Set(Object.keys(o))});Object.assign(o,e)}let c=a?applyCodeModeToToolSet({harnessTools:e.tools,lifecycle:t===void 0?void 0:createCodeModeLifecycle({emit:t,emissionState:l,tools:e.tools}),tools:o}).modelTools:o,u=T?applyLastToolCacheBreakpoint(c,T):c,f=resolveGatewayPinForStep({cachePath:x,modelReference:s.agent.modelReference,tools:u}),p=r.extraSystemNote?[{role:`system`,content:r.extraSystemNote}]:[],m=s.agent.system?[{role:`system`,content:s.agent.system}]:[],h=L.length>0||p.length>0?[...p,...m,...L]:s.agent.system||void 0,g=buildStepHooks({cachePath:x,emit:t,emissionState:l,emitStepStarted:r.suppressStepStartedEmission!==!0,gatewayPinProvider:f,marker:T,session:s}),_=new ToolLoopAgent({headers:A,instructions:h,model:y,onToolExecutionEnd:logToolExecutionError,onError(e){logError(log,`tool-loop stream error`,e.error)},onStepFinish:g.onStepFinish,prepareStep:g.prepareStep,runtimeContext:buildTelemetryRuntimeContext(n,s),stopWhen:isStepCount(1),telemetry:enrichTelemetry(n,i),tools:u});return runModelCallWithRetries(async()=>{if(t){let n=await _.stream({messages:z}),{inlineActionResultCallIds:r,inlineToolResultParts:i}=await emitStreamContent(t,l,n.fullStream),a=await g.stepResult;return await emitStepActions(t,l,a,{excludedActionToolNames:new Set([ASK_QUESTION_TOOL_NAME,CODE_MODE_TOOL_NAME]),inlineActionResultCallIds:r,tools:e.tools}),i.length>0?{content:a.content,finishReason:a.finishReason,response:{...a.response,messages:[{role:`tool`,content:[...i]},...a.response.messages]},text:a.text,toolCalls:a.toolCalls,toolResults:a.toolResults,usage:a.usage}:a}return await _.generate({messages:z}),await g.stepResult},{sessionId:s.sessionId,turnId:l.turnId})},B;try{B=await runOneModelCall({})}catch(e){let n=await attemptUnsupportedProviderToolRecovery({error:e,runOneModelCall,sessionId:s.sessionId,turnId:l.turnId});if(n.outcome===`recovered`)B=n.result;else{let e=n.error;if(o&&recordErrorOnSpan(o,e),!t)throw e;let r=classifyModelCallError(e),i=createErrorId(),a=r===`terminal`?summarizeKnownModelCallConfigError(e):null,u=a===null?summarizeKnownModelCallRequestError(e):null,d=a?.message??u?.message??toErrorMessage(e),p=extractModelCallErrorDetails(e),m=buildModelCallFailureDetails({configSummary:a,error:e,errorId:i,modelCallDetails:p,requestSummary:u}),h=buildModelCallFailureLogFields({error:e,errorId:i,modelCallDetails:p,requestSummary:u,sessionId:s.sessionId,turnId:l.turnId});return r===`terminal`?(a===null?log.error(u?.message??`model call failed terminally`,h):log.error(`${a.name}: ${a.message}`,{errorId:i,sessionId:s.sessionId,turnId:l.turnId}),await emitFailedStep(t,l,{code:`MODEL_CALL_FAILED`,details:m,message:d,sessionId:s.sessionId}),{next:{done:!0,output:``},session:s}):(log.error(u?.message??`model call failed — parking session for retry by the user`,h),l=await emitRecoverableFailedTurn(t,l,{code:`MODEL_CALL_FAILED`,details:m,message:d}),{next:null,session:setHarnessEmissionState(s,l)})}}return handleStepResult({config:e,emit:t,emissionState:l,promptMessages:h,result:B,runStep,session:s})}return runStep}function buildModelCallFailureDetails(e){let{configSummary:t,error:n,errorId:r,modelCallDetails:i,requestSummary:a}=e;return t===null?a===null?{...formatError(n,r),...i}:{errorId:r,message:toErrorMessage(n),name:a.name,...i}:{errorId:r,message:t.message,name:t.name,...i}}function buildModelCallFailureLogFields(e){let t={errorId:e.errorId,sessionId:e.sessionId,turnId:e.turnId};return e.requestSummary===null?{...t,error:e.error}:{...t,details:e.modelCallDetails}}async function attemptUnsupportedProviderToolRecovery(e){let t=extractUnsupportedProviderToolTypes(e.error);if(t.length===0)return{outcome:`failed`,error:e.error};let n=[];for(let e of t){let t=resolveFrameworkToolFromUpstreamType(e);t!==null&&!n.includes(t)&&n.push(t)}if(n.length===0)return{outcome:`failed`,error:e.error};log.warn(`disabling unsupported provider tool(s); retrying step once`,{disabled:n,sessionId:e.sessionId,turnId:e.turnId,upstreamTypes:t});try{return{outcome:`recovered`,result:await e.runOneModelCall({disabledProviderTools:new Set(n),extraSystemNote:buildDisabledToolNote(n),suppressStepStartedEmission:!0})}}catch(e){return{outcome:`failed`,error:e}}}function buildDisabledToolNote(e){let t=e.join(`, `);return`The following ${e.length===1?`tool is`:`tools are`} not available with the current model and has been removed: ${t}. Proceed using the remaining tools or your training knowledge.`}async function handleStepResult(e){let{config:t,emit:r,promptMessages:i,result:o,runStep:s}=e,{emissionState:c,session:l}=e,u=o.response.messages,d=resolveAssistantStepText(u,o.text),f={...l,compaction:createNextCompactionConfig(l.compaction,i,o)},m=getCodeModeInterrupt(o);if(m!==void 0){if(isCodeModeConnectionAuthInterrupt(m))return parkOnCodeModeConnectionAuth({baseSession:f,config:t,emit:r,emissionState:c,interrupt:m,promptMessages:i,responseMessages:u});if(isCodeModeApprovalInterrupt(m))return parkOnCodeModeApproval({baseSession:f,config:t,emit:r,emissionState:c,interrupt:m,promptMessages:i,responseMessages:u})}let h=extractToolApprovalInputRequests({content:o.content??[]}),_=new Set(h.map(e=>e.action.callId)),v=extractQuestionInputRequests({toolCalls:o.toolCalls,excludedCallIds:_}),y=[...h,...v],b=(o.toolCalls??[]).filter(e=>!isInvalidToolCall(e)).filter(e=>t.tools.get(e.toolName)?.runtimeAction!==void 0).map(e=>createRuntimeActionRequestFromToolCall({toolCall:e,tools:t.tools}));if(b.length>0)return{next:null,session:setHarnessEmissionState(setPendingRuntimeActionBatch({actions:b,event:{sequence:c.sequence,stepIndex:c.stepIndex,turnId:c.turnId},responseMessages:u,session:{...f,history:[...i]}}),c)};if(y.length>0){let e=setPendingInputBatch({requests:y,responseMessages:u,session:{...f,history:[...i]}});return r&&(await r(createInputRequestedEvent({requests:y,sequence:c.sequence,stepIndex:c.stepIndex,turnId:c.turnId})),t.mode===`conversation`&&(c=await emitTurnEpilogue(r,c,t.mode),e=setHarnessEmissionState(e,c))),{next:null,session:e}}let S=(o.toolResults??[]).find(e=>isAuthorizationSignal(e.output));if(S&&isAuthorizationSignal(S.output)){let{challenges:e}=S.output;if(r)for(let t of e)await r(createAuthorizationRequiredEvent({authorization:t.challenge,name:t.name,description:t.challenge.instructions??`Authorization required for ${t.name}`,webhookUrl:t.hookUrl,sequence:c.sequence,stepIndex:c.stepIndex,turnId:c.turnId}));return{next:null,session:setHarnessEmissionState({...f,history:[...i],state:setPendingAuthorization(f.state,{challenges:e})},c)}}let C=pruneToolResults(i,t.retentionPolicies),w=C!==i,E=f.compaction;w&&E.lastKnownInputTokens!==void 0&&(E={recentWindowSize:E.recentWindowSize,threshold:E.threshold});let D=[...C,...u],O={...f,compaction:E,history:D},k=u.at(-1)?.role===`tool`||hasDeferredStepInput(O);return r&&(c=k?advanceStep(c):await emitTurnEpilogue(r,c,t.mode),O=setHarnessEmissionState(O,c)),k?{next:s,session:O}:{next:t.mode===`task`?{done:!0,output:d??``}:null,session:O}}async function continuePendingCodeModeApproval(r){let i=getPendingCodeModeApproval(r.session.state);if(i===void 0)return null;let a=getCodeModeApprovalResponse([...r.messages],i.interrupt);if(a===void 0)return{next:null,session:r.session};let o=contextStorage.getStore(),c=await buildCodeModeHostTools({approvedTools:getApprovedTools(r.session),capabilities:r.capabilities,discovered:o?.get(DiscoveredConnectionToolsKey),registry:o?.get(ConnectionRegistryKey),tools:r.config.tools}),l;try{l=await continueCodeModeApproval({approvalResponse:a,interrupt:i.interrupt,options:createAshCodeModeOptions({lifecycle:r.emit===void 0?void 0:createCodeModeLifecycle({emit:r.emit,emissionState:r.emissionState,skipReplayed:!0,tools:r.config.tools})}),tools:c})}catch(e){logError(log,`code-mode approval continuation failed`,e),l={error:`code_mode_continuation_failed`,message:toErrorMessage(e),retryable:!1}}let u=unwrapCodeModeResult(l),f=u.status===`interrupted`?u.interrupt:u.output,p=replaceCodeModeApprovalInterruptResult([...r.session.history,...i.responseMessages],i.interrupt,f),m=clearPendingCodeModeApproval({...r.session,history:p});if(u.status===`interrupted`){if(isCodeModeConnectionAuthInterrupt(u.interrupt)){let e=r.session.history.length,t=p.slice(0,e),n=p.slice(e);return m={...m,history:t},parkOnCodeModeConnectionAuth({baseSession:m,config:r.config,emit:r.emit,emissionState:r.emissionState,interrupt:u.interrupt,promptMessages:t,responseMessages:n})}if(isCodeModeApprovalInterrupt(u.interrupt)){let e=r.session.history.length,t=p.slice(0,e),n=p.slice(e);return m={...m,history:t},parkOnCodeModeApproval({baseSession:m,config:r.config,emit:r.emit,emissionState:r.emissionState,interrupt:u.interrupt,promptMessages:t,responseMessages:n})}}return{next:r.runStep,session:m}}async function parkOnCodeModeConnectionAuth(e){let{connectionName:t}=e.interrupt.payload,n=(contextStorage.getStore()?.get(ConnectionRegistryKey))?.getConnections().find(e=>e.connectionName===t),r=n?.authorization&&supportsInteractiveAuthorization(n.authorization)?n.authorization:void 0,i=[];if(r){let e=getHookUrl(t);if(e){let a=resolveConnectionPrincipal(t,r),{challenge:o,state:s}=await r.startAuthorization({callbackUrl:e,connection:{url:n?.url??``},principal:a});i.push({name:t,challenge:o,hookUrl:e,state:s})}}if(e.emit)for(let t of i)await e.emit(createAuthorizationRequiredEvent({authorization:t.challenge,name:t.name,description:t.challenge.instructions??`Authorization required for ${t.name}`,webhookUrl:t.hookUrl,sequence:e.emissionState.sequence,stepIndex:e.emissionState.stepIndex,turnId:e.emissionState.turnId}));return{next:null,session:setPendingCodeModeConnectionAuth({interrupt:e.interrupt,responseMessages:e.responseMessages,session:{...e.baseSession,history:[...e.promptMessages],state:setPendingAuthorization(e.baseSession.state,{challenges:i})}})}}async function continuePendingCodeModeConnectionAuth(e){let t=getPendingCodeModeConnectionAuth(e.session.state);if(t===void 0)return null;let r=contextStorage.getStore(),a=new Set,{connectionName:c}=t.interrupt.payload;a.add(c);let l=await buildCodeModeHostTools({approvedTools:getApprovedTools(e.session),capabilities:e.capabilities,codeModeMetadataOnlyConnectionNames:a,discovered:r?.get(DiscoveredConnectionToolsKey),registry:r?.get(ConnectionRegistryKey),tools:e.config.tools}),u=e.emit===void 0?void 0:createCodeModeLifecycle({emit:e.emit,emissionState:e.emissionState,skipReplayed:!0,tools:e.config.tools}),f;try{f=await continueCodeModeInterrupt({interrupt:t.interrupt,resolution:{status:`authorized`},tools:l,options:createAshCodeModeOptions({lifecycle:u})})}catch(e){logError(log,`code-mode interrupt continuation failed`,e),f={error:`code_mode_continuation_failed`,message:toErrorMessage(e),retryable:!1}}let p=unwrapCodeModeResult(f),m=p.status===`interrupted`?p.interrupt:p.output,h=replaceCodeModeInterruptResult([...e.session.history,...t.responseMessages],t.interrupt.pendingContinuation,m),g=clearPendingCodeModeConnectionAuth({...e.session,history:h});if(p.status===`interrupted`){if(isCodeModeConnectionAuthInterrupt(p.interrupt)){let t=e.session.history.length,n=h.slice(0,t),r=h.slice(t);return g={...g,history:n},parkOnCodeModeConnectionAuth({baseSession:g,config:e.config,emit:e.emit,emissionState:e.emissionState,interrupt:p.interrupt,promptMessages:n,responseMessages:r})}if(isCodeModeApprovalInterrupt(p.interrupt)){let t=e.session.history.length,n=h.slice(0,t),r=h.slice(t);return g={...g,history:n},parkOnCodeModeApproval({baseSession:g,config:e.config,emit:e.emit,emissionState:e.emissionState,interrupt:p.interrupt,promptMessages:n,responseMessages:r})}}return{next:e.runStep,session:g}}async function parkOnCodeModeApproval(e){let t=toCodeModeApprovalMessages(e.interrupt),n=extractToolApprovalInputRequests({content:extractAssistantContent(t)}),i=setPendingInputBatch({requests:n,responseMessages:t,session:setPendingCodeModeApproval({interrupt:e.interrupt,responseMessages:e.responseMessages,session:{...e.baseSession,history:[...e.promptMessages]}})});if(e.emit&&(await e.emit(createInputRequestedEvent({requests:n,sequence:e.emissionState.sequence,stepIndex:e.emissionState.stepIndex,turnId:e.emissionState.turnId})),e.config.mode===`conversation`)){let t=await emitTurnEpilogue(e.emit,e.emissionState,e.config.mode);i=setHarnessEmissionState(i,t)}return{next:null,session:i}}function extractAssistantContent(e){let t=[];for(let n of e)n.role===`assistant`&&Array.isArray(n.content)&&t.push(...n.content);return t}function createNextCompactionConfig(e,t,n){let r={recentWindowSize:e.recentWindowSize,threshold:e.threshold};return n.usage?.inputTokens!==void 0&&(r.lastKnownInputTokens=n.usage.inputTokens,r.lastKnownPromptMessageCount=t.length),r}async function maybeCompact(e){let{emit:t,emissionState:n}=e,r=e.messages,i=e.session;if(!shouldCompact(r,i.compaction))return{messages:r,session:i};let a=await resolveCompactionModel({compactionModelReference:i.agent.compactionModelReference,model:e.model,modelReference:i.agent.modelReference,resolveModel:e.resolveModel});if(t&&await t(createCompactionRequestedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId,usageInputTokens:getInputTokenCount(r,i.compaction)})),r=await compactMessages(r,a.model,i.compaction,a.providerOptions,e.telemetry,e.headers),e.onCompaction){let t=await e.onCompaction(i);i=t.session;for(let e of t.messages)r.push(e)}return t&&await t(createCompactionCompletedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId})),{messages:r,session:i}}function resolveApprovalKeyFromTools(e){return t=>{let n=e.get(t.action.toolName);if(n?.approvalKey!==void 0)return n.approvalKey(t.action.input)}}async function runModelCallWithRetries(e,t){for(let n=1;;n++)try{return await e()}catch(e){if(n===3||classifyModelCallError(e)!==`retry`)throw e;let r=500*2**(n-1)+Math.floor(Math.random()*250);log.warn(`model call failed transiently — retrying`,{attempt:n,delayMs:r,sessionId:t.sessionId,turnId:t.turnId,error:e}),await new Promise(e=>setTimeout(e,r))}}export{createToolLoopHarness};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire}from"node:module";import{basename,dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{ASH_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const WORKFLOW_MODULE_ALIASES={"workflow/api":`src/compiled/@workflow/core/runtime.js`,"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`,"workflow/runtime":`src/compiled/@workflow/core/runtime.js`};function resolveFallbackPackageVersion(){return`0.
|
|
1
|
+
import{createRequire}from"node:module";import{basename,dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{ASH_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const WORKFLOW_MODULE_ALIASES={"workflow/api":`src/compiled/@workflow/core/runtime.js`,"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`,"workflow/runtime":`src/compiled/@workflow/core/runtime.js`};function resolveFallbackPackageVersion(){return`0.37.0`}const FALLBACK_PACKAGE_INFO={name:ASH_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const require=createRequire(resolveCurrentModulePath());function isBuildOutputPackageRoot(e){return basename(e)===`dist`&&existsSync(join(dirname(e),`package.json`))}function resolvePackageBuildRoot(){let e=dirname(realpathSync(resolveCurrentModulePath()));for(;;){if(isBuildOutputPackageRoot(e))return e;let t=dirname(e);if(t===e)return null;e=t}}function findNearestPackageRoot(e){let t=e;for(;;){if(existsSync(join(t,`package.json`))&&!isBuildOutputPackageRoot(t))return t;let r=dirname(t);if(r===t)throw Error(`Failed to resolve package root from "${e}".`);t=r}}function resolvePackageRoot(){return findNearestPackageRoot(dirname(realpathSync(resolveCurrentModulePath())))}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(!(typeof t.name!=`string`||typeof t.version!=`string`))return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let n=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(n?.name===t)return n}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),ASH_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(require.resolve(`${ASH_PACKAGE_NAME}/package.json`),ASH_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?require.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveInstalledPackageInfo,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{dirname,join,relative,resolve}from"node:path";import{cp,mkdir,readFile,rm,writeFile}from"node:fs/promises";import{resolvePackageSourceDirectoryPath,resolveWorkflowModulePath}from"#internal/application/package.js";import{normalizeEsmImportSpecifier}from"#internal/application/import-specifier.js";import{buildWithNitroRolldown,getSingleRolldownChunk}from"#internal/bundler/nitro-rolldown.js";import{prepareAshVersionedCacheDirectory,writeAshVersionedCacheMetadata}from"#internal/application/cache-metadata.js";import{WORKFLOW_BUILDER_DEFERRED_PACKAGES,WORKFLOW_STEP_EXTERNAL_PACKAGES,copyNitroFunctionDirectory,createWorkflowFunctionEnvironment,retargetNitroFunctionDirectoryToWorkflowRoute}from"#internal/workflow-bundle/vercel-workflow-output.js";import{WORKFLOW_QUEUE_TRIGGER,detectWorkflowPatterns}from"#internal/workflow-bundle/workflow-builders.js";import{
|
|
2
|
-
`);return await bundleFinalWorkflowOutput({bundleFinalOutput:t,code:getSingleRolldownChunk(await buildWithNitroRolldown({cwd:this.config.workingDir,input:WORKFLOW_VIRTUAL_ENTRY_ID,platform:`neutral`,plugins:[createWorkflowVirtualEntryPlugin(h),createWorkflowPseudoPackagePlugin(),createAshPackageImportsPlugin(this.config.workingDir,{workflowCondition:!0}),createWorkflowTransformPlugin({manifest:
|
|
1
|
+
import{dirname,join,relative,resolve}from"node:path";import{cp,mkdir,readFile,rm,writeFile}from"node:fs/promises";import{resolvePackageSourceDirectoryPath,resolveWorkflowModulePath}from"#internal/application/package.js";import{normalizeEsmImportSpecifier}from"#internal/application/import-specifier.js";import{Buffer}from"node:buffer";import{buildWithNitroRolldown,getSingleRolldownChunk}from"#internal/bundler/nitro-rolldown.js";import{prepareAshVersionedCacheDirectory,writeAshVersionedCacheMetadata}from"#internal/application/cache-metadata.js";import{WORKFLOW_BUILDER_DEFERRED_PACKAGES,WORKFLOW_STEP_EXTERNAL_PACKAGES,copyNitroFunctionDirectory,createWorkflowFunctionEnvironment,retargetNitroFunctionDirectoryToWorkflowRoute}from"#internal/workflow-bundle/vercel-workflow-output.js";import{WORKFLOW_QUEUE_TRIGGER,detectWorkflowPatterns}from"#internal/workflow-bundle/workflow-builders.js";import{WORKFLOW_VIRTUAL_ENTRY_ID,atomicWriteFile,bundleFinalWorkflowOutput,collectWorkflowInputFiles,convertClassesManifest,convertStepsManifest,convertWorkflowsManifest,createAshPackageImportsPlugin,createWorkflowImport,createWorkflowNodeBuiltinGuardPlugin,createWorkflowPseudoPackagePlugin,createWorkflowTransformPlugin,createWorkflowVirtualEntryPlugin}from"#internal/workflow-bundle/builder-support.js";import{writeNitroStepEntrypoint}from"#internal/workflow-bundle/nitro-step-entry.js";const workflowBundleBuildLocks=new Map;var WorkflowBundleBuilder=class{#e;#t;config;#n=new WeakMap;constructor(e){let t=[resolvePackageSourceDirectoryPath(`src/execution`)];e.includeTestFixtures===!0&&t.push(resolvePackageSourceDirectoryPath(`src/internal/testing`)),this.config={buildTarget:`standalone`,dirs:t,externalPackages:[...WORKFLOW_STEP_EXTERNAL_PACKAGES,...WORKFLOW_BUILDER_DEFERRED_PACKAGES],projectRoot:e.appRoot,watch:e.watch,workingDir:e.rootDir},this.#e=e.compiledArtifactsBootstrapPath,this.#t=e.outDir}async build(e={}){let t=(workflowBundleBuildLocks.get(this.#t)??Promise.resolve()).then(()=>this.#r(e));workflowBundleBuildLocks.set(this.#t,t.catch(()=>{})),await t}async#r(n){await prepareAshVersionedCacheDirectory(this.#t);let r=await this.#i();if(r.length===0)throw Error(`Expected the execution workflow source file under "${resolvePackageSourceDirectoryPath(`src/execution`)}".`);let i=await this.findTsConfigPath();await mkdir(this.#t,{recursive:!0});let o=await this.discoverEntries(r,this.#t,i),s=join(this.#t,`workflows.mjs`),{manifest:c}=await this.createWorkflowsBundle({discoveredEntries:o,keepInterimBundleContext:!1,outfile:s,bundleFinalOutput:!1,format:`esm`,inputFiles:r,tsconfigPath:i}),d=join(this.#t,`steps.mjs`),f=await writeNitroStepEntrypoint({builtinsPath:resolveWorkflowModulePath(`workflow/internal/builtins`),discoveredEntries:o,outfile:d,preferAbsoluteFileImports:!0,projectRoot:this.config.projectRoot??this.config.workingDir,workingDir:this.config.workingDir}),p=n.nitroStepOutfile;p!==void 0&&p!==d&&await writeNitroStepEntrypoint({builtinsPath:resolveWorkflowModulePath(`workflow/internal/builtins`),discoveredEntries:o,outfile:p,preferAbsoluteFileImports:!0,projectRoot:this.config.projectRoot??this.config.workingDir,workingDir:this.config.workingDir}),await addStepRegistrationsImport(s,d),await rewriteWorkflowRuntimeImports(s),await rewriteWorkflowCodeLiteral(s);let m=n.nitroWorkflowOutfile;m!==void 0&&m!==s&&(await mkdir(dirname(m),{recursive:!0}),await mirrorFileBypassingUnlink(s,m),p!==void 0&&(await addStepRegistrationsImport(m,p),await rewriteWorkflowRuntimeImports(m),await rewriteWorkflowCodeLiteral(m))),await this.createManifest({workflowBundlePath:join(this.#t,`workflows.mjs`),manifestDir:this.#t,manifest:{steps:{...f.steps,...c.steps},workflows:{...f.workflows,...c.workflows},classes:{...f.classes,...c.classes}}}),await writeAshVersionedCacheMetadata(this.#t)}get transformProjectRoot(){return this.config.projectRoot??this.config.workingDir}async findTsConfigPath(){let n=this.config.workingDir;for(;;){for(let e of[`tsconfig.json`,`jsconfig.json`]){let r=join(n,e);try{return await readFile(r),r}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}}let r=dirname(n);if(r===n)return;n=r}}async getInputFiles(){let e=this.config.dirs.map(e=>resolve(this.config.workingDir,e));return(await Promise.all(e.map(e=>collectWorkflowInputFiles(e)))).flat()}async discoverEntries(e,t,n){let r=this.#n.get(e);if(r!==void 0)return r;let i={discoveredSerdeFiles:[],discoveredSteps:[],discoveredWorkflows:[]};for(let t of e){let e=detectWorkflowPatterns(await readFile(t,`utf8`));e.hasUseStep&&i.discoveredSteps.push(t),e.hasUseWorkflow&&i.discoveredWorkflows.push(t),e.hasSerde&&i.discoveredSerdeFiles.push(t)}return this.#n.set(e,i),i}async createWorkflowsBundle({bundleFinalOutput:t=!0,discoveredEntries:n,format:r=`cjs`,inputFiles:i,keepInterimBundleContext:a=this.config.watch,outfile:o,tsconfigPath:s}){let c=n??await this.discoverEntries(i,dirname(o),s),l=[...c.discoveredWorkflows].sort(),u=new Set(l),d=[...c.discoveredSerdeFiles].sort().filter(e=>!u.has(e)),f={},h=[...l.map(e=>createWorkflowImport(e,this.config.workingDir)),...d.map(e=>createWorkflowImport(e,this.config.workingDir))].join(`
|
|
2
|
+
`);return await bundleFinalWorkflowOutput({bundleFinalOutput:t,code:getSingleRolldownChunk(await buildWithNitroRolldown({cwd:this.config.workingDir,input:WORKFLOW_VIRTUAL_ENTRY_ID,platform:`neutral`,plugins:[createWorkflowVirtualEntryPlugin(h),createWorkflowPseudoPackagePlugin(),createAshPackageImportsPlugin(this.config.workingDir,{workflowCondition:!0}),createWorkflowTransformPlugin({manifest:f,projectRoot:this.transformProjectRoot,sideEffectFiles:[...l,...d],workingDir:this.config.workingDir}),createWorkflowNodeBuiltinGuardPlugin()],resolve:{conditionNames:[`ash-source`,`workflow`,`node`,`import`,`default`],extensions:[`.ts`,`.tsx`,`.mts`,`.cts`,`.js`,`.jsx`,`.mjs`,`.cjs`],mainFields:[`module`,`main`]},tsconfig:s??!1,write:!1,output:{banner:`globalThis.__private_workflows = new Map();`,codeSplitting:!1,comments:!1,format:`cjs`,sourcemap:`inline`}}),`intermediate workflow bundle for "${o}"`).code,format:r,outfile:o,workingDir:this.config.workingDir}),a?{bundleFinal:async e=>{await bundleFinalWorkflowOutput({bundleFinalOutput:t,code:e,format:r,outfile:o,workingDir:this.config.workingDir})},interimBundleCtx:void 0,manifest:f}:{manifest:f}}async createManifest({manifest:e,manifestDir:n}){let r={version:`1.0.0`,steps:convertStepsManifest(e.steps),workflows:convertWorkflowsManifest(e.workflows),classes:convertClassesManifest(e.classes)},i=JSON.stringify(r,null,2);return await mkdir(n,{recursive:!0}),await writeFile(join(n,`manifest.json`),i),i}async buildVercelOutput(e){await this.build();let n=join(this.#t,`vercel-build-output`,`functions`,`.well-known`,`workflow`,`v1`),r=join(n,`flow.func`),o=join(e.outputDir,`functions`,`.well-known`,`workflow`,`v1`),c=join(e.flowNitroOutputDir,`functions`,`__server.func`),l=join(e.flowNitroOutputDir,`functions`,`.well-known`,`workflow`,`v1`,`flow.func`),u=join(o,`flow.func`),d=join(o,`step.func`),f=join(o,`webhook`,`[token].func`);await copyNitroFunctionDirectory({fallbackPath:c,sourcePath:l,targetPath:r}),await Promise.all([this.#a(r,{experimentalTriggers:Array.from([WORKFLOW_QUEUE_TRIGGER]),maxDuration:`max`,runtime:e.runtime??null,shouldAddHelpers:!1}),cp(join(this.#t,`manifest.json`),join(n,`manifest.json`))]),await retargetNitroFunctionDirectoryToWorkflowRoute({functionDirectoryPath:r,workflowRoutePath:`/.well-known/workflow/v1/flow`}),await Promise.all([rm(u,{force:!0,recursive:!0}),rm(d,{force:!0,recursive:!0}),rm(f,{force:!0,recursive:!0})]),await mkdir(o,{recursive:!0}),await Promise.all([cp(r,u,{recursive:!0}),cp(join(n,`manifest.json`),join(o,`manifest.json`))])}async#i(){return[...await this.getInputFiles(),this.#e]}async#a(e,n){let r=join(e,`.vc-config.json`),i=await this.#o(r),a={...i};a.environment=createWorkflowFunctionEnvironment(i.environment),n.runtime!==null&&(a.runtime=n.runtime),n.maxDuration!==void 0&&(a.maxDuration=n.maxDuration),n.shouldAddHelpers!==void 0&&(a.shouldAddHelpers=n.shouldAddHelpers),n.shouldAddSourcemapSupport!==void 0&&(a.shouldAddSourcemapSupport=n.shouldAddSourcemapSupport),n.experimentalTriggers!==void 0&&(a.experimentalTriggers=[...n.experimentalTriggers]),await writeFile(r,`${JSON.stringify(a,null,2)}\n`)}async#o(e){try{let t=JSON.parse(await readFile(e,`utf8`));if(typeof t==`object`&&t)return t}catch{}return{}}};async function addStepRegistrationsImport(t,n){let r=await readTextFileIfPresent(t);if(r===null||r.includes(`__ashWorkflowStepsRegistered`))return;let i=createRelativeImportSpecifier(dirname(t),n),a=[`import { __steps_registered as __ashWorkflowStepsRegistered } from ${JSON.stringify(i)};`,`void __ashWorkflowStepsRegistered;`,``].join(`
|
|
3
3
|
`),o=r.match(/^import\s.+?;\n/m);if(o===null||o.index===void 0){await atomicWriteFile(t,`${a}${r}`);return}let s=o.index+o[0].length;await atomicWriteFile(t,`${r.slice(0,s)}${a}${r.slice(s)}`)}async function rewriteWorkflowRuntimeImports(e){let t=await readTextFileIfPresent(e);if(t===null)return;let n=t;for(let e of[`workflow`,`workflow/api`,`workflow/internal/builtins`,`workflow/internal/private`,`workflow/runtime`]){let t=normalizeImportSpecifierPath(resolveWorkflowModulePath(e));n=replaceStringLiteralSpecifier(n,e,t)}n!==t&&await atomicWriteFile(e,n)}async function rewriteWorkflowCodeLiteral(e){let t=await readTextFileIfPresent(e);if(t===null)return;let n=t.indexOf(`const workflowCode = `),r=t.lastIndexOf(`;
|
|
4
4
|
|
|
5
5
|
export const POST = workflowEntrypoint(workflowCode);`);if(n===-1||r===-1||r<=n)return;let i=n+21,a=t.slice(i,r);if(!a.trimStart().startsWith("`"))return;let o=decodeWorkflowCodeTemplateLiteral(a,e),s=`${t.slice(0,i)}${encodeWorkflowCodeLiteral(o)}${t.slice(r)}`;s!==t&&await atomicWriteFile(e,s)}function encodeWorkflowCodeLiteral(e){let t=Buffer.from(e,`utf8`).toString(`base64`).match(/.{1,16384}/g)??[``];return`Buffer.from(${JSON.stringify(t)}.join(""), "base64").toString("utf8")`}function decodeWorkflowCodeTemplateLiteral(e,t){let n=e.trim();if(!n.startsWith("`")||!n.endsWith("`"))throw Error(`Expected generated workflow code literal in "${t}" to be a template.`);let r=n.slice(1,-1),i=``;for(let e=0;e<r.length;e+=1){let t=r[e];if(t!==`\\`){i+=t;continue}let n=r[e+1];if(n===`\\`||n==="`"||n===`$`){i+=n,e+=1;continue}i+=t}return i}function replaceStringLiteralSpecifier(e,t,n){return e.replaceAll(JSON.stringify(t),JSON.stringify(n)).replaceAll(`'${t}'`,JSON.stringify(n))}function normalizeImportSpecifierPath(e){return normalizeEsmImportSpecifier(e)}function createRelativeImportSpecifier(e,t){let r=relative(e,t).replaceAll(`\\`,`/`);return r.startsWith(`.`)?r:`./${r}`}async function readTextFileIfPresent(e){try{return await readFile(e,`utf8`)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return null;throw e}}async function readBinaryFileIfPresent(e){try{return await readFile(e)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return null;throw e}}async function mirrorFileBypassingUnlink(e,t){let n=await readFile(e),r=await readBinaryFileIfPresent(t);r!==null&&r.equals(n)||await atomicWriteFile(t,n)}export{WorkflowBundleBuilder};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./errors.js";import"./continuation-capability.js";import"./host-interrupt.js";import"./runtime/max-workers.js";import"./runtime/manager.js";import"./run-code-mode.js";import"./approval-continuation.js";import"./interrupt-continuation.js";import"./code-mode-tool.js";
|
|
1
|
+
import"./errors.js";import"./continuation-capability.js";import"./host-interrupt.js";import"./runtime/max-workers.js";import"./runtime/manager.js";import"./run-code-mode.js";import"./approval-continuation.js";import"./interrupt-continuation.js";import"./code-mode-tool.js";export{};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{CodeModeAbortedError,CodeModeBridgeLimitError,CodeModeConcurrencyError,CodeModeDetachedBridgeRequestError,CodeModeProtocolError,CodeModeTimeoutError,CodeModeToolApprovalDeniedError,deserializeError,serializeBridgeErrorForGuest,serializeError}from"../errors.js";import{assertCodeModeApprovalResponse}from"../approval-response.js";import{signCodeModeContinuation,verifyCodeModeContinuation}from"../continuation-capability.js";import{executeHostFetch}from"../fetch-policy.js";import{normalizeOptions}from"../options.js";import{toJsonPayload}from"../serialization.js";import{assertSourceSize,transformSource}from"../source-cache.js";import{addTelemetryEvent,endTelemetrySpan,recordTelemetryError,startTelemetrySpan}from"../telemetry.js";import{invokeHostTool}from"../tool-invocation.js";import{getMaxWorkers}from"./max-workers.js";import{INLINE_CODE_MODE_WORKER_SOURCE}from"./worker-source.js";import{randomBytes}from"node:crypto";import{Buffer}from"node:buffer";import{Worker}from"node:worker_threads";let activeInvocations=0,invocationCounter=0,inlineWorkerUrl;const idleWorkers=[];function getCodeModeWorkerUrl(){return getDefaultCodeModeWorkerUrl()}function getDefaultCodeModeWorkerUrl(){return getInlineWorkerUrl()}async function runManagedCodeMode(t){let r=normalizeOptions(t.options),i=getMaxWorkers({memoryLimitBytes:r.memoryLimitBytes,activeWorkers:activeInvocations});if(activeInvocations>=i)throw new CodeModeConcurrencyError(i);activeInvocations++;let a=!0;try{if(t.toolExecutionOptions?.abortSignal?.aborted)throw new CodeModeAbortedError;assertSourceSize(t.js,r.maxSourceBytes);let n=transformSource(t.js);assertContinuationInput({js:n,continuation:t.continuation,approvalResponse:t.approvalResponse,interruptResolution:t.interruptResolution});let o=startWorkerRun({...t,js:n,normalizedOptions:r,maxWorkers:i});return a=!1,o.accountingDone.then(()=>releaseInvocationSlot(r.memoryLimitBytes),()=>releaseInvocationSlot(r.memoryLimitBytes)),await o.result}finally{a&&releaseInvocationSlot(r.memoryLimitBytes)}}function assertContinuationInput({js:e,continuation:t,approvalResponse:n,interruptResolution:r}){if(n!==void 0&&assertCodeModeApprovalResponse(n),n!==void 0&&r!==void 0)throw new CodeModeProtocolError(`A code-mode continuation cannot be resumed with both an approval response and a generic interrupt resolution.`,{approvalId:n.approvalId,interruptId:r.interruptId});if(t===void 0){if(n!==void 0||r!==void 0)throw new CodeModeProtocolError(`A code-mode continuation response was provided without continuation state.`,{hasApprovalResponse:n!==void 0,hasInterruptResolution:r!==void 0});return}if(verifyCodeModeContinuation(t),t.version!==1)throw new CodeModeProtocolError(`Unsupported code-mode continuation version.`,{version:t.version});if(t.js!==e)throw new CodeModeProtocolError(`Code mode continuation source does not match the resumed source.`,{continuationSourceBytes:byteLength(t.js),resumedSourceBytes:byteLength(e)});if(typeof t.outerToolCallId!=`string`)throw new CodeModeProtocolError(`Code mode continuation outerToolCallId must be a string.`,{outerToolCallId:t.outerToolCallId});if(assertDeterminismState(t.determinism),assertContinuationLedgerShape(t),n!==void 0){let e=t.ledger.filter(e=>e.kind===`tool`&&e.status===`approval-required`&&e.approvalId===n.approvalId);if(e.length!==1)throw new CodeModeProtocolError(`Approval response does not match exactly one pending continuation ledger entry.`,{approvalId:n.approvalId,matches:e.length})}if(r!==void 0){let e=t.ledger.filter(e=>e.kind===`tool`&&e.status===`interrupted`&&e.interruptId===r.interruptId);if(e.length!==1)throw new CodeModeProtocolError(`Interrupt resolution does not match exactly one pending continuation ledger entry.`,{interruptId:r.interruptId,matches:e.length})}}function startWorkerRun({js:n,tools:s,toolExecutionOptions:u,options:f,continuation:m,approvalResponse:g,interruptResolution:_,normalizedOptions:v,maxWorkers:y}){let b=`code-mode-${++invocationCounter}`,x=acquireWorker(y),S=x.worker,C=u?.abortSignal,w=new AbortController,T=getMaxNestedToolCounter(m?.ledger??[]),E,D=!1,O=!1,k=!1,A=!1,j=0,M=0,N,P=new Set,F=cloneLedger(m?.ledger??[]),I=m?.determinism??createDeterminismState(),L=u?.context??u?.experimental_context,R=u?.experimental_context??u?.context,z={toolCallId:u?.toolCallId??m?.outerToolCallId??b,messages:u?.messages??[],abortSignal:w.signal,...R===void 0?{}:{experimental_context:R},...L===void 0?{}:{context:L}},B=Date.now(),V={invocationId:b,outerToolCallId:z.toolCallId,status:`completed`,startedAtMs:B,completedAtMs:B,durationMs:0,bridgeRequests:[]},H=!1,U=startTelemetrySpan(f?.telemetry,`ai.code_mode.execute`,{"code_mode.invocation.id":b,"code_mode.outer_tool_call.id":z.toolCallId,"code_mode.continuation":m!==void 0,"code_mode.fetch.enabled":v.fetchEnabled,"code_mode.max_workers":y,...f?.telemetry?.recordInputs===!1?{}:{"code_mode.source.bytes":byteLength(n)}}),emitNestedToolCall=async e=>{await emitLifecycleHook(`onNestedToolCall`,e)},emitNestedToolResult=async e=>{await emitLifecycleHook(`onNestedToolResult`,e)},emitInterrupt=async e=>{await emitLifecycleHook(`onInterrupt`,{invocationId:b,outerToolCallId:z.toolCallId,interrupt:e})},emitLifecycleHook=async(e,t)=>{let n=f?.lifecycle,r=n?.[e];if(r!==void 0)try{await r(t)}catch(r){try{await n?.onHookError?.(r,{hook:e,event:t})}catch{}}},emitFetchRequest=async e=>{await emitLifecycleHook(`onFetchRequest`,e)},emitFetchResult=async e=>{await emitLifecycleHook(`onFetchResult`,e)},emitTrace=async e=>{await emitLifecycleHook(`onTrace`,e)},W,finishTrace=(e,t={})=>{if(H)return W??Promise.resolve();H=!0;let n=Date.now();return V.status=e,V.completedAtMs=n,V.durationMs=Math.max(0,n-V.startedAtMs),t.interruptedBy!==void 0&&(V.interruptedBy=t.interruptedBy,addTelemetryEvent(U,`code_mode.interrupt`,{"code_mode.interrupt.type":t.interruptedBy})),t.error!==void 0&&(V.error=serializeError(t.error),recordTelemetryError(U,t.error)),U?.setAttributes?.({"code_mode.status":e,"code_mode.duration_ms":V.durationMs,"code_mode.bridge_requests.count":V.bridgeRequests.length,"code_mode.bridge_requests.replayed_count":V.bridgeRequests.filter(e=>e.replayed).length}),endTelemetrySpan(U),W=emitTrace(cloneTrace(V)),W},makeToolCallEvent=({bridgeIndex:e,toolName:t,input:n,inputJson:r,toolCallId:i,replayed:a,startedAtMs:o})=>({invocationId:b,outerToolCallId:z.toolCallId,bridgeIndex:e,toolName:t,input:n,inputBytes:byteLength(r),toolCallId:i,replayed:a,startedAtMs:o}),pushToolTrace=e=>{let t={kind:`tool`,bridgeIndex:e.bridgeIndex,toolName:e.toolName,toolCallId:e.toolCallId,status:e.status,replayed:e.replayed,startedAtMs:e.startedAtMs,completedAtMs:e.completedAtMs,durationMs:e.durationMs,inputBytes:e.inputBytes,...e.status===`fulfilled`?{outputBytes:e.outputBytes}:{},...e.status===`rejected`?{error:toTraceError(e.error)}:{},...e.status===`interrupted`?{interruptType:e.interrupt.type}:{}};return V.bridgeRequests.push(t),t},makeFetchRequestEvent=({bridgeIndex:e,inputJson:t,request:n,replayed:r,startedAtMs:i})=>({invocationId:b,outerToolCallId:z.toolCallId,bridgeIndex:e,url:n.url,method:n.method??`GET`,inputBytes:byteLength(t),replayed:r,startedAtMs:i}),pushFetchTrace=e=>{let t={kind:`fetch`,bridgeIndex:e.bridgeIndex,url:e.url,method:e.method,status:e.status,replayed:e.replayed,startedAtMs:e.startedAtMs,completedAtMs:e.completedAtMs,durationMs:e.durationMs,inputBytes:e.inputBytes,...e.status===`fulfilled`?{outputBytes:e.outputBytes}:{},...e.status===`rejected`?{error:toTraceError(e.error)}:{}};return V.bridgeRequests.push(t),t},finishToolEvent=async e=>{pushToolTrace(e),addTelemetryEvent(U,`code_mode.nested_tool.result`,{"code_mode.bridge.index":e.bridgeIndex,"code_mode.tool.name":e.toolName,"code_mode.tool_call.id":e.toolCallId,"code_mode.status":e.status,"code_mode.replayed":e.replayed,...e.status===`fulfilled`&&f?.telemetry?.recordOutputs!==!1?{"code_mode.tool.output.bytes":e.outputBytes}:{}}),await emitNestedToolResult(e)},finishFetchEvent=async e=>{pushFetchTrace(e),addTelemetryEvent(U,`code_mode.fetch.result`,{"code_mode.bridge.index":e.bridgeIndex,"code_mode.fetch.url":e.url,"code_mode.fetch.method":e.method,"code_mode.status":e.status,"code_mode.replayed":e.replayed,...e.status===`fulfilled`&&f?.telemetry?.recordOutputs!==!1?{"code_mode.fetch.output.bytes":e.outputBytes}:{}}),await emitFetchResult(e)},startNestedToolSpan=e=>startTelemetrySpan(f?.telemetry,`ai.code_mode.nested_tool`,{"code_mode.invocation.id":b,"code_mode.outer_tool_call.id":z.toolCallId,"code_mode.bridge.index":e.bridgeIndex,"code_mode.tool.name":e.toolName,"code_mode.tool_call.id":e.toolCallId,"code_mode.replayed":e.replayed,...f?.telemetry?.recordInputs===!1?{}:{"code_mode.tool.input.bytes":e.inputBytes}}),startFetchSpan=e=>startTelemetrySpan(f?.telemetry,`ai.code_mode.fetch`,{"code_mode.invocation.id":b,"code_mode.outer_tool_call.id":z.toolCallId,"code_mode.bridge.index":e.bridgeIndex,"code_mode.fetch.url":e.url,"code_mode.fetch.method":e.method,"code_mode.replayed":e.replayed,...f?.telemetry?.recordInputs===!1?{}:{"code_mode.fetch.input.bytes":e.inputBytes}}),G,K,q=new Promise((e,t)=>{G=e,K=t}),J,Y=new Promise(e=>{J=e}),abortInvocation=e=>{w.signal.aborted||w.abort(e)},cleanupWorker=e=>{A||(A=!0,clearTimeout(X),C?.removeEventListener(`abort`,onAbort),S.off(`message`,onMessage),S.off(`error`,onError),S.off(`exit`,onExit),e?releaseWorker(x):destroyWorker(x))},settleAccountingIfDone=()=>{!O&&D&&M===0&&(O=!0,J())},settleCaller=e=>{if(!D){D=!0,settleAccountingIfDone();try{e()}catch(e){K(e)}finally{settleAccountingIfDone()}}},failTerminal=e=>{k||(k=!0,abortInvocation(e),cleanupWorker(!1),(async()=>{await finishTrace(`failed`,{error:e}),settleCaller(()=>K(e))})())},onAbort=()=>{failTerminal(new CodeModeAbortedError)},X=setTimeout(()=>{failTerminal(new CodeModeTimeoutError(v.timeoutMs))},v.timeoutMs),onMessage=e=>{if(e.invocationId!==b){failTerminal(new CodeModeProtocolError(`Worker message invocationId mismatch: expected ${b}, received ${e.invocationId}.`,{expectedInvocationId:b,receivedInvocationId:e.invocationId,messageType:e.type}));return}if(e.type===`result`){if(E!==void 0){failTerminal(new CodeModeProtocolError(`Worker sent duplicate result for invocation ${b}.`,{invocationId:b}));return}E=e;return}if(e.type===`ready`){handleReadyMessage(e);return}if(e.type===`tool-request`){let t=markWorkerRequest(e);t!==void 0&&handleToolRequest(e,t);return}if(e.type===`fetch-request`){let t=markWorkerRequest(e);t!==void 0&&handleFetchRequest(e,t)}},onError=e=>{failTerminal(e)},onExit=e=>{!k&&e!==0&&failTerminal(Error(`Code mode worker exited with code ${e}.`))};S.on(`message`,onMessage),S.on(`error`,onError),S.on(`exit`,onExit),C?.addEventListener(`abort`,onAbort,{once:!0}),C?.aborted&&onAbort();let Z={type:`run`,invocationId:b,js:n,determinism:I,options:{timeoutMs:v.timeoutMs,memoryLimitBytes:v.memoryLimitBytes,maxStackSizeBytes:v.maxStackSizeBytes,maxResultBytes:v.maxResultBytes,fetchEnabled:v.fetchEnabled}};if(!k)try{S.postMessage(Z)}catch(e){failTerminal(e)}return{result:q,accountingDone:Y};async function handleToolRequest(e,t){let n=F[t-1],r=fromJsonPayload(e.inputJson);try{if(n!==void 0){if(assertReplayEntryMatches(n,{kind:`tool`,name:e.toolName,inputJson:e.inputJson}),n.kind!==`tool`)throw new CodeModeProtocolError(`Continuation replay expected a tool ledger entry.`,{invocationId:b,bridgeIndex:t,kind:n.kind});if(n.status===`fulfilled`){let i=Date.now(),a=makeToolCallEvent({bridgeIndex:t,toolName:e.toolName,input:r,inputJson:e.inputJson,toolCallId:n.toolCallId,replayed:!0,startedAtMs:i});await emitNestedToolCall(a);let o=Date.now();await finishToolEvent({...a,status:`fulfilled`,completedAtMs:o,durationMs:o-i,outputBytes:byteLength(n.valueJson),output:fromJsonPayload(n.valueJson)}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!0,dateNowMs:n.dateNowMs,valueJson:n.valueJson});return}if(n.status===`rejected`){let i=Date.now(),a=makeToolCallEvent({bridgeIndex:t,toolName:e.toolName,input:r,inputJson:e.inputJson,toolCallId:n.toolCallId,replayed:!0,startedAtMs:i});await emitNestedToolCall(a);let o=Date.now();await finishToolEvent({...a,status:`rejected`,completedAtMs:o,durationMs:o-i,error:n.error}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!1,dateNowMs:n.dateNowMs,error:n.error});return}if(n.status===`approval-required`){if(g?.approvalId===n.approvalId&&g.approved===!0){let a=Date.now(),o=makeToolCallEvent({bridgeIndex:t,toolName:e.toolName,input:r,inputJson:e.inputJson,toolCallId:n.toolCallId,replayed:!1,startedAtMs:a});await emitNestedToolCall(o);let c=startNestedToolSpan(o),l=await invokeHostTool({toolName:e.toolName,inputJson:e.inputJson,tools:s,baseExecutionOptions:z,codeModeOptions:f??{},maxToolInputBytes:v.maxToolInputBytes,maxToolOutputBytes:v.maxToolOutputBytes,toolCallId:n.toolCallId,skipApproval:!0}).catch(e=>{throw recordTelemetryError(c,e),e}).finally(()=>endTelemetrySpan(c));if(l.type===`approval-required`)throw new CodeModeProtocolError(`Approved continuation for ${e.toolName} requested approval again.`,{invocationId:b,requestId:e.requestId,toolName:e.toolName,approvalId:n.approvalId});if(l.type===`interrupted`){let r=`${n.toolCallId}:interrupt`;F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:n.toolCallId,interruptId:r,interruptPayload:l.payload,status:`interrupted`},requestInterrupt(t-1);return}let u=Date.now();F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:n.toolCallId,status:`fulfilled`,dateNowMs:u,valueJson:l.valueJson},await finishToolEvent({...o,status:`fulfilled`,completedAtMs:u,durationMs:u-a,outputBytes:byteLength(l.valueJson),output:fromJsonPayload(l.valueJson)}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!0,dateNowMs:u,valueJson:l.valueJson});return}if(g?.approvalId===n.approvalId&&g.approved===!1){let i=new CodeModeToolApprovalDeniedError(n.name,n.approvalInput,n.toolCallId,g.reason),a=serializeError(i),s=serializeBridgeErrorForGuest(i,`tool`),u=Date.now();F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:n.toolCallId,status:`rejected`,dateNowMs:u,error:s},await finishToolEvent({invocationId:b,outerToolCallId:z.toolCallId,bridgeIndex:t,toolName:e.toolName,input:r,inputBytes:byteLength(e.inputJson),toolCallId:n.toolCallId,replayed:!1,startedAtMs:u,status:`rejected`,completedAtMs:u,durationMs:0,error:a}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!1,dateNowMs:u,error:s});return}requestInterrupt(t-1);return}if(n.status===`interrupted`){if(_?.interruptId===n.interruptId){let i={interruptId:n.interruptId,payload:n.interruptPayload,resolution:_.resolution},a=Date.now(),o=makeToolCallEvent({bridgeIndex:t,toolName:e.toolName,input:r,inputJson:e.inputJson,toolCallId:n.toolCallId,replayed:!1,startedAtMs:a});await emitNestedToolCall(o);let c=startNestedToolSpan(o),l=await invokeHostTool({toolName:e.toolName,inputJson:e.inputJson,tools:s,baseExecutionOptions:z,codeModeOptions:f??{},maxToolInputBytes:v.maxToolInputBytes,maxToolOutputBytes:v.maxToolOutputBytes,toolCallId:n.toolCallId,codeModeInterrupt:i,skipApproval:!0}).catch(e=>{throw recordTelemetryError(c,e),e}).finally(()=>endTelemetrySpan(c));if(l.type===`approval-required`){F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:n.toolCallId,approvalId:createApprovalId(n.toolCallId),approvalInput:l.input,status:`approval-required`},requestInterrupt(t-1);return}if(l.type===`interrupted`){F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:n.toolCallId,interruptId:`${n.toolCallId}:interrupt`,interruptPayload:l.payload,status:`interrupted`},requestInterrupt(t-1);return}let u=Date.now();F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:n.toolCallId,status:`fulfilled`,dateNowMs:u,valueJson:l.valueJson},await finishToolEvent({...o,status:`fulfilled`,completedAtMs:u,durationMs:u-a,outputBytes:byteLength(l.valueJson),output:fromJsonPayload(l.valueJson)}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!0,dateNowMs:u,valueJson:l.valueJson});return}if(_!==void 0&&_.interruptId!==n.interruptId)throw new CodeModeProtocolError(`Interrupt resolution ${_.interruptId} does not match pending code-mode interrupt ${n.interruptId}.`,{expectedInterruptId:n.interruptId,receivedInterruptId:_.interruptId});requestInterrupt(t-1);return}return}let a=`${z.toolCallId}:tool-${++T}`,u=Date.now(),d=makeToolCallEvent({bridgeIndex:t,toolName:e.toolName,input:r,inputJson:e.inputJson,toolCallId:a,replayed:!1,startedAtMs:u});await emitNestedToolCall(d);let p=startNestedToolSpan(d),m=await invokeHostTool({toolName:e.toolName,inputJson:e.inputJson,tools:s,baseExecutionOptions:z,codeModeOptions:f??{},maxToolInputBytes:v.maxToolInputBytes,maxToolOutputBytes:v.maxToolOutputBytes,toolCallId:a}).catch(e=>{throw recordTelemetryError(p,e),e}).finally(()=>endTelemetrySpan(p));if(m.type===`approval-required`){F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:a,approvalId:createApprovalId(a),approvalInput:m.input,status:`approval-required`},requestInterrupt(t-1);return}if(m.type===`interrupted`){F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:a,interruptId:`${a}:interrupt`,interruptPayload:m.payload,status:`interrupted`},requestInterrupt(t-1);return}let h=Date.now();F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:a,status:`fulfilled`,dateNowMs:h,valueJson:m.valueJson},await finishToolEvent({...d,status:`fulfilled`,completedAtMs:h,durationMs:h-u,outputBytes:byteLength(m.valueJson),output:fromJsonPayload(m.valueJson)}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!0,dateNowMs:h,valueJson:m.valueJson})}catch(a){if(a instanceof CodeModeProtocolError){failTerminal(a);return}let o=serializeError(a),s=serializeBridgeErrorForGuest(a,`tool`),u=Date.now(),d=n?.kind===`tool`?n.toolCallId:`${z.toolCallId}:tool-${T}`;n?.kind===`tool`&&(n.status===`approval-required`||n.status===`interrupted`)&&(n.status===`approval-required`&&g?.approvalId===n.approvalId&&g.approved===!0||n.status===`interrupted`&&_?.interruptId===n.interruptId)?F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:n.toolCallId,status:`rejected`,dateNowMs:u,error:s}:n===void 0&&(F[t-1]={kind:`tool`,name:e.toolName,inputJson:e.inputJson,toolCallId:d,status:`rejected`,dateNowMs:u,error:s}),await finishToolEvent({invocationId:b,outerToolCallId:z.toolCallId,bridgeIndex:t,toolName:e.toolName,input:r,inputBytes:byteLength(e.inputJson),toolCallId:d,replayed:!1,startedAtMs:u,status:`rejected`,completedAtMs:u,durationMs:0,error:o}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!1,dateNowMs:u,error:s})}finally{M--,settleInterruptIfReady(),settleAccountingIfDone()}}async function handleFetchRequest(e,t){let n=JSON.stringify(e.request),r=F[t-1];try{if(r!==void 0){if(assertReplayEntryMatches(r,{kind:`fetch`,name:e.request.url,inputJson:n}),r.kind!==`fetch`)throw new CodeModeProtocolError(`Continuation replay expected a fetch ledger entry.`,{invocationId:b,bridgeIndex:t,kind:r.kind});if(r.status===`fulfilled`){let i=Date.now(),a=makeFetchRequestEvent({bridgeIndex:t,inputJson:n,request:e.request,replayed:!0,startedAtMs:i});await emitFetchRequest(a);let o=Date.now();await finishFetchEvent({...a,status:`fulfilled`,completedAtMs:o,durationMs:o-i,outputBytes:byteLength(r.valueJson)}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!0,dateNowMs:r.dateNowMs,valueJson:r.valueJson});return}if(r.status===`rejected`){let i=Date.now(),a=makeFetchRequestEvent({bridgeIndex:t,inputJson:n,request:e.request,replayed:!0,startedAtMs:i});await emitFetchRequest(a);let o=Date.now();await finishFetchEvent({...a,status:`rejected`,completedAtMs:o,durationMs:o-i,error:r.error}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!1,dateNowMs:r.dateNowMs,error:r.error});return}throw new CodeModeProtocolError(`Continuation ledger entry for fetch cannot be interrupted.`,{invocationId:b,requestId:e.requestId})}let a=Date.now(),o=makeFetchRequestEvent({bridgeIndex:t,inputJson:n,request:e.request,replayed:!1,startedAtMs:a});await emitFetchRequest(o);let s=startFetchSpan(o),c=toJsonPayload(await executeHostFetch({request:e.request,fetch:v.fetch,policy:v.fetchPolicy,signal:w.signal}).catch(e=>{throw recordTelemetryError(s,e),e}).finally(()=>endTelemetrySpan(s)),v.maxResultBytes,`fetch response`),l=Date.now();F[t-1]={kind:`fetch`,name:e.request.url,inputJson:n,status:`fulfilled`,dateNowMs:l,valueJson:c},await finishFetchEvent({...o,status:`fulfilled`,completedAtMs:l,durationMs:l-a,outputBytes:byteLength(c)}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!0,dateNowMs:l,valueJson:c})}catch(a){if(a instanceof CodeModeProtocolError){failTerminal(a);return}let o=serializeError(a),s=serializeBridgeErrorForGuest(a,`fetch`),u=Date.now();r===void 0&&(F[t-1]={kind:`fetch`,name:e.request.url,inputJson:n,status:`rejected`,dateNowMs:u,error:s}),await finishFetchEvent({invocationId:b,outerToolCallId:z.toolCallId,bridgeIndex:t,url:e.request.url,method:e.request.method??`GET`,inputBytes:byteLength(n),replayed:!1,startedAtMs:u,status:`rejected`,completedAtMs:u,durationMs:0,error:o}),postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!1,dateNowMs:u,error:s})}finally{M--,settleInterruptIfReady(),settleAccountingIfDone()}}function markWorkerRequest(e){if(!k&&N===void 0){if(E!==void 0){failTerminal(new CodeModeProtocolError(`Worker sent ${e.type} after result for invocation ${b}.`,{invocationId:b,requestId:e.requestId,messageType:e.type}));return}if(P.has(e.requestId)){failTerminal(new CodeModeProtocolError(`Worker reused requestId ${e.requestId} for invocation ${b}.`,{invocationId:b,requestId:e.requestId,messageType:e.type}));return}if(P.add(e.requestId),j>=v.maxBridgeRequests){let n=new CodeModeBridgeLimitError(`Code mode exceeded the maxBridgeRequests limit (${v.maxBridgeRequests}).`,{invocationId:b,requestId:e.requestId,maxBridgeRequests:v.maxBridgeRequests});postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!1,dateNowMs:Date.now(),error:serializeBridgeErrorForGuest(n,`bridge`)});return}if(M>=v.maxInFlightBridgeRequests){let n=new CodeModeBridgeLimitError(`Code mode exceeded the maxInFlightBridgeRequests limit (${v.maxInFlightBridgeRequests}).`,{invocationId:b,requestId:e.requestId,maxInFlightBridgeRequests:v.maxInFlightBridgeRequests});postBridgeResponse({type:`bridge-response`,invocationId:b,requestId:e.requestId,success:!1,dateNowMs:Date.now(),error:serializeBridgeErrorForGuest(n,`bridge`)});return}return j++,M++,j}}function postBridgeResponse(e){if(!(k||A))try{S.postMessage(e)}catch(e){failTerminal(e)}}function requestInterrupt(e){N??=e}function settleInterruptIfReady(){if(N===void 0||k||M>0)return;let e=N,t=F[e];if(t===void 0||t.kind!==`tool`){failTerminal(new CodeModeProtocolError(`Code mode interruption references a missing tool ledger entry.`,{invocationId:b,interruptEntryIndex:N}));return}if(t.status!==`approval-required`&&t.status!==`interrupted`){failTerminal(new CodeModeProtocolError(`Code mode interruption references a non-pending ledger entry.`,{invocationId:b,interruptEntryIndex:N,status:t.status}));return}let r=signCodeModeContinuation({version:1,js:n,outerToolCallId:z.toolCallId,determinism:{...I},ledger:cloneLedger(F)}),a=t.status===`approval-required`?createApprovalInterrupt(t,r):createGenericInterrupt(t,r);k=!0,abortInvocation(a),cleanupWorker(!1),(async()=>{let n=Date.now(),r=makeToolCallEvent({bridgeIndex:e+1,toolName:t.name,input:fromJsonPayload(t.inputJson),inputJson:t.inputJson,toolCallId:t.toolCallId,replayed:!1,startedAtMs:n});t.status===`interrupted`?await finishToolEvent({...r,status:`interrupted`,completedAtMs:n,durationMs:0,interrupt:a}):await finishToolEvent({...r,status:`approval-required`,completedAtMs:n,durationMs:0,approvalId:t.approvalId}),await emitInterrupt(a),await finishTrace(`interrupted`,{interruptedBy:a.type}),settleCaller(()=>G(a))})()}function createApprovalInterrupt(e,t){return{type:`code-mode-approval-required`,approvalId:e.approvalId,toolCallId:e.toolCallId,toolName:e.name,input:e.approvalInput,continuation:t}}function createGenericInterrupt(e,t){let n={type:`code-mode-interrupt`,interruptId:e.interruptId,kind:e.interruptPayload.kind,toolCallId:e.toolCallId,toolName:e.name,input:fromJsonPayload(e.inputJson),payload:structuredClone(e.interruptPayload)},r={type:`code-mode-pending-continuation`,version:1,outerToolCallId:t.outerToolCallId,interruptId:e.interruptId,requestMessages:[],continuation:t,interrupt:n};return{...n,pendingContinuation:r}}async function handleReadyMessage(e){if(k)return;if(N!==void 0){settleInterruptIfReady();return}if(E===void 0){failTerminal(new CodeModeProtocolError(`Code mode worker became ready without a result for ${e.invocationId}.`,{invocationId:e.invocationId}));return}let t=E;if(t.invocationId!==e.invocationId){failTerminal(new CodeModeProtocolError(`Worker result/ready invocationId mismatch: result was ${t.invocationId}, ready was ${e.invocationId}.`,{resultInvocationId:t.invocationId,readyInvocationId:e.invocationId}));return}if(k=!0,M>0){let e=t.success?new CodeModeDetachedBridgeRequestError(`Code mode returned while ${M} bridge request(s) were still in flight.`,{invocationId:b,inFlightBridgeRequests:M,totalBridgeRequests:j}):deserializeResultError(t);abortInvocation(e),cleanupWorker(!1),await finishTrace(`failed`,{error:e}),settleCaller(()=>K(e));return}if(m!==void 0&&j<F.length){let e=new CodeModeProtocolError(`Code mode continuation returned before replaying the full bridge ledger.`,{invocationId:b,replayedBridgeRequests:j,ledgerEntries:F.length,nextLedgerEntry:F[j]});abortInvocation(e),cleanupWorker(!1),await finishTrace(`failed`,{error:e}),settleCaller(()=>K(e));return}t.success?await finishTrace(`completed`):await finishTrace(`failed`,{error:deserializeResultError(t)}),cleanupWorker(!0),settleCaller(()=>settleWithResultMessage(t,G,K))}}function acquireWorker(e){let t=idleWorkers.pop();for(;t?.destroyed;)t=idleWorkers.pop();return t??=createWorker(),t.worker.removeAllListeners(`exit`),t.worker.ref(),trimIdleWorkers(Math.max(0,e-activeInvocations)),t}function createWorker(){return{worker:new Worker(getInlineWorkerUrl()),destroyed:!1}}function getInlineWorkerUrl(){return inlineWorkerUrl??=new URL(`data:text/javascript;base64,${Buffer.from(INLINE_CODE_MODE_WORKER_SOURCE).toString(`base64`)}`),inlineWorkerUrl}function releaseWorker(e){e.destroyed||(e.worker.once(`exit`,()=>{e.destroyed=!0;let t=idleWorkers.indexOf(e);t!==-1&&idleWorkers.splice(t,1)}),e.worker.unref(),idleWorkers.push(e))}function destroyWorker(e){e.destroyed||(e.destroyed=!0,e.worker.removeAllListeners(),e.worker.terminate())}function trimIdleWorkers(e){for(;idleWorkers.length>e;){let e=idleWorkers.pop();e!==void 0&&destroyWorker(e)}}function releaseInvocationSlot(e){activeInvocations=Math.max(0,activeInvocations-1);let t=getMaxWorkers({memoryLimitBytes:e,activeWorkers:activeInvocations});trimIdleWorkers(Math.max(0,t-activeInvocations))}function deserializeResultError(e){return deserializeError(e.error??{name:`Error`,message:`Unknown worker error.`})}function settleWithResultMessage(e,t,n){if(!e.success){n(deserializeResultError(e));return}t(e.valueJson===``||e.valueJson===void 0?void 0:JSON.parse(e.valueJson))}function fromJsonPayload(e){return e===``?void 0:JSON.parse(e)}function cloneLedger(e){return e.map(e=>{switch(e.status){case`fulfilled`:return{...e};case`rejected`:return{...e,error:{...e.error}};case`approval-required`:return{...e,approvalInput:structuredClone(e.approvalInput)};case`interrupted`:return{...e,interruptPayload:structuredClone(e.interruptPayload)};default:return e}})}function assertReplayEntryMatches(e,t){if(e.kind!==t.kind||e.name!==t.name||e.inputJson!==t.inputJson)throw new CodeModeProtocolError(`Code mode continuation replay diverged from the recorded bridge ledger.`,{expected:{kind:e.kind,name:e.name,inputJson:e.inputJson},received:t})}function assertDeterminismState(e){if(!Number.isFinite(e.dateNowMs)||!Number.isInteger(e.dateNowMs))throw new CodeModeProtocolError(`Code mode continuation determinism dateNowMs must be an integer.`,{dateNowMs:e.dateNowMs});if(!/^[0-9a-f]{32}$/i.test(e.randomSeed))throw new CodeModeProtocolError(`Code mode continuation determinism randomSeed must be a 128-bit hex string.`,{randomSeed:e.randomSeed})}function assertContinuationLedgerShape(e){let t=new Set;for(let[n,r]of e.ledger.entries()){if(r.kind!==`tool`&&r.kind!==`fetch`)throw new CodeModeProtocolError(`Code mode continuation ledger entry has an unknown kind.`,{index:n,kind:r.kind});if(typeof r.name!=`string`)throw new CodeModeProtocolError(`Code mode continuation ledger entry name must be a string.`,{index:n,name:r.name});if(assertJsonPayload(r.inputJson,`ledger[${n}].inputJson`),r.kind===`fetch`){if(r.status===`fulfilled`){assertFiniteDateNow(r.dateNowMs,n),assertJsonPayload(r.valueJson,`ledger[${n}].valueJson`);continue}if(r.status===`rejected`){assertFiniteDateNow(r.dateNowMs,n),assertSerializableError(r.error,n);continue}throw new CodeModeProtocolError(`Fetch continuation ledger entry cannot be pending.`,{index:n,status:r.status})}if(typeof r.toolCallId!=`string`||!r.toolCallId.startsWith(`${e.outerToolCallId}:tool-`))throw new CodeModeProtocolError(`Tool continuation ledger entry has an unexpected toolCallId.`,{index:n,toolCallId:r.toolCallId,outerToolCallId:e.outerToolCallId});if(t.has(r.toolCallId))throw new CodeModeProtocolError(`Tool continuation ledger contains a duplicate toolCallId.`,{index:n,toolCallId:r.toolCallId});switch(t.add(r.toolCallId),r.status){case`fulfilled`:assertFiniteDateNow(r.dateNowMs,n),assertJsonPayload(r.valueJson,`ledger[${n}].valueJson`);break;case`rejected`:assertFiniteDateNow(r.dateNowMs,n),assertSerializableError(r.error,n);break;case`approval-required`:if(typeof r.approvalId!=`string`||!r.approvalId.startsWith(`${r.toolCallId}:approval-`))throw new CodeModeProtocolError(`Approval continuation ledger entry has an unexpected approvalId.`,{index:n,toolCallId:r.toolCallId,approvalId:r.approvalId});break;case`interrupted`:if(r.interruptId!==`${r.toolCallId}:interrupt`)throw new CodeModeProtocolError(`Generic interruption ledger entry has an unexpected interruptId.`,{index:n,toolCallId:r.toolCallId,interruptId:r.interruptId});if(typeof r.interruptPayload!=`object`||r.interruptPayload===null||Array.isArray(r.interruptPayload)||typeof r.interruptPayload.kind!=`string`||r.interruptPayload.kind.length===0)throw new CodeModeProtocolError(`Generic interruption ledger entry payload must include a string kind.`,{index:n,interruptPayload:r.interruptPayload});break;default:throw new CodeModeProtocolError(`Tool continuation ledger entry has an unknown status.`,{index:n,status:r.status})}}}function assertJsonPayload(e,t){if(typeof e!=`string`)throw new CodeModeProtocolError(`${t} must be a string.`,{value:e});if(e!==``)try{JSON.parse(e)}catch(e){throw new CodeModeProtocolError(`${t} must be valid JSON.`,{cause:e instanceof Error?e.message:String(e)})}}function assertFiniteDateNow(e,t){if(!Number.isFinite(e)||!Number.isInteger(e))throw new CodeModeProtocolError(`Continuation ledger dateNowMs must be an integer.`,{index:t,dateNowMs:e})}function assertSerializableError(e,t){let n=e;if(typeof e!=`object`||!e||Array.isArray(e)||typeof n.name!=`string`||typeof n.message!=`string`)throw new CodeModeProtocolError(`Rejected continuation ledger entry has an invalid serialized error.`,{index:t,error:e})}function getMaxNestedToolCounter(e){let t=0;for(let n of e){if(n.kind!==`tool`)continue;let e=/:tool-(\d+)$/.exec(n.toolCallId);e&&(t=Math.max(t,Number(e[1])))}return t}function createDeterminismState(){return{dateNowMs:Date.now(),randomSeed:randomBytes(16).toString(`hex`)}}function createApprovalId(e){return`${e}:approval-${randomBytes(16).toString(`hex`)}`}function byteLength(e){return new TextEncoder().encode(e).byteLength}function toTraceError(e){return isSerializableError(e)?{name:e.name,message:e.message,...e.stack===void 0?{}:{stack:e.stack},...e.code===void 0?{}:{code:e.code},...e.details===void 0?{}:{details:e.details}}:serializeError(e)}function isSerializableError(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;return typeof t.name==`string`&&typeof t.message==`string`&&(t.stack===void 0||typeof t.stack==`string`)&&(t.code===void 0||typeof t.code==`string`)}function cloneTrace(e){return{...e,bridgeRequests:e.bridgeRequests.map(e=>({...e,...e.error===void 0?{}:{error:{...e.error}}})),...e.error===void 0?{}:{error:{...e.error}}}}export{getCodeModeWorkerUrl,getDefaultCodeModeWorkerUrl,runManagedCodeMode};
|