experimental-ash 0.35.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +7 -7
- package/dist/docs/internals/context.md +6 -5
- package/dist/docs/internals/core-beliefs.md +2 -2
- package/dist/docs/internals/hooks.md +16 -11
- package/dist/docs/internals/mechanical-invariants.md +4 -4
- package/dist/docs/internals/testing.md +1 -1
- package/dist/docs/public/README.md +11 -11
- package/dist/docs/public/{auth-and-route-protection.md → advanced/auth-and-route-protection.md} +5 -4
- package/dist/docs/public/{cli-build-and-debugging.md → advanced/cli-build-and-debugging.md} +2 -1
- package/dist/docs/public/{context-control.md → advanced/context-control.md} +1 -0
- package/dist/docs/public/{evals.md → advanced/evals.md} +1 -0
- package/dist/docs/public/{faqs.md → advanced/faqs.md} +5 -5
- package/dist/docs/public/{hooks.md → advanced/hooks.md} +19 -23
- package/dist/docs/public/{instrumentation.md → advanced/instrumentation.md} +1 -0
- package/dist/docs/public/advanced/meta.json +19 -0
- package/dist/docs/public/{project-layout.md → advanced/project-layout.md} +1 -0
- package/dist/docs/public/{runs-and-streaming.md → advanced/runs-and-streaming.md} +1 -0
- package/dist/docs/public/{session-context.md → advanced/session-context.md} +26 -27
- package/dist/docs/public/{typescript-api.md → advanced/typescript-api.md} +11 -11
- package/dist/docs/public/{vercel-deployment.md → advanced/vercel-deployment.md} +1 -0
- package/dist/docs/public/{workspace.md → advanced/workspace.md} +1 -0
- package/dist/docs/public/channels/{README.md → index.md} +2 -2
- package/dist/docs/public/channels/slack.md +3 -3
- package/dist/docs/public/meta.json +1 -14
- package/dist/docs/public/sandbox.md +9 -11
- package/dist/docs/public/schedules.md +1 -1
- package/dist/docs/public/skills.md +3 -4
- package/dist/docs/public/subagents.md +1 -1
- package/dist/docs/public/tools.md +13 -17
- package/dist/src/channel/session.d.ts +3 -29
- package/dist/src/channel/session.js +1 -1
- package/dist/src/context/accessors.d.ts +0 -25
- package/dist/src/context/accessors.js +1 -1
- package/dist/src/context/build-callback-context.d.ts +8 -0
- package/dist/src/context/build-callback-context.js +1 -0
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +2 -2
- package/dist/src/evals/define-eval-suite.d.ts +3 -2
- package/dist/src/evals/types.d.ts +38 -12
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/sandbox/bash-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/bash-tool.js +1 -1
- package/dist/src/execution/sandbox/glob-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/glob-tool.js +3 -3
- package/dist/src/execution/sandbox/grep-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/grep-tool.js +3 -3
- package/dist/src/execution/sandbox/read-file-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/read-file-tool.js +1 -1
- package/dist/src/execution/sandbox/write-file-tool.d.ts +2 -1
- package/dist/src/execution/sandbox/write-file-tool.js +1 -1
- package/dist/src/execution/skills/types.d.ts +1 -1
- package/dist/src/execution/tool-compaction.js +1 -1
- package/dist/src/harness/code-mode-approval.js +1 -1
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/step-hooks.d.ts +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/workflow-bundle/builder.js +2 -2
- package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/index.js +1 -1
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/manager.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/worker-source.js +408 -0
- package/dist/src/packages/ash-scaffold/src/channels.js +2 -12
- package/dist/src/packages/ash-scaffold/src/pnpm-workspace.js +11 -0
- package/dist/src/packages/ash-scaffold/src/project.js +1 -1
- package/dist/src/public/channels/discord/defaults.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.d.ts +4 -4
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/slack/defaults.js +4 -4
- package/dist/src/public/channels/slack/slackChannel.d.ts +4 -4
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/defaults.js +3 -3
- package/dist/src/public/channels/teams/teamsChannel.d.ts +4 -4
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/defaults.js +2 -2
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +4 -4
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/defaults.js +2 -2
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +4 -4
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/context/index.d.ts +3 -2
- package/dist/src/public/context/index.js +1 -1
- package/dist/src/public/definitions/agent.d.ts +2 -1
- package/dist/src/public/definitions/callback-context.d.ts +22 -0
- package/dist/src/public/definitions/callback-context.js +1 -0
- package/dist/src/public/definitions/defineChannel.d.ts +16 -4
- package/dist/src/public/definitions/defineChannel.js +1 -1
- package/dist/src/public/definitions/exact.d.ts +7 -0
- package/dist/src/public/definitions/exact.js +1 -0
- package/dist/src/public/definitions/hook.d.ts +10 -49
- package/dist/src/public/definitions/instructions.d.ts +2 -1
- package/dist/src/public/definitions/instrumentation.d.ts +2 -1
- package/dist/src/public/definitions/schedule.d.ts +12 -2
- package/dist/src/public/definitions/skill.d.ts +2 -1
- package/dist/src/public/definitions/tool.d.ts +14 -15
- package/dist/src/public/hooks/index.d.ts +1 -1
- package/dist/src/public/sandbox/index.d.ts +0 -1
- package/dist/src/public/sandbox/index.js +1 -1
- package/dist/src/public/skills/index.d.ts +0 -1
- package/dist/src/public/skills/index.js +1 -1
- package/dist/src/public/tools/defaults.js +1 -1
- package/dist/src/public/tools/define-bash-tool.js +1 -1
- package/dist/src/public/tools/define-glob-tool.js +1 -1
- package/dist/src/public/tools/define-grep-tool.js +1 -1
- package/dist/src/public/tools/define-read-file-tool.js +1 -1
- package/dist/src/public/tools/define-write-file-tool.js +1 -1
- package/dist/src/public/tools/index.d.ts +2 -1
- package/dist/src/public/tools/internal.d.ts +4 -0
- package/dist/src/public/tools/internal.js +1 -1
- package/dist/src/runtime/framework-tools/bash.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search.js +1 -1
- package/dist/src/runtime/framework-tools/connection-tools.js +1 -1
- package/dist/src/runtime/framework-tools/file-state.d.ts +2 -2
- package/dist/src/runtime/framework-tools/file-state.js +1 -1
- package/dist/src/runtime/framework-tools/glob.js +1 -1
- package/dist/src/runtime/framework-tools/grep.js +1 -1
- package/dist/src/runtime/framework-tools/read-file.js +2 -2
- package/dist/src/runtime/framework-tools/skill.js +1 -1
- package/dist/src/runtime/framework-tools/todo.js +1 -1
- package/dist/src/runtime/framework-tools/write-file.js +1 -1
- package/dist/src/runtime/governance/auth/types.d.ts +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/sandbox/state.d.ts +1 -1
- package/package.json +2 -2
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/manager.js +0 -1
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/worker-source.js +0 -1153
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime-assets.js +0 -1
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/approval-continuation.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/approval-response.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/code-mode-tool.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/continuation-capability.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/errors.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/fetch-policy.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/host-interrupt.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/interrupt-continuation.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/options.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/run-code-mode.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/runtime/max-workers.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/serialization.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/source-cache.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/telemetry.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/tool-invocation.js +0 -0
- /package/dist/src/node_modules/.pnpm/{experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_ → experimental-ai-sdk-code-mode@1.0.10_ai@7.0.0-canary.154_zod@4.4.3_}/node_modules/experimental-ai-sdk-code-mode/dist/tool-prompt.js +0 -0
|
@@ -1,42 +1,41 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Session Context"
|
|
3
|
-
description: "Runtime helpers:
|
|
3
|
+
description: "Runtime helpers: ctx.session, ctx.getSandbox, ctx.getSkill, and defineState."
|
|
4
|
+
url: /session-context
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
Ash exposes runtime
|
|
7
|
+
Ash exposes runtime state through the `ctx` parameter passed to tool `execute`, hook handlers,
|
|
8
|
+
and channel event handlers:
|
|
7
9
|
|
|
8
|
-
- `
|
|
9
|
-
- `getSandbox()`
|
|
10
|
-
- `getSkill(identifier)`
|
|
11
|
-
- `defineState(name, initial)` -- typed durable state with `get()` and `update()`
|
|
10
|
+
- `ctx.session` -- session metadata, turn, auth, and parent lineage
|
|
11
|
+
- `ctx.getSandbox()` -- live sandbox handle for the current agent
|
|
12
|
+
- `ctx.getSkill(identifier)` -- handle for a named skill visible to the current agent
|
|
13
|
+
- `defineState(name, initial)` -- typed durable state with `get()` and `update()` (imported from `"experimental-ash/context"`)
|
|
12
14
|
|
|
13
15
|
These APIs work only inside active authored runtime execution such as tools, channel event
|
|
14
16
|
handlers, and authored hooks. They throw when called outside a managed context.
|
|
15
17
|
|
|
16
|
-
## `
|
|
18
|
+
## `ctx.session`
|
|
17
19
|
|
|
18
|
-
Use `
|
|
20
|
+
Use `ctx.session` when you need durable runtime metadata about the current execution.
|
|
19
21
|
|
|
20
22
|
`agent/tools/who_called_me.ts`
|
|
21
23
|
|
|
22
24
|
```ts
|
|
23
|
-
import { getSession } from "experimental-ash/context";
|
|
24
25
|
import { defineTool } from "experimental-ash/tools";
|
|
25
26
|
import { z } from "zod";
|
|
26
27
|
|
|
27
28
|
export default defineTool({
|
|
28
29
|
description: "Return the active session metadata.",
|
|
29
30
|
inputSchema: z.object({}),
|
|
30
|
-
async execute() {
|
|
31
|
-
const session = getSession();
|
|
32
|
-
|
|
31
|
+
async execute(_input, ctx) {
|
|
33
32
|
return {
|
|
34
|
-
sessionId: session.
|
|
35
|
-
turnId: session.turn.id,
|
|
36
|
-
turnSequence: session.turn.sequence,
|
|
37
|
-
currentCaller: session.auth.current?.principalId,
|
|
38
|
-
initiator: session.auth.initiator?.principalId,
|
|
39
|
-
parentSessionId: session.parent?.
|
|
33
|
+
sessionId: ctx.session.id,
|
|
34
|
+
turnId: ctx.session.turn.id,
|
|
35
|
+
turnSequence: ctx.session.turn.sequence,
|
|
36
|
+
currentCaller: ctx.session.auth.current?.principalId,
|
|
37
|
+
initiator: ctx.session.auth.initiator?.principalId,
|
|
38
|
+
parentSessionId: ctx.session.parent?.id,
|
|
40
39
|
};
|
|
41
40
|
},
|
|
42
41
|
});
|
|
@@ -46,7 +45,7 @@ Public session fields:
|
|
|
46
45
|
|
|
47
46
|
- `auth.current`
|
|
48
47
|
- `auth.initiator`
|
|
49
|
-
- `
|
|
48
|
+
- `id`
|
|
50
49
|
- `turn.id`
|
|
51
50
|
- `turn.sequence`
|
|
52
51
|
- optional `parent`
|
|
@@ -59,12 +58,12 @@ Important behavior:
|
|
|
59
58
|
- top-level schedule sessions expose the framework app principal (`principalId: "ash:app"`, `principalType: "runtime"`)
|
|
60
59
|
- `parent` is present for child subagent sessions
|
|
61
60
|
|
|
62
|
-
## `getSandbox()`
|
|
61
|
+
## `ctx.getSandbox()`
|
|
63
62
|
|
|
64
|
-
`getSandbox()` returns a live handle for the current agent's sandbox.
|
|
63
|
+
`ctx.getSandbox()` returns a live handle for the current agent's sandbox.
|
|
65
64
|
|
|
66
65
|
```ts
|
|
67
|
-
const sandbox = await getSandbox();
|
|
66
|
+
const sandbox = await ctx.getSandbox();
|
|
68
67
|
const result = await sandbox.run({ command: "pnpm test" });
|
|
69
68
|
```
|
|
70
69
|
|
|
@@ -81,12 +80,12 @@ child process.
|
|
|
81
80
|
|
|
82
81
|
See [Sandboxes](./sandbox.md) for lifecycle details.
|
|
83
82
|
|
|
84
|
-
## `getSkill(identifier)`
|
|
83
|
+
## `ctx.getSkill(identifier)`
|
|
85
84
|
|
|
86
|
-
`getSkill(identifier)` returns a handle for a named skill visible to the current agent.
|
|
85
|
+
`ctx.getSkill(identifier)` returns a handle for a named skill visible to the current agent.
|
|
87
86
|
|
|
88
87
|
```ts
|
|
89
|
-
const skill = getSkill("research");
|
|
88
|
+
const skill = ctx.getSkill("research");
|
|
90
89
|
const notes = await skill.file("references/checklist.md").text();
|
|
91
90
|
```
|
|
92
91
|
|
|
@@ -151,7 +150,7 @@ import { budget } from "../lib/budget.js";
|
|
|
151
150
|
|
|
152
151
|
export default defineHook({
|
|
153
152
|
lifecycle: {
|
|
154
|
-
turn() {
|
|
153
|
+
turn(ctx) {
|
|
155
154
|
// Reset budget each turn
|
|
156
155
|
budget.update(() => ({ count: 0, cap: 25 }));
|
|
157
156
|
},
|
|
@@ -175,7 +174,7 @@ export default defineHook({
|
|
|
175
174
|
|
|
176
175
|
Safe places:
|
|
177
176
|
|
|
178
|
-
- inside `defineTool(...).execute(
|
|
177
|
+
- inside `defineTool(...).execute(input, ctx)`
|
|
179
178
|
- inside authored callbacks Ash runs inside the runtime
|
|
180
179
|
- after asynchronous boundaries inside the same authored execution chain
|
|
181
180
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "TypeScript API"
|
|
3
3
|
description: "TypeScript API: defineAgent, defineTool, defineSandbox, and all runtime helpers."
|
|
4
|
+
url: /typescript-api
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
This page is the quick reference for Ash's public TypeScript surface.
|
|
@@ -50,11 +51,12 @@ Most apps use `defineAgent`, `defineTool`, and `defineSandbox` the most.
|
|
|
50
51
|
|
|
51
52
|
## Runtime Helpers
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
Session metadata, sandbox access, and skill access are available through the `ctx` parameter
|
|
55
|
+
passed to tool `execute`, hook handlers, and channel event handlers:
|
|
54
56
|
|
|
55
|
-
- `
|
|
56
|
-
- `getSandbox()` - live sandbox handle for the current agent
|
|
57
|
-
- `getSkill(identifier)` - handle for a named skill visible to the current agent
|
|
57
|
+
- `ctx.session` - current session, turn, auth, and optional parent lineage
|
|
58
|
+
- `ctx.getSandbox()` - live sandbox handle for the current agent
|
|
59
|
+
- `ctx.getSkill(identifier)` - handle for a named skill visible to the current agent
|
|
58
60
|
- `defineState(name, initial)` - typed durable state with `get()` and `update()` (`experimental-ash/context`)
|
|
59
61
|
|
|
60
62
|
Related exported types by subpath:
|
|
@@ -154,7 +156,7 @@ Channel types exported from `experimental-ash/channels`:
|
|
|
154
156
|
- `POST` - route helper for POST endpoints
|
|
155
157
|
- `GET` - route helper for GET endpoints
|
|
156
158
|
- `Session` - session handle returned by `send()`
|
|
157
|
-
- `SessionHandle` - read-only session handle
|
|
159
|
+
- `SessionHandle` - read-only session handle available as `ctx.session`
|
|
158
160
|
- `SendOptions` - options for `send(message, options)`
|
|
159
161
|
|
|
160
162
|
`RunMode` is explicit: `"conversation"` sessions may wait for follow-up input, while `"task"`
|
|
@@ -199,14 +201,12 @@ Event handlers on the channel config receive typed event data:
|
|
|
199
201
|
### Typed Tool
|
|
200
202
|
|
|
201
203
|
```ts
|
|
202
|
-
import { getSession } from "experimental-ash/context";
|
|
203
204
|
import { defineTool } from "experimental-ash/tools";
|
|
204
205
|
```
|
|
205
206
|
|
|
206
207
|
### Sandbox Access
|
|
207
208
|
|
|
208
209
|
```ts
|
|
209
|
-
import { getSandbox } from "experimental-ash/sandbox";
|
|
210
210
|
import { defineTool } from "experimental-ash/tools";
|
|
211
211
|
import { defineBashTool } from "experimental-ash/tools";
|
|
212
212
|
```
|
|
@@ -214,7 +214,7 @@ import { defineBashTool } from "experimental-ash/tools";
|
|
|
214
214
|
### Skill Access
|
|
215
215
|
|
|
216
216
|
```ts
|
|
217
|
-
import { defineSkill
|
|
217
|
+
import { defineSkill } from "experimental-ash/skills";
|
|
218
218
|
```
|
|
219
219
|
|
|
220
220
|
### Wrapping Or Disabling A Framework Default
|
|
@@ -254,9 +254,9 @@ import { Braintrust } from "experimental-ash/evals/reporters";
|
|
|
254
254
|
- `defineChannel` and channel factories -> [Channels](./channels/README.md)
|
|
255
255
|
- `defineTool`, `disableTool`, `defineBashTool`, `defineReadFileTool`, `defineWriteFileTool`, and `experimental-ash/tools/defaults` -> [Tools](./tools.md)
|
|
256
256
|
- `defineHook`, `HookContext`, and lifecycle/event types -> [Hooks](./hooks.md)
|
|
257
|
-
- `defineSandbox` and `getSandbox` -> [Sandboxes](./sandbox.md)
|
|
258
|
-
- `defineSkill` and `getSkill` -> [Skills](./skills.md)
|
|
259
|
-
- `
|
|
257
|
+
- `defineSandbox` and `ctx.getSandbox()` -> [Sandboxes](./sandbox.md)
|
|
258
|
+
- `defineSkill` and `ctx.getSkill()` -> [Skills](./skills.md)
|
|
259
|
+
- `ctx.session` -> [Session Context](./session-context.md)
|
|
260
260
|
- subagents (authored with `defineAgent` under `subagents/<id>/agent.ts`) -> [Subagents](./subagents.md)
|
|
261
261
|
- `defineSchedule` -> [Schedules](./schedules.md)
|
|
262
262
|
- `defineEvalSuite`, loaders, reporters, and scorers -> [Evals](./evals.md)
|
|
@@ -179,7 +179,7 @@ export default slackChannel({
|
|
|
179
179
|
if (event.finishReason === "tool-calls") return;
|
|
180
180
|
if (event.message) ctx.thread.post(event.message);
|
|
181
181
|
},
|
|
182
|
-
"session.failed"(
|
|
182
|
+
"session.failed"(_event, ctx) {
|
|
183
183
|
ctx.thread.post("Something went wrong.");
|
|
184
184
|
},
|
|
185
185
|
},
|
|
@@ -372,7 +372,7 @@ Semantics:
|
|
|
372
372
|
|
|
373
373
|
- The target channel's authored `receive(input, { send })` hook owns the continuation-token
|
|
374
374
|
format and the initial state. Callers supply only `{ message, args, auth }`.
|
|
375
|
-
- `auth` flows through to `session.
|
|
375
|
+
- `auth` flows through to `session.auth.initiator` so the target's event handlers and the
|
|
376
376
|
agent's tools can read who started the session.
|
|
377
377
|
- Calling `args.receive(...)` does **not** also start a session on the current channel. The
|
|
378
378
|
inbound channel's response is whatever the route handler returns explicitly (e.g.
|
|
@@ -163,7 +163,7 @@ export default slackChannel({
|
|
|
163
163
|
if (event.finishReason === "tool-calls") return;
|
|
164
164
|
if (event.message) ctx.thread.post(event.message);
|
|
165
165
|
},
|
|
166
|
-
"session.failed"(
|
|
166
|
+
"session.failed"(_event, ctx) {
|
|
167
167
|
ctx.thread.post("Something went wrong.");
|
|
168
168
|
},
|
|
169
169
|
},
|
|
@@ -194,8 +194,8 @@ export default slackChannel({
|
|
|
194
194
|
webhook side via `waitUntil`, so the channel returns `200 OK` to Slack immediately.
|
|
195
195
|
|
|
196
196
|
`events: { ... }` handlers receive runtime events emitted by the harness after the turn dispatches
|
|
197
|
-
(`turn.started`, `message.completed`, `session.failed`, etc.). They
|
|
198
|
-
not on the inbound webhook side.
|
|
197
|
+
(`turn.started`, `message.completed`, `session.failed`, etc.). They receive `(eventData, ctx)` and
|
|
198
|
+
run inside the workflow context, not on the inbound webhook side.
|
|
199
199
|
|
|
200
200
|
### Thread Context
|
|
201
201
|
|
|
@@ -2,30 +2,17 @@
|
|
|
2
2
|
"pages": [
|
|
3
3
|
"getting-started",
|
|
4
4
|
"---",
|
|
5
|
-
"project-layout",
|
|
6
5
|
"agent-ts",
|
|
7
|
-
"context-control",
|
|
8
6
|
"skills",
|
|
9
7
|
"tools",
|
|
10
|
-
"hooks",
|
|
11
8
|
"human-in-the-loop",
|
|
12
9
|
"sandbox",
|
|
13
10
|
"channels",
|
|
14
|
-
"auth-and-route-protection",
|
|
15
11
|
"subagents",
|
|
16
12
|
"schedules",
|
|
17
13
|
"connections",
|
|
18
14
|
"---",
|
|
19
|
-
"
|
|
20
|
-
"runs-and-streaming",
|
|
21
|
-
"session-context",
|
|
22
|
-
"workspace",
|
|
23
|
-
"evals",
|
|
24
|
-
"instrumentation",
|
|
25
|
-
"cli-build-and-debugging",
|
|
26
|
-
"typescript-api",
|
|
27
|
-
"...",
|
|
28
|
-
"faqs",
|
|
15
|
+
"advanced",
|
|
29
16
|
"---",
|
|
30
17
|
"research"
|
|
31
18
|
]
|
|
@@ -114,18 +114,17 @@ and `write_file` tools. The runtime name comes from the file stem (here, `repo_s
|
|
|
114
114
|
## Using The Sandbox From Authored Code
|
|
115
115
|
|
|
116
116
|
Any authored runtime function (tool, step, or model callback) can bind a live sandbox handle via
|
|
117
|
-
`getSandbox()`:
|
|
117
|
+
`ctx.getSandbox()`:
|
|
118
118
|
|
|
119
119
|
```ts
|
|
120
|
-
import { getSandbox } from "experimental-ash/sandbox";
|
|
121
120
|
import { defineTool } from "experimental-ash/tools";
|
|
122
121
|
import { z } from "zod";
|
|
123
122
|
|
|
124
123
|
export default defineTool({
|
|
125
124
|
description: "Append an analytics event to the running session log.",
|
|
126
125
|
inputSchema: z.object({ kind: z.string(), payload: z.string() }),
|
|
127
|
-
async execute({ kind, payload }) {
|
|
128
|
-
const sandbox = await getSandbox();
|
|
126
|
+
async execute({ kind, payload }, ctx) {
|
|
127
|
+
const sandbox = await ctx.getSandbox();
|
|
129
128
|
await sandbox.run({
|
|
130
129
|
command: `echo ${JSON.stringify(JSON.stringify({ kind, payload }))} >> /var/lib/analytics/events.log`,
|
|
131
130
|
});
|
|
@@ -136,7 +135,7 @@ export default defineTool({
|
|
|
136
135
|
|
|
137
136
|
Important rules:
|
|
138
137
|
|
|
139
|
-
- `getSandbox()` takes no arguments and is async.
|
|
138
|
+
- `ctx.getSandbox()` takes no arguments and is async.
|
|
140
139
|
- It only works inside authored runtime execution.
|
|
141
140
|
- Visibility is node-local: the root agent sees the root agent's sandbox; a local subagent sees its
|
|
142
141
|
own sandbox, not the parent's.
|
|
@@ -154,7 +153,7 @@ Use it when you need an absolute path to interpolate into a generated command or
|
|
|
154
153
|
hardcoding `/workspace/` yourself:
|
|
155
154
|
|
|
156
155
|
```ts
|
|
157
|
-
const sandbox = await getSandbox();
|
|
156
|
+
const sandbox = await ctx.getSandbox();
|
|
158
157
|
const analysisRoot = sandbox.resolvePath("python-analysis");
|
|
159
158
|
|
|
160
159
|
await sandbox.writeFile("python-analysis/run.py", "print('ok')\n");
|
|
@@ -176,7 +175,7 @@ different skills, so they should not inherit the parent's filesystem.
|
|
|
176
175
|
with that workspace seeded in.
|
|
177
176
|
- If a subagent authors neither, the framework default is used as-is.
|
|
178
177
|
|
|
179
|
-
Inside a subagent's authored code, `getSandbox()` binds to the subagent's own sandbox.
|
|
178
|
+
Inside a subagent's authored code, `ctx.getSandbox()` binds to the subagent's own sandbox.
|
|
180
179
|
|
|
181
180
|
## Lifecycle Semantics
|
|
182
181
|
|
|
@@ -210,18 +209,17 @@ returned. The accepted option shape is whatever the backend's update call accept
|
|
|
210
209
|
factory; `onSession`'s `use()` overrides any overlapping fields post-create.
|
|
211
210
|
|
|
212
211
|
Unlike `bootstrap`, `onSession` runs inside the active Ash runtime context, so user-scoped setup can
|
|
213
|
-
|
|
212
|
+
read `ctx.session` and derive the current principal without baking credentials into the reusable
|
|
214
213
|
template:
|
|
215
214
|
|
|
216
215
|
```ts
|
|
217
|
-
import { getSession } from "experimental-ash/context";
|
|
218
216
|
import { defineSandbox, vercelBackend } from "experimental-ash/sandbox";
|
|
219
217
|
|
|
220
218
|
export default defineSandbox({
|
|
221
219
|
backend: vercelBackend(),
|
|
222
|
-
async onSession({ use }) {
|
|
220
|
+
async onSession({ use, ctx }) {
|
|
223
221
|
const sandbox = await use({ networkPolicy: "deny-all" });
|
|
224
|
-
const user =
|
|
222
|
+
const user = ctx.session.auth.current;
|
|
225
223
|
if (user === null) return;
|
|
226
224
|
|
|
227
225
|
await sandbox.writeFile(
|
|
@@ -162,7 +162,7 @@ When a schedule fires, the dispatcher takes one of two paths:
|
|
|
162
162
|
2. The agent runs in **task mode** with the app principal.
|
|
163
163
|
3. Output is discarded.
|
|
164
164
|
|
|
165
|
-
In both cases, the schedule session uses the **app principal**: `
|
|
165
|
+
In both cases, the schedule session uses the **app principal**: `ctx.session.auth.current` and `ctx.session.auth.initiator` are set to `"ash:app"` with `principalType: "runtime"`.
|
|
166
166
|
|
|
167
167
|
The session goes through the same durable runtime engine as any other Ash session.
|
|
168
168
|
|
|
@@ -77,18 +77,17 @@ Packaged skills are useful when you want files like:
|
|
|
77
77
|
- `scripts/`
|
|
78
78
|
- example inputs or templates
|
|
79
79
|
|
|
80
|
-
Inside authored runtime code, you can read those packaged files through `getSkill(identifier)`.
|
|
80
|
+
Inside authored runtime code, you can read those packaged files through `ctx.getSkill(identifier)`.
|
|
81
81
|
|
|
82
82
|
```ts
|
|
83
|
-
import { getSkill } from "experimental-ash/skills";
|
|
84
83
|
import { defineTool } from "experimental-ash/tools";
|
|
85
84
|
import { z } from "zod";
|
|
86
85
|
|
|
87
86
|
export default defineTool({
|
|
88
87
|
description: "Load a packaged skill reference file.",
|
|
89
88
|
inputSchema: z.object({}),
|
|
90
|
-
async execute() {
|
|
91
|
-
const research = getSkill("research");
|
|
89
|
+
async execute(_input, ctx) {
|
|
90
|
+
const research = ctx.getSkill("research");
|
|
92
91
|
return await research.file("references/checklist.md").text();
|
|
93
92
|
},
|
|
94
93
|
});
|
|
@@ -108,7 +108,7 @@ Subagent execution gets:
|
|
|
108
108
|
- its own tools
|
|
109
109
|
- its own sandbox (independent of the parent's sandbox)
|
|
110
110
|
- its own `skills/` set (independent of the parent's skills)
|
|
111
|
-
- immediate parent lineage in `
|
|
111
|
+
- immediate parent lineage in `ctx.session.parent`
|
|
112
112
|
|
|
113
113
|
Skills and sandboxes do not cross the parent/child boundary. The subagent only sees skills
|
|
114
114
|
authored under `agent/subagents/<id>/skills/`; skills under the root `agent/skills/` are not
|
|
@@ -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
|
```
|
|
@@ -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};
|
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
import type { SkillHandle } from "#execution/skills/types.js";
|
|
2
|
-
import type { SandboxSession } from "#public/definitions/sandbox.js";
|
|
3
1
|
import type { ContextKey } from "#context/key.js";
|
|
4
|
-
import { type Session } from "#context/keys.js";
|
|
5
2
|
export type { Session, SessionAuth, SessionAuthContext, SessionParent, SessionTurn, } from "#context/keys.js";
|
|
6
|
-
/**
|
|
7
|
-
* Returns the active session for the current authored async execution chain.
|
|
8
|
-
*
|
|
9
|
-
* @throws When called outside of a managed step execution.
|
|
10
|
-
*/
|
|
11
|
-
export declare function getSession(): Session;
|
|
12
|
-
/**
|
|
13
|
-
* Returns the active sandbox session for the current runtime execution.
|
|
14
|
-
*
|
|
15
|
-
* Each agent owns exactly one sandbox; callers do not pass a name.
|
|
16
|
-
*
|
|
17
|
-
* @throws When called outside of a managed step execution or when the
|
|
18
|
-
* sandbox is not available on the current context.
|
|
19
|
-
*/
|
|
20
|
-
export declare function getSandbox(): Promise<SandboxSession>;
|
|
21
3
|
/**
|
|
22
4
|
* Returns the current value of a context key, or `undefined` when unset.
|
|
23
5
|
*
|
|
@@ -56,10 +38,3 @@ export declare function setContext<T>(key: ContextKey<T>, valueOrUpdater: T | ((
|
|
|
56
38
|
* @throws When called outside of a managed step execution.
|
|
57
39
|
*/
|
|
58
40
|
export declare function ensureContext<T>(key: ContextKey<T>, create: () => T): T;
|
|
59
|
-
/**
|
|
60
|
-
* Returns a handle for the named skill visible to the current agent.
|
|
61
|
-
*
|
|
62
|
-
* @throws When called outside of a managed step execution or when the
|
|
63
|
-
* requested skill is not found.
|
|
64
|
-
*/
|
|
65
|
-
export declare function getSkill(identifier: string): SkillHandle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{loadContext}from"#context/container.js";function getContext(e){return loadContext().get(e)}function requireContext(e){return loadContext().require(e)}function hasContext(e){return loadContext().has(e)}function setContext(e,t){return loadContext().set(e,t)}function ensureContext(e,t){return loadContext().ensure(e,t)}export{ensureContext,getContext,hasContext,requireContext,setContext};
|
|
@@ -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{loadContext}from"#context/container.js";import{createSandboxSkillHandle}from"#runtime/skills/sandbox-access.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};
|
|
@@ -19,8 +19,8 @@ export interface SessionAuth {
|
|
|
19
19
|
readonly initiator: SessionAuthContext | null;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* Public session metadata exposed to authored code (tools,
|
|
23
|
-
*
|
|
22
|
+
* Public session metadata exposed to authored code (tools, hooks,
|
|
23
|
+
* channel events) via `ctx.session`.
|
|
24
24
|
*/
|
|
25
25
|
export interface Session {
|
|
26
26
|
readonly auth: SessionAuth;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AshEvalSuiteDefinition, AshEvalSuiteInput } from "#evals/types.js";
|
|
1
|
+
import type { AshEvalSuiteDefinition, AshEvalSuiteInput, AshEvalSuiteInputFields } from "#evals/types.js";
|
|
2
|
+
import type { ExactDefinition } from "#public/definitions/exact.js";
|
|
2
3
|
/**
|
|
3
4
|
* Defines one Ash eval suite.
|
|
4
5
|
*
|
|
@@ -7,4 +8,4 @@ import type { AshEvalSuiteDefinition, AshEvalSuiteInput } from "#evals/types.js"
|
|
|
7
8
|
* either `load` (an async function) or `cases` (a static array), but not
|
|
8
9
|
* both.
|
|
9
10
|
*/
|
|
10
|
-
export declare function defineEvalSuite(input:
|
|
11
|
+
export declare function defineEvalSuite<TInput extends AshEvalSuiteInput>(input: ExactDefinition<TInput, AshEvalSuiteInputFields>): AshEvalSuiteDefinition;
|