experimental-ash 0.35.0 → 0.36.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 +23 -0
- 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 +1 -1
- package/dist/docs/public/auth-and-route-protection.md +4 -4
- package/dist/docs/public/channels/{README.md → index.md} +2 -2
- package/dist/docs/public/channels/slack.md +3 -3
- package/dist/docs/public/cli-build-and-debugging.md +1 -1
- package/dist/docs/public/faqs.md +4 -5
- package/dist/docs/public/hooks.md +18 -23
- package/dist/docs/public/meta.json +4 -4
- package/dist/docs/public/sandbox.md +9 -11
- package/dist/docs/public/schedules.md +1 -1
- package/dist/docs/public/session-context.md +25 -27
- 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/docs/public/typescript-api.md +10 -11
- package/dist/src/channel/session.d.ts +3 -29
- package/dist/src/channel/session.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/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/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/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/context/index.d.ts +3 -2
- package/dist/src/public/context/index.js +1 -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/hook.d.ts +9 -49
- 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/todo.js +1 -1
- package/dist/src/runtime/framework-tools/write-file.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- 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
|
@@ -13,7 +13,6 @@ back.
|
|
|
13
13
|
`agent/tools/get_weather.ts`
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
|
-
import { getSession } from "experimental-ash/context";
|
|
17
16
|
import { defineTool } from "experimental-ash/tools";
|
|
18
17
|
import { z } from "zod";
|
|
19
18
|
|
|
@@ -22,12 +21,10 @@ export default defineTool({
|
|
|
22
21
|
inputSchema: z.object({
|
|
23
22
|
city: z.string(),
|
|
24
23
|
}),
|
|
25
|
-
async execute(input) {
|
|
26
|
-
const session = getSession();
|
|
27
|
-
|
|
24
|
+
async execute(input, ctx) {
|
|
28
25
|
return {
|
|
29
26
|
city: input.city,
|
|
30
|
-
sessionId: session.
|
|
27
|
+
sessionId: ctx.session.id,
|
|
31
28
|
temperatureF: 72,
|
|
32
29
|
};
|
|
33
30
|
},
|
|
@@ -40,17 +37,17 @@ There is no `name` override and no compile-time normalization — if you want a
|
|
|
40
37
|
identifier, name the file in snake_case.
|
|
41
38
|
|
|
42
39
|
`defineTool`, `disableTool`, `defineBashTool`, `defineReadFileTool`, and `defineWriteFileTool` live on the `experimental-ash/tools` subpath.
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
`defineState` lives on `experimental-ash/context`. Session metadata, sandbox access, and skill access
|
|
41
|
+
are available through the `ctx` parameter passed to `execute`.
|
|
45
42
|
|
|
46
43
|
## What A Tool Definition Needs
|
|
47
44
|
|
|
48
45
|
- a filename slug under `agent/tools/` (this is the model-facing tool name)
|
|
49
46
|
- `description`
|
|
50
47
|
- `inputSchema` — a Zod schema (or any Standard Schema). Required, matching the AI SDK's `Tool` contract. For a tool with no input, pass `z.object({})`.
|
|
51
|
-
- `execute(input,
|
|
48
|
+
- `execute(input, ctx)` — the tool's implementation. `ctx` provides session metadata, sandbox access, and skill access.
|
|
52
49
|
|
|
53
|
-
The AI SDK uses `inputSchema` to validate and transform model input (including Zod defaults) and to type `execute(input)`.
|
|
50
|
+
The AI SDK uses `inputSchema` to validate and transform model input (including Zod defaults) and to type the `input` parameter in `execute(input, ctx)`.
|
|
54
51
|
|
|
55
52
|
## Schemas
|
|
56
53
|
|
|
@@ -75,14 +72,13 @@ export default defineTool({
|
|
|
75
72
|
|
|
76
73
|
## Runtime Helpers Inside Tools
|
|
77
74
|
|
|
78
|
-
|
|
75
|
+
The `ctx` parameter passed to `execute` is the primary way to access runtime state:
|
|
79
76
|
|
|
80
|
-
- `
|
|
81
|
-
- `getSandbox()` for the live sandbox handle
|
|
82
|
-
- `getSkill(identifier)` for reading skill metadata and packaged skill files
|
|
77
|
+
- `ctx.session` for session metadata, turn, auth, and parent lineage data
|
|
78
|
+
- `ctx.getSandbox()` for the live sandbox handle
|
|
79
|
+
- `ctx.getSkill(identifier)` for reading skill metadata and packaged skill files
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
evaluation.
|
|
81
|
+
These are available inside `execute` and other active authored runtime execution contexts.
|
|
86
82
|
|
|
87
83
|
## When A Tool Runs
|
|
88
84
|
|
|
@@ -131,9 +127,9 @@ import { bash } from "experimental-ash/tools/defaults";
|
|
|
131
127
|
|
|
132
128
|
export default defineTool({
|
|
133
129
|
...bash,
|
|
134
|
-
async execute(input) {
|
|
130
|
+
async execute(input, ctx) {
|
|
135
131
|
console.log("[bash]", input);
|
|
136
|
-
return bash.execute(input);
|
|
132
|
+
return bash.execute(input, ctx);
|
|
137
133
|
},
|
|
138
134
|
});
|
|
139
135
|
```
|
|
@@ -50,11 +50,12 @@ Most apps use `defineAgent`, `defineTool`, and `defineSandbox` the most.
|
|
|
50
50
|
|
|
51
51
|
## Runtime Helpers
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Session metadata, sandbox access, and skill access are available through the `ctx` parameter
|
|
54
|
+
passed to tool `execute`, hook handlers, and channel event handlers:
|
|
54
55
|
|
|
55
|
-
- `
|
|
56
|
-
- `getSandbox()` - live sandbox handle for the current agent
|
|
57
|
-
- `getSkill(identifier)` - handle for a named skill visible to the current agent
|
|
56
|
+
- `ctx.session` - current session, turn, auth, and optional parent lineage
|
|
57
|
+
- `ctx.getSandbox()` - live sandbox handle for the current agent
|
|
58
|
+
- `ctx.getSkill(identifier)` - handle for a named skill visible to the current agent
|
|
58
59
|
- `defineState(name, initial)` - typed durable state with `get()` and `update()` (`experimental-ash/context`)
|
|
59
60
|
|
|
60
61
|
Related exported types by subpath:
|
|
@@ -154,7 +155,7 @@ Channel types exported from `experimental-ash/channels`:
|
|
|
154
155
|
- `POST` - route helper for POST endpoints
|
|
155
156
|
- `GET` - route helper for GET endpoints
|
|
156
157
|
- `Session` - session handle returned by `send()`
|
|
157
|
-
- `SessionHandle` - read-only session handle
|
|
158
|
+
- `SessionHandle` - read-only session handle available as `ctx.session`
|
|
158
159
|
- `SendOptions` - options for `send(message, options)`
|
|
159
160
|
|
|
160
161
|
`RunMode` is explicit: `"conversation"` sessions may wait for follow-up input, while `"task"`
|
|
@@ -199,14 +200,12 @@ Event handlers on the channel config receive typed event data:
|
|
|
199
200
|
### Typed Tool
|
|
200
201
|
|
|
201
202
|
```ts
|
|
202
|
-
import { getSession } from "experimental-ash/context";
|
|
203
203
|
import { defineTool } from "experimental-ash/tools";
|
|
204
204
|
```
|
|
205
205
|
|
|
206
206
|
### Sandbox Access
|
|
207
207
|
|
|
208
208
|
```ts
|
|
209
|
-
import { getSandbox } from "experimental-ash/sandbox";
|
|
210
209
|
import { defineTool } from "experimental-ash/tools";
|
|
211
210
|
import { defineBashTool } from "experimental-ash/tools";
|
|
212
211
|
```
|
|
@@ -214,7 +213,7 @@ import { defineBashTool } from "experimental-ash/tools";
|
|
|
214
213
|
### Skill Access
|
|
215
214
|
|
|
216
215
|
```ts
|
|
217
|
-
import { defineSkill
|
|
216
|
+
import { defineSkill } from "experimental-ash/skills";
|
|
218
217
|
```
|
|
219
218
|
|
|
220
219
|
### Wrapping Or Disabling A Framework Default
|
|
@@ -254,9 +253,9 @@ import { Braintrust } from "experimental-ash/evals/reporters";
|
|
|
254
253
|
- `defineChannel` and channel factories -> [Channels](./channels/README.md)
|
|
255
254
|
- `defineTool`, `disableTool`, `defineBashTool`, `defineReadFileTool`, `defineWriteFileTool`, and `experimental-ash/tools/defaults` -> [Tools](./tools.md)
|
|
256
255
|
- `defineHook`, `HookContext`, and lifecycle/event types -> [Hooks](./hooks.md)
|
|
257
|
-
- `defineSandbox` and `getSandbox` -> [Sandboxes](./sandbox.md)
|
|
258
|
-
- `defineSkill` and `getSkill` -> [Skills](./skills.md)
|
|
259
|
-
- `
|
|
256
|
+
- `defineSandbox` and `ctx.getSandbox()` -> [Sandboxes](./sandbox.md)
|
|
257
|
+
- `defineSkill` and `ctx.getSkill()` -> [Skills](./skills.md)
|
|
258
|
+
- `ctx.session` -> [Session Context](./session-context.md)
|
|
260
259
|
- subagents (authored with `defineAgent` under `subagents/<id>/agent.ts`) -> [Subagents](./subagents.md)
|
|
261
260
|
- `defineSchedule` -> [Schedules](./schedules.md)
|
|
262
261
|
- `defineEvalSuite`, loaders, reporters, and scorers -> [Evals](./evals.md)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ContextAccessor } from "#context/key.js";
|
|
2
2
|
import type { HandleMessageStreamEvent } from "#protocol/message.js";
|
|
3
|
-
import type { Runtime
|
|
3
|
+
import type { Runtime } from "#channel/types.js";
|
|
4
|
+
import type { SessionAuth } from "#context/keys.js";
|
|
4
5
|
export interface Session {
|
|
5
6
|
readonly id: string;
|
|
6
7
|
readonly continuationToken: string;
|
|
@@ -18,35 +19,8 @@ export interface Session {
|
|
|
18
19
|
*/
|
|
19
20
|
export interface SessionHandle {
|
|
20
21
|
readonly id: string;
|
|
21
|
-
/**
|
|
22
|
-
* Runtime-scoped continuation token (`<channelName>:<channel-local-token>`).
|
|
23
|
-
*/
|
|
24
22
|
readonly continuationToken: string;
|
|
25
|
-
readonly auth:
|
|
26
|
-
readonly initiatorAuth: SessionAuthContext | null;
|
|
27
|
-
/**
|
|
28
|
-
* Re-key the session under a new continuation token.
|
|
29
|
-
*
|
|
30
|
-
* Use this when the channel's resume address depends on data
|
|
31
|
-
* produced during the turn (e.g. Slack auto-anchoring its first
|
|
32
|
-
* post adopts the post's `ts` as the thread root). Pass the
|
|
33
|
-
* channel-local raw token, matching the token shape accepted by
|
|
34
|
-
* route `send()`; the session handle preserves the current channel
|
|
35
|
-
* namespace before writing to runtime context.
|
|
36
|
-
*
|
|
37
|
-
* Effects:
|
|
38
|
-
*
|
|
39
|
-
* - Updates `ContinuationTokenKey` in the active context to the
|
|
40
|
-
* runtime-scoped token (`<channelName>:<rawToken>`).
|
|
41
|
-
* - Causes the workflow runtime to dispose its current park hook
|
|
42
|
-
* and register a new one at the new token at the next step
|
|
43
|
-
* boundary, so follow-up `deliver` calls keyed under the new
|
|
44
|
-
* token resume the same session.
|
|
45
|
-
* - Idempotent — calling with the current token is a no-op.
|
|
46
|
-
*
|
|
47
|
-
* The session must already have a namespaced placeholder
|
|
48
|
-
* continuation token so the handle can preserve the channel name.
|
|
49
|
-
*/
|
|
23
|
+
readonly auth: SessionAuth;
|
|
50
24
|
setContinuationToken(rawToken: string): void;
|
|
51
25
|
}
|
|
52
26
|
export declare function createSession(id: string, continuationToken: string, runtime: Runtime): Session;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";function createSession(e,t,n){return{id:e,continuationToken:t,async getEventStream(t){return n.getEventStream(e,t)}}}function createGetSessionFn(e){return t=>createSession(t,``,e)}function buildSessionHandle(i){return{get id(){return i.get(SessionIdKey)??``},get continuationToken(){return i.get(ContinuationTokenKey)??``},get auth(){return
|
|
1
|
+
import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";function createSession(e,t,n){return{id:e,continuationToken:t,async getEventStream(t){return n.getEventStream(e,t)}}}function createGetSessionFn(e){return t=>createSession(t,``,e)}function buildSessionHandle(i){return{get id(){return i.get(SessionIdKey)??``},get continuationToken(){return i.get(ContinuationTokenKey)??``},get auth(){return{current:i.get(AuthKey)??null,initiator:i.get(InitiatorAuthKey)??null}},setContinuationToken(e){let n=i.get(ContinuationTokenKey)??``,r=namespaceContinuationToken(n,e);n!==r&&i.set(ContinuationTokenKey,r)}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}export{buildSessionHandle,createGetSessionFn,createSession};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AshCallbackContext } from "#public/definitions/callback-context.js";
|
|
2
|
+
/**
|
|
3
|
+
* Builds an {@link AshCallbackContext} from the active ALS scope.
|
|
4
|
+
*
|
|
5
|
+
* Must be called inside a harness step (active `contextStorage.run`).
|
|
6
|
+
* Throws when called outside an ALS scope.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildCallbackContext(): AshCallbackContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{SandboxKey,SessionKey}from"#context/keys.js";import{createSandboxSkillHandle}from"#runtime/skills/sandbox-access.js";import{loadContext}from"#context/container.js";function buildCallbackContext(){let r=loadContext(),i=r.require(SessionKey);return{session:{id:i.sessionId,auth:i.auth,turn:i.turn,parent:i.parent},getSandbox(){let t=r.get(SandboxKey);if(t===void 0)throw Error(`Ash sandbox runtime access is unavailable in the current async context. Call ctx.getSandbox() only from authored runtime functions such as tools, hooks, and channel events.`);return t.get().then(e=>{if(e===null)throw Error(`The sandbox is not available in the current authored runtime context.`);return e})},getSkill(t){let n=r.get(SandboxKey);if(n===void 0)throw Error(`Ash sandbox runtime access is unavailable in the current async context. Call ctx.getSkill() only from authored runtime functions such as tools, hooks, and channel events.`);return createSandboxSkillHandle(n,t)}}}export{buildCallbackContext};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ContinuationTokenKey,SandboxKey,
|
|
1
|
+
import{ContinuationTokenKey,SandboxKey,SessionPreparedKey}from"./keys.js";import{createLogger}from"#internal/logging.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeSkillPackage,writeSkillPackageToSandbox}from"#shared/skill-package.js";import{getAdapterKind}from"#channel/adapter.js";import{emitRecoverableFailedTurn,emitTurnPreamble,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{formatAvailableSkillsSection}from"#execution/skills/instructions.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";const log=createLogger(`hooks.lifecycle`);async function dispatchHookLifecycle(e){let{ctx:t,registry:r,emit:a}=e,o=getHarnessEmissionState(e.session.state),s=buildHookContext(t),c=[],l=e.session;if(r.session.length>0&&t.get(SessionPreparedKey)!==!0){t.set(SessionPreparedKey,!0);let e=[];for(let n of r.session){let r=await n.handler(s);r?.modelContext!==void 0&&r.modelContext.length>0&&c.push(...r.modelContext),e.push(...normalizeLifecycleSkillResults(t,r))}l=await materializeLifecycleSkills(t,l,e)}let u=!1,d=o;try{let e=[];for(let n of r.turn){let r=await n.handler(s);r?.modelContext!==void 0&&r.modelContext.length>0&&c.push(...r.modelContext),e.push(...normalizeLifecycleSkillResults(t,r))}l=await materializeLifecycleSkills(t,l,e)}catch(t){let n=toErrorMessage(t);try{u||=(d=await emitTurnPreamble(a,{message:e.input.message},o,e.runtimeIdentity),!0);let t=await emitRecoverableFailedTurn(a,d,{code:`HOOK_TURN_FAILED`,message:n});return{kind:`turn-failed`,message:n,nextSession:setHarnessEmissionState(l,t)}}catch(e){throw log.error(`Event hook threw while emitting the turn.failed cascade for a lifecycle.turn failure — escalating to session.failed.`,{error:toErrorMessage(e)}),e}}let f=e.input.modelContext??[],p=f.length===0?c:[...f,...c];return{kind:`proceed`,input:p.length>0?{...e.input,modelContext:p}:e.input,nextSession:l}}function normalizeLifecycleSkillResults(e,t){if(t?.skills===void 0||t.skills.length===0)return[];let n=new Set(e.require(BundleKey).resolvedAgent.skills.map(e=>e.name)),r=new Map;for(let e of t.skills){let t=normalizeSkillPackage(e);if(n.has(t.name))throw Error(`Hook-contributed skill "${t.name}" conflicts with an authored skill.`);r.set(t.name,t)}return[...r.values()]}async function materializeLifecycleSkills(e,n,r){if(r.length===0)return n;let i=new Map(r.map(e=>[e.name,e])),a=await e.require(SandboxKey).get();if(a===null)throw Error(`Dynamic skills require a sandbox for the current agent.`);for(let e of i.values())await writeSkillPackageToSandbox({sandbox:a,skill:e});let s=formatAvailableSkillsSection([...i.values()]);return s===null?n:{...n,history:[...n.history,{role:`system`,content:s}]}}async function dispatchStreamEventHooks(e){let t=e.registry.streamEventsByType.get(e.event.type)??[],n=e.registry.streamEventsWildcard;if(t.length===0&&n.length===0)return;let r=buildHookContext(e.ctx);for(let n of t)await n.handler(e.event,r);for(let t of n)await t.handler(e.event,r)}function buildHookContext(t){let n=t.require(BundleKey),r=t.get(ChannelKey),i=t.get(ContinuationTokenKey),a=r===void 0?void 0:getAdapterKind(r);return{...buildCallbackContext(),agent:{name:n.resolvedAgent.config.name??`agent`,nodeId:n.nodeId},channel:{kind:a,continuationToken:i}}}async function runHookLifecycleStep(e,t){let n=await dispatchHookLifecycle(e);return n.kind===`turn-failed`?{next:e.mode===`conversation`?null:{done:!0,output:n.message},session:n.nextSession}:t(n.nextSession,n.input)}export{dispatchHookLifecycle,dispatchStreamEventHooks,runHookLifecycleStep};
|
|
@@ -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};
|
|
@@ -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};
|
|
@@ -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.36.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};
|