experimental-ash 0.41.0 → 0.43.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 +36 -0
- package/dist/docs/internals/hooks.md +53 -11
- package/dist/docs/public/README.md +8 -8
- package/dist/docs/public/advanced/{auth-and-route-protection.md → auth-and-route-protection.mdx} +11 -0
- package/dist/docs/public/advanced/context-control.md +4 -4
- package/dist/docs/public/advanced/{evals.md → evals.mdx} +11 -1
- package/dist/docs/public/advanced/{hooks.md → hooks.mdx} +37 -46
- package/dist/docs/public/advanced/instrumentation.md +92 -3
- package/dist/docs/public/advanced/project-layout.md +5 -5
- package/dist/docs/public/advanced/runs-and-streaming.md +8 -2
- package/dist/docs/public/advanced/session-context.md +1 -1
- package/dist/docs/public/advanced/typescript-api.md +49 -6
- package/dist/docs/public/advanced/vercel-deployment.md +1 -1
- package/dist/docs/public/agent-ts.md +5 -5
- package/dist/docs/public/channels/{discord.md → discord.mdx} +11 -0
- package/dist/docs/public/channels/index.md +10 -10
- package/dist/docs/public/channels/{slack.md → slack.mdx} +11 -0
- package/dist/docs/public/channels/{teams.md → teams.mdx} +12 -0
- package/dist/docs/public/channels/{telegram.md → telegram.mdx} +11 -0
- package/dist/docs/public/channels/{twilio.md → twilio.mdx} +11 -0
- package/dist/docs/public/{connections.md → connections.mdx} +18 -6
- package/dist/docs/public/frontend/README.md +16 -0
- package/dist/docs/public/frontend/meta.json +3 -0
- package/dist/docs/public/frontend/nextjs.md +192 -0
- package/dist/docs/public/frontend/use-ash-agent.md +332 -0
- package/dist/docs/public/{getting-started.md → getting-started.mdx} +12 -1
- package/dist/docs/public/{human-in-the-loop.md → human-in-the-loop.mdx} +12 -1
- package/dist/docs/public/meta.json +1 -0
- package/dist/docs/public/sandbox.md +1 -1
- package/dist/docs/public/{schedules.md → schedules.mdx} +9 -0
- package/dist/docs/public/skills.md +2 -2
- package/dist/docs/public/{subagents.md → subagents.mdx} +10 -0
- package/dist/docs/public/{tools.md → tools.mdx} +62 -36
- package/dist/src/channel/adapter.d.ts +13 -0
- package/dist/src/channel/instrumentation.d.ts +10 -0
- package/dist/src/channel/instrumentation.js +1 -0
- package/dist/src/channel/send.js +1 -1
- package/dist/src/channel/types.d.ts +16 -0
- package/dist/src/cli/commands/channels.d.ts +2 -1
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/compiler/manifest.d.ts +13 -1
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/module-map.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/normalize-skill.d.ts +15 -2
- package/dist/src/compiler/normalize-skill.js +1 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/dynamic-skill-lifecycle.d.ts +23 -0
- package/dist/src/context/dynamic-skill-lifecycle.js +1 -0
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +19 -23
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/hook-lifecycle.d.ts +4 -6
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +10 -9
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/providers/connection.d.ts +9 -0
- package/dist/src/context/providers/connection.js +1 -1
- package/dist/src/context/providers/sandbox.js +1 -1
- package/dist/src/execution/ash-workflow-attributes.d.ts +118 -0
- package/dist/src/execution/ash-workflow-attributes.js +1 -0
- package/dist/src/execution/channel-context.d.ts +5 -0
- package/dist/src/execution/channel-context.js +1 -0
- package/dist/src/execution/create-session-step.d.ts +28 -1
- package/dist/src/execution/create-session-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/durable-session-store.d.ts +7 -0
- package/dist/src/execution/node-step.d.ts +2 -2
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/prewarm.js +1 -1
- package/dist/src/execution/session.d.ts +6 -0
- package/dist/src/execution/session.js +2 -2
- package/dist/src/execution/skills/instructions.d.ts +3 -2
- package/dist/src/execution/subagent-tool.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/code-mode.d.ts +0 -5
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/emission.d.ts +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/instrumentation-config.d.ts +1 -1
- package/dist/src/harness/instrumentation-metadata.d.ts +23 -0
- package/dist/src/harness/instrumentation-metadata.js +1 -0
- package/dist/src/harness/otel-integration.d.ts +2 -2
- package/dist/src/harness/otel-integration.js +1 -1
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/turn-tag-state.d.ts +50 -0
- package/dist/src/harness/turn-tag-state.js +1 -0
- package/dist/src/harness/types.d.ts +20 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.d.ts +0 -1
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/internal/instrumentation.d.ts +39 -0
- package/dist/src/internal/instrumentation.js +1 -0
- package/dist/src/internal/workflow/builtins.d.ts +32 -0
- package/dist/src/internal/workflow/builtins.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +34 -0
- package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-transformer.js +1 -1
- package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
- package/dist/src/packages/ash-scaffold/src/steps/run-add-to-agent.js +2 -2
- package/dist/src/public/channels/slack/attachments.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +6 -0
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/index.d.ts +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +6 -0
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/definitions/defineChannel.d.ts +12 -2
- package/dist/src/public/definitions/defineChannel.js +1 -1
- package/dist/src/public/definitions/hook.d.ts +3 -11
- package/dist/src/public/definitions/instrumentation.d.ts +88 -2
- package/dist/src/public/definitions/skill.d.ts +5 -0
- package/dist/src/public/definitions/tool.d.ts +25 -66
- package/dist/src/public/definitions/tool.js +1 -1
- package/dist/src/public/instrumentation/index.d.ts +1 -4
- package/dist/src/public/instrumentation/index.js +1 -1
- package/dist/src/public/skills/index.d.ts +2 -0
- package/dist/src/public/skills/index.js +1 -1
- package/dist/src/public/tools/index.d.ts +2 -2
- package/dist/src/public/tools/index.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +4 -7
- package/dist/src/runtime/agent/mock-model-skill-selection.d.ts +9 -0
- package/dist/src/runtime/agent/mock-model-skill-selection.js +4 -0
- package/dist/src/runtime/attributes/emit.d.ts +73 -0
- package/dist/src/runtime/attributes/emit.js +1 -0
- package/dist/src/runtime/channels/registry.js +1 -1
- package/dist/src/runtime/connections/mcp-client.js +1 -1
- package/dist/src/runtime/framework-tools/code-mode-connection-auth.d.ts +2 -0
- package/dist/src/runtime/framework-tools/connection-search-dynamic.d.ts +34 -0
- package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -0
- package/dist/src/runtime/framework-tools/index.d.ts +7 -5
- package/dist/src/runtime/framework-tools/index.js +1 -1
- package/dist/src/runtime/prompt/connections.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/resolve-dynamic-skill.d.ts +8 -0
- package/dist/src/runtime/resolve-dynamic-skill.js +1 -0
- package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/runtime/sessions/runtime-context-keys.js +1 -1
- package/dist/src/runtime/types.d.ts +13 -4
- package/dist/src/shared/dynamic-tool-definition.d.ts +57 -80
- package/dist/src/shared/dynamic-tool-definition.js +1 -1
- package/dist/src/shared/guards.d.ts +14 -0
- package/dist/src/shared/guards.js +1 -1
- package/dist/src/shared/skill-definition.d.ts +5 -4
- package/dist/src/shared/tool-definition.d.ts +12 -0
- package/package.json +2 -1
- package/dist/src/runtime/framework-tools/connection-search.d.ts +0 -57
- package/dist/src/runtime/framework-tools/connection-search.js +0 -1
- package/dist/src/runtime/framework-tools/connection-tools.d.ts +0 -55
- package/dist/src/runtime/framework-tools/connection-tools.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# experimental-ash
|
|
2
2
|
|
|
3
|
+
## 0.43.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 52146a5: Migrate `connection_search` from a framework tool singleton to a dynamic tool resolver. Discovered connection tools are now derived from conversation history via `ctx.messages` — no `DiscoveredConnectionToolsKey` durable state or `onCompact` hook needed. Deletes `connection-tools.ts` and the old `connection-search.ts` implementation.
|
|
8
|
+
- 2469218: Unified dynamic tool API: `defineTools` and `defineTool({ events })` are replaced by `defineDynamic`, and the `tool()` entry wrapper is replaced by `defineTool`. Handlers return either a single `defineTool(...)` (named after the file slug) or a `Record<string, defineTool(...)>` (named `slug__key`). The `identity` field is removed from compiled manifests — single vs map detection is now runtime-based.
|
|
9
|
+
- 192a1eb: Add dynamic instrumentation metadata via `metadata["step.started"]`, with per-attempt session, turn, step, channel, and model-input access. The channel projection exposes `kind` (`channel:<filename>` for authored channels, or `http`/`schedule`/`subagent`), also emitted as the `ash.channel.kind` span attribute. Authored metadata is parsed defensively: resolver failures, thenables, reserved `ash.*` keys, and non-string values are dropped without interrupting the model call.
|
|
10
|
+
- d7de8e0: Clean up `DynamicToolResolveContext`: remove `__cache`, add `messages` for history access, add `toModelOutput` to `DynamicToolEntry`, and run the dynamic tool bundler transform on framework tools during the ash build.
|
|
11
|
+
- dc0db8e: Dynamic skills can now be authored with `defineDynamic` + `defineSkill` in `agent/skills/`, matching the `defineDynamic` + `defineTool` pattern for dynamic tools. Resolvers subscribe to lifecycle events (`session.started`, `turn.started`, `step.started`) and return branded `defineSkill(...)` entries that are materialized to the sandbox. Single returns use the file slug as the skill name; map returns use `slug__key`. Hook-contributed skills via `LifecycleHookResult.skills` continue to work but are deprecated in favor of this approach.
|
|
12
|
+
- 80b4c1d: Remove `LifecycleHookResult.skills` — lifecycle hooks can no longer contribute skills. Use `defineDynamic` + `defineSkill` in `agent/skills/` instead.
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 3df1814: Emit `$ash.*` workflow run attributes for agent run observability. Every
|
|
17
|
+
session, turn, and subagent run now tags itself with a small set of
|
|
18
|
+
reserved-namespace attributes (`$ash.type`, `$ash.parent`,
|
|
19
|
+
`$ash.root`, `$ash.subagent`, `$ash.trigger`, `$ash.title`,
|
|
20
|
+
`$ash.model`, `$ash.input_tokens`, `$ash.output_tokens`,
|
|
21
|
+
`$ash.cache_read_tokens`, `$ash.tool_count`) so the Vercel dashboard can
|
|
22
|
+
hydrate the Agent Runs view via the workflow runtime's
|
|
23
|
+
`workflow_run_attributes` table without scraping events.
|
|
24
|
+
|
|
25
|
+
Tag writes are best-effort — runtime failures are logged once per process
|
|
26
|
+
and swallowed so a broken attribute write can never break a session. No
|
|
27
|
+
public API changes; authored agent code never sees the `$ash.*` namespace.
|
|
28
|
+
See `research/active/workflow-run-attributes.md` for the full design.
|
|
29
|
+
|
|
30
|
+
- 70a2d17: Authenticate Slack Enterprise Grid file downloads so agents can read private attachments served from workspace `enterprise.slack.com` hosts.
|
|
31
|
+
- 08e2696: Deploy scaffolded Web Chat routes to Vercel when channel setup adds a deployable route.
|
|
32
|
+
|
|
33
|
+
## 0.42.0
|
|
34
|
+
|
|
35
|
+
### Minor Changes
|
|
36
|
+
|
|
37
|
+
- edce3c9: Unified event dispatch: single `handleEvent` pipeline for all event-based handlers (channels, hooks, dynamic tools). Dynamic tool entries now require the `tool()` wrapper — the bundler transform only matches `execute` inside `tool()` calls.
|
|
38
|
+
|
|
3
39
|
## 0.41.0
|
|
4
40
|
|
|
5
41
|
### Minor Changes
|
|
@@ -124,13 +124,35 @@ itself throws while the dispatcher is emitting the recoverable
|
|
|
124
124
|
`session.failed` instead. This is the bounded second-order behavior
|
|
125
125
|
when both a `lifecycle.turn` and a `turn.failed` event hook fail.
|
|
126
126
|
|
|
127
|
-
Stream
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
### Stream event dispatch (`handleEvent`)
|
|
128
|
+
|
|
129
|
+
Every stream event passes through one `handleEvent` function
|
|
130
|
+
(`execution/workflow-steps.ts`) that coordinates three stages:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
handleEvent(event):
|
|
134
|
+
1. emit(event) — channel adapter handler + durable stream write
|
|
135
|
+
2. dispatchStreamEventHooks — typed bucket, then wildcard bucket
|
|
136
|
+
3. dispatchDynamicToolEvent — resolvers subscribed to event.type
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`emit` handles the channel adapter's event handler (can mutate
|
|
140
|
+
adapter state, can transform the event) and writes the (possibly
|
|
141
|
+
transformed) event to the durable stream. The durable record is
|
|
142
|
+
consistent with what was written even if a downstream handler throws.
|
|
143
|
+
|
|
144
|
+
`dispatchStreamEventHooks` reads the typed bucket
|
|
130
145
|
(`registry.streamEventsByType.get(eventType)`) followed by the flat
|
|
131
|
-
wildcard bucket (`registry.streamEventsWildcard`)
|
|
132
|
-
propagate through the
|
|
133
|
-
|
|
146
|
+
wildcard bucket (`registry.streamEventsWildcard`). Thrown errors
|
|
147
|
+
propagate through the handler; the existing harness error path catches
|
|
148
|
+
them and emits the recoverable `turn.failed` cascade.
|
|
149
|
+
|
|
150
|
+
`dispatchDynamicToolEvent` (`context/dynamic-tool-lifecycle.ts`) runs
|
|
151
|
+
dynamic tool resolvers subscribed to the event type and merges
|
|
152
|
+
resolved tools into `DynamicToolsKey`. The tool-loop reads this key
|
|
153
|
+
right before each model call. See the [event dispatch
|
|
154
|
+
doc](../../research/active/unified-event-dispatch.md) for the full
|
|
155
|
+
design.
|
|
134
156
|
|
|
135
157
|
## `SessionPreparedKey`
|
|
136
158
|
|
|
@@ -162,11 +184,31 @@ The `discover/discover-subagent.ts` path walks each local subagent's
|
|
|
162
184
|
| `lifecycle.turn` | Caught by dispatcher → recoverable `turn.failed` cascade emitted |
|
|
163
185
|
| Stream-event hooks | Propagated through the emit composer → existing harness error path emits `turn.failed` |
|
|
164
186
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
187
|
+
### Full per-turn execution order
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
dispatchHookLifecycle():
|
|
191
|
+
lifecycle.session hooks (once per session, produce modelContext)
|
|
192
|
+
lifecycle.turn hooks (once per turn, produce modelContext)
|
|
193
|
+
|
|
194
|
+
emitTurnPreamble() via handleEvent:
|
|
195
|
+
handleEvent(session.started) → emit, hooks, dynamic tool resolvers
|
|
196
|
+
handleEvent(turn.started) → emit, hooks, dynamic tool resolvers
|
|
197
|
+
handleEvent(message.received) → emit, hooks
|
|
198
|
+
|
|
199
|
+
emitStepStarted() via handleEvent:
|
|
200
|
+
handleEvent(step.started) → emit, hooks, dynamic tool resolvers
|
|
201
|
+
|
|
202
|
+
runOneModelCall():
|
|
203
|
+
read DynamicToolsKey (current tools from all prior events)
|
|
204
|
+
build effective toolset (static + dynamic + connections)
|
|
205
|
+
model.stream()
|
|
206
|
+
|
|
207
|
+
emitStepActions() via handleEvent:
|
|
208
|
+
handleEvent(actions.requested) → emit, hooks, dynamic tool resolvers
|
|
209
|
+
handleEvent(action.result) × N → emit, hooks, dynamic tool resolvers
|
|
210
|
+
handleEvent(step.completed) → emit, hooks
|
|
211
|
+
```
|
|
170
212
|
|
|
171
213
|
## Testing Strategy
|
|
172
214
|
|
|
@@ -15,24 +15,24 @@ Important naming note:
|
|
|
15
15
|
|
|
16
16
|
Read in this order:
|
|
17
17
|
|
|
18
|
-
1. [Getting Started](./getting-started.
|
|
18
|
+
1. [Getting Started](./getting-started.mdx)
|
|
19
19
|
2. [Project Layout](./advanced/project-layout.md)
|
|
20
20
|
3. [`agent.ts`](./agent-ts.md)
|
|
21
21
|
4. [TypeScript API](./advanced/typescript-api.md)
|
|
22
22
|
5. [Context Control](./advanced/context-control.md)
|
|
23
23
|
6. [Skills](./skills.md)
|
|
24
|
-
7. [Tools](./tools.
|
|
25
|
-
8. [Connections](./connections.
|
|
24
|
+
7. [Tools](./tools.mdx)
|
|
25
|
+
8. [Connections](./connections.mdx)
|
|
26
26
|
9. [Workspace](./advanced/workspace.md)
|
|
27
27
|
10. [Sandboxes](./sandbox.md)
|
|
28
28
|
11. [Channels](./channels/README.md)
|
|
29
|
-
12. [Human In The Loop](./human-in-the-loop.
|
|
29
|
+
12. [Human In The Loop](./human-in-the-loop.mdx)
|
|
30
30
|
13. [Session Context](./advanced/session-context.md)
|
|
31
31
|
14. [Sessions And Streaming](./advanced/runs-and-streaming.md)
|
|
32
|
-
15. [Subagents](./subagents.
|
|
33
|
-
16. [Schedules](./schedules.
|
|
34
|
-
17. [Evals](./advanced/evals.
|
|
35
|
-
18. [Auth And Route Protection](./advanced/auth-and-route-protection.
|
|
32
|
+
15. [Subagents](./subagents.mdx)
|
|
33
|
+
16. [Schedules](./schedules.mdx)
|
|
34
|
+
17. [Evals](./advanced/evals.mdx)
|
|
35
|
+
18. [Auth And Route Protection](./advanced/auth-and-route-protection.mdx)
|
|
36
36
|
19. [Vercel Deployment](./advanced/vercel-deployment.md)
|
|
37
37
|
20. [CLI, Build, And Debugging](./advanced/cli-build-and-debugging.md)
|
|
38
38
|
|
package/dist/docs/public/advanced/{auth-and-route-protection.md → auth-and-route-protection.mdx}
RENAMED
|
@@ -16,6 +16,17 @@ These settings apply to:
|
|
|
16
16
|
- `POST /ash/v1/session/:sessionId`
|
|
17
17
|
- `GET /ash/v1/session/:sessionId/stream`
|
|
18
18
|
|
|
19
|
+
<CopyPrompt text="Protect the user's Ash HTTP routes through the channel layer. In Ash, route auth and IP policy live on channel factories, usually agent/channels/ash.ts with ashChannel auth config, not in agent.ts. Inspect the existing channel file and app auth code, replace any generated exampleProductionAuth placeholder with the smallest AuthFn or helper composition, use helpers such as localDev, vercelOidc, none, httpBasic, jwtHmac, jwtEcdsa, or oidc as appropriate, keep secrets in environment variables, preserve localDev and vercelOidc behavior where useful, verify unauthenticated production browser requests are rejected with 401, and do not commit unless the user asks.">
|
|
20
|
+
Protect the user's Ash HTTP routes through the channel layer. In Ash, route auth and IP policy
|
|
21
|
+
live on channel factories, usually agent/channels/ash.ts with ashChannel auth config, not in
|
|
22
|
+
agent.ts. Inspect the existing channel file and app auth code, replace any generated
|
|
23
|
+
exampleProductionAuth placeholder with the smallest AuthFn or helper composition, use helpers such
|
|
24
|
+
as localDev, vercelOidc, none, httpBasic, jwtHmac, jwtEcdsa, or oidc as appropriate, keep secrets
|
|
25
|
+
in environment variables, preserve localDev and vercelOidc behavior where useful, verify
|
|
26
|
+
unauthenticated production browser requests are rejected with 401, and do not commit unless the
|
|
27
|
+
user asks.
|
|
28
|
+
</CopyPrompt>
|
|
29
|
+
|
|
19
30
|
## Generated Web Chat Auth
|
|
20
31
|
|
|
21
32
|
`pnpm create experimental-ash-agent` scaffolds `agent/channels/ash.ts` from the Web Chat example.
|
|
@@ -116,7 +116,7 @@ Subagents are a context-control tool too:
|
|
|
116
116
|
- they can have their own tools and their own sandbox
|
|
117
117
|
- they run inside their own delegated subagent context instead of extending the root agent inline
|
|
118
118
|
|
|
119
|
-
See [Subagents](./subagents.
|
|
119
|
+
See [Subagents](./subagents.mdx).
|
|
120
120
|
|
|
121
121
|
## Choosing The Right Lever
|
|
122
122
|
|
|
@@ -140,8 +140,8 @@ For most agents:
|
|
|
140
140
|
|
|
141
141
|
## What To Read Next
|
|
142
142
|
|
|
143
|
-
- [Tools](./tools.
|
|
144
|
-
- [Hooks](./hooks.
|
|
143
|
+
- [Tools](./tools.mdx)
|
|
144
|
+
- [Hooks](./hooks.mdx)
|
|
145
145
|
- [Skills](./skills.md)
|
|
146
146
|
- [Workspace](./workspace.md)
|
|
147
|
-
- [Subagents](./subagents.
|
|
147
|
+
- [Subagents](./subagents.mdx)
|
|
@@ -13,6 +13,16 @@ Use evals when you want to:
|
|
|
13
13
|
- compare output against expected text, JSON, SQL, or session behavior
|
|
14
14
|
- export results to Braintrust for review and comparison
|
|
15
15
|
|
|
16
|
+
<CopyPrompt text="Add repeatable Ash evals to the user's project. Ash eval suites live under the app root evals directory, use .eval.ts files, and export defineEvalSuite from experimental-ash/evals; suite identity is derived from the file path, not an authored id or name. Inspect existing evals and agent behavior, create a focused smoke suite with model, cases or load, and scores, prefer cheap scorers such as Run.didNotFail, Run.usedTool, Text.includes, Json.deepEqual, or Sql.exactNormalized before LLM judges, add fixture loading only if it helps, run ash eval with the relevant suite flags, and do not commit unless the user asks.">
|
|
17
|
+
Add repeatable Ash evals to the user's project. Ash eval suites live under the app root evals
|
|
18
|
+
directory, use .eval.ts files, and export defineEvalSuite from experimental-ash/evals; suite
|
|
19
|
+
identity is derived from the file path, not an authored id or name. Inspect existing evals and
|
|
20
|
+
agent behavior, create a focused smoke suite with model, cases or load, and scores, prefer cheap
|
|
21
|
+
scorers such as Run.didNotFail, Run.usedTool, Text.includes, Json.deepEqual, or
|
|
22
|
+
Sql.exactNormalized before LLM judges, add fixture loading only if it helps, run ash eval with the
|
|
23
|
+
relevant suite flags, and do not commit unless the user asks.
|
|
24
|
+
</CopyPrompt>
|
|
25
|
+
|
|
16
26
|
## Where Evals Live
|
|
17
27
|
|
|
18
28
|
Ash discovers eval suites under the app root `evals/` directory.
|
|
@@ -276,5 +286,5 @@ For most apps:
|
|
|
276
286
|
## What To Read Next
|
|
277
287
|
|
|
278
288
|
- [TypeScript API](./typescript-api.md)
|
|
279
|
-
- [Tools](./tools.
|
|
289
|
+
- [Tools](./tools.mdx)
|
|
280
290
|
- [Sessions And Streaming](./runs-and-streaming.md)
|
|
@@ -7,10 +7,24 @@ url: /hooks
|
|
|
7
7
|
Hooks are Ash's authored extension points for the per-turn lifecycle and
|
|
8
8
|
the runtime event stream.
|
|
9
9
|
|
|
10
|
+
This page is about `agent/hooks/*.ts` runtime hooks. For the React client hook,
|
|
11
|
+
see [`useAshAgent`](../frontend/use-ash-agent.md).
|
|
12
|
+
|
|
10
13
|
Use a hook when you want to run code **around** a turn (before the model
|
|
11
14
|
runs, around stream events) without writing a tool, a context provider,
|
|
12
15
|
or a channel adapter handler.
|
|
13
16
|
|
|
17
|
+
<CopyPrompt text="Add an Ash hook to the user's project. Ash hooks live under agent/hooks, use defineHook from experimental-ash/hooks, and can subscribe to lifecycle.session, lifecycle.turn, or stream events. Use lifecycle hooks when the model needs ephemeral modelContext before the next model call; use events handlers for observe-only side effects after events are durably recorded. Inspect existing hooks and agent/lib, choose the smallest hook file and path-derived slug, use defineState only when durable shared state is needed, wrap best-effort side effects so they do not fail sessions accidentally, verify the relevant lifecycle or stream event behavior, and do not commit unless the user asks.">
|
|
18
|
+
Add an Ash hook to the user's project. Ash hooks live under agent/hooks, use defineHook from
|
|
19
|
+
experimental-ash/hooks, and can subscribe to lifecycle.session, lifecycle.turn, or stream events.
|
|
20
|
+
Use lifecycle hooks when the model needs ephemeral modelContext before the next model call; use
|
|
21
|
+
events handlers for observe-only side effects after events are durably recorded. Inspect existing
|
|
22
|
+
hooks and agent/lib, choose the smallest hook file and path-derived slug, use defineState only
|
|
23
|
+
when durable shared state is needed, wrap best-effort side effects so they do not fail sessions
|
|
24
|
+
accidentally, verify the relevant lifecycle or stream event behavior, and do not commit unless the
|
|
25
|
+
user asks.
|
|
26
|
+
</CopyPrompt>
|
|
27
|
+
|
|
14
28
|
## The Main API
|
|
15
29
|
|
|
16
30
|
`agent/hooks/audit.ts`
|
|
@@ -103,7 +117,7 @@ Lifecycle hooks share one signature:
|
|
|
103
117
|
```ts
|
|
104
118
|
type LifecycleHook = (
|
|
105
119
|
ctx: HookContext,
|
|
106
|
-
) => void | { modelContext?: readonly ModelMessage[]
|
|
120
|
+
) => void | { modelContext?: readonly ModelMessage[] } | Promise<…>;
|
|
107
121
|
```
|
|
108
122
|
|
|
109
123
|
Session and turn metadata are available on `ctx.session`. For example,
|
|
@@ -113,14 +127,16 @@ Session and turn metadata are available on `ctx.session`. For example,
|
|
|
113
127
|
model turn. `lifecycle.turn` runs **once per fresh delivery** — tool-loop
|
|
114
128
|
continuations and HITL resumes do not re-fire it.
|
|
115
129
|
|
|
116
|
-
Both keys may return `{ modelContext
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
130
|
+
Both keys may return `{ modelContext }`. `modelContext` contributions
|
|
131
|
+
are concatenated session-then-turn before the harness's next model
|
|
132
|
+
call, and are never written to durable history. Channels may also
|
|
133
|
+
contribute the same `modelContext` shape through `SendPayload`;
|
|
134
|
+
channel-provided messages appear before lifecycle hook messages.
|
|
135
|
+
|
|
136
|
+
Browser UIs can contribute one-turn page state through `useAshAgent()`
|
|
137
|
+
`prepareSend` and `clientContext`. That client context is merged before
|
|
138
|
+
runtime lifecycle hook context, so use it for page state and use runtime hooks
|
|
139
|
+
for server-side policy and durable context.
|
|
124
140
|
|
|
125
141
|
### Seed durable context
|
|
126
142
|
|
|
@@ -174,36 +190,6 @@ export default defineHook({
|
|
|
174
190
|
`modelContext` messages are appended in registry order and visible to
|
|
175
191
|
the next model call only — never persisted.
|
|
176
192
|
|
|
177
|
-
### Contribute dynamic skills
|
|
178
|
-
|
|
179
|
-
```ts
|
|
180
|
-
// agent/hooks/tenant-skills.ts
|
|
181
|
-
import { defineHook } from "experimental-ash/hooks";
|
|
182
|
-
|
|
183
|
-
export default defineHook({
|
|
184
|
-
lifecycle: {
|
|
185
|
-
async session(ctx) {
|
|
186
|
-
return {
|
|
187
|
-
skills: [
|
|
188
|
-
{
|
|
189
|
-
name: "tenant-policy",
|
|
190
|
-
description: "Apply tenant-specific policy before answering.",
|
|
191
|
-
markdown: "Read the policy reference before making a recommendation.",
|
|
192
|
-
files: {
|
|
193
|
-
"references/policy.md": "Policy body\n",
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
],
|
|
197
|
-
};
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Dynamic skills may be returned from `lifecycle.session` or
|
|
204
|
-
`lifecycle.turn`. They can update earlier dynamic skills with the same
|
|
205
|
-
name, but cannot replace authored skills discovered under `agent/skills/`.
|
|
206
|
-
|
|
207
193
|
### Once-per-session text
|
|
208
194
|
|
|
209
195
|
```ts
|
|
@@ -229,7 +215,7 @@ export default defineHook({
|
|
|
229
215
|
The session contribution lands in `modelContext` for the **first** model
|
|
230
216
|
call only. Subsequent turns proceed without it.
|
|
231
217
|
|
|
232
|
-
## Stream
|
|
218
|
+
## Stream Events
|
|
233
219
|
|
|
234
220
|
Side-effect-only handlers for accepted runtime events. Subscribe by
|
|
235
221
|
event type, or use `*` for every event:
|
|
@@ -255,12 +241,15 @@ export default defineHook({
|
|
|
255
241
|
});
|
|
256
242
|
```
|
|
257
243
|
|
|
258
|
-
|
|
244
|
+
### Execution order
|
|
245
|
+
|
|
246
|
+
When a stream event fires, three things happen in order:
|
|
247
|
+
|
|
248
|
+
1. **Emit** — the channel adapter handler runs, then the event is written to the durable stream.
|
|
249
|
+
2. **Hooks** — stream event hooks fire (typed handlers first, then `*` wildcard). Return values are ignored.
|
|
250
|
+
3. **Dynamic tool resolvers** — resolvers subscribed to the event type run and update the tool set.
|
|
259
251
|
|
|
260
|
-
|
|
261
|
-
written it to the durable stream.
|
|
262
|
-
- Return values are ignored.
|
|
263
|
-
- Typed event hooks run **before** `*` for the same event.
|
|
252
|
+
Hooks always run **after** the event is durably recorded — if a hook throws, the stream is consistent.
|
|
264
253
|
|
|
265
254
|
## Errors
|
|
266
255
|
|
|
@@ -298,7 +287,9 @@ when both are registered.
|
|
|
298
287
|
|
|
299
288
|
## What to read next
|
|
300
289
|
|
|
301
|
-
- [
|
|
290
|
+
- [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
291
|
+
- [Next.js](../frontend/nextjs.md)
|
|
292
|
+
- [Tools](./tools.mdx)
|
|
302
293
|
- [Context Control](./context-control.md)
|
|
303
294
|
- [Sessions And Streaming](./runs-and-streaming.md)
|
|
304
295
|
- [Session Context](./session-context.md)
|
|
@@ -52,7 +52,95 @@ These fields control what the AI SDK records inside OTel spans:
|
|
|
52
52
|
- `recordOutputs` -- record model outputs on spans (defaults to `true`). Set to `false` to disable
|
|
53
53
|
output recording.
|
|
54
54
|
- `functionId` -- override the function name on spans (defaults to the agent name)
|
|
55
|
-
- `metadata` --
|
|
55
|
+
- `metadata["step.started"]` -- a synchronous callback that returns key-value pairs for one
|
|
56
|
+
model-call attempt
|
|
57
|
+
|
|
58
|
+
## Metadata
|
|
59
|
+
|
|
60
|
+
Use `metadata["step.started"]` when the metadata depends on the current session, turn, step,
|
|
61
|
+
channel, or model input:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import type { SlackInstrumentationMetadata } from "experimental-ash/channels/slack";
|
|
65
|
+
|
|
66
|
+
// A Slack-backed channel authored at `agent/channels/support.ts` has kind
|
|
67
|
+
// `channel:support` (its filename).
|
|
68
|
+
declare module "experimental-ash/instrumentation" {
|
|
69
|
+
interface ChannelMetadataMap {
|
|
70
|
+
readonly "channel:support": SlackInstrumentationMetadata;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default defineInstrumentation({
|
|
75
|
+
metadata: {
|
|
76
|
+
"step.started"(input) {
|
|
77
|
+
if (input.channel.kind !== "channel:support") {
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
"slack.channel_id": input.channel.metadata.channelId ?? "",
|
|
83
|
+
"slack.user_id": input.channel.metadata.triggeringUserId ?? "",
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The callback runs after Ash has assembled the model input for the attempt and before constructing
|
|
91
|
+
the AI SDK call. That timing lets the returned values attach to the AI SDK model-call span and its
|
|
92
|
+
child spans. It runs for each model-call attempt, including a retry of the same logical step when
|
|
93
|
+
Ash changes provider settings or instructions.
|
|
94
|
+
|
|
95
|
+
The callback receives:
|
|
96
|
+
|
|
97
|
+
- `session` -- the session id, current/initiator auth, and parent session lineage when this is a
|
|
98
|
+
child run
|
|
99
|
+
- `turn` -- the stream turn id and sequence, e.g. `turn_0`
|
|
100
|
+
- `step` -- the zero-based step index inside the turn
|
|
101
|
+
- `channel` -- the channel's `kind` and the metadata projected by the active channel
|
|
102
|
+
- `modelInput` -- the final instructions and messages passed to the model call
|
|
103
|
+
|
|
104
|
+
A channel exposes its identity through `kind`: the discriminant you narrow on. For authored
|
|
105
|
+
channels it is `channel:<name>`, where `<name>` is the channel's filename under
|
|
106
|
+
`agent/channels/` — `agent/channels/support.ts` is `channel:support`. Framework channels use
|
|
107
|
+
`http`, `schedule`, or `subagent`. It is also emitted as the `ash.channel.kind` span attribute.
|
|
108
|
+
|
|
109
|
+
Channel metadata is channel-owned. Built-in channels expose only the fields they choose to make
|
|
110
|
+
observable; for example, Slack projects `channelId`, `teamId`, `threadTs`, and `triggeringUserId`
|
|
111
|
+
from its durable channel state. User-authored channels expose their own projection by returning
|
|
112
|
+
`metadata(state)` from `defineChannel`. To make TypeScript narrow `input.channel.metadata`,
|
|
113
|
+
declaration-merge the same `channel:<name>` kind into `ChannelMetadataMap`:
|
|
114
|
+
|
|
115
|
+
`metadata(state)` must return an object composed of JSON primitives, arrays, and plain objects.
|
|
116
|
+
Ash omits `undefined` object properties and drops projections containing values such as `Date` or
|
|
117
|
+
`Map` with a warning.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { defineChannel } from "experimental-ash/channels";
|
|
121
|
+
|
|
122
|
+
declare module "experimental-ash/instrumentation" {
|
|
123
|
+
interface ChannelMetadataMap {
|
|
124
|
+
readonly "channel:support": {
|
|
125
|
+
readonly triggeringUserId: string | null;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export default defineChannel({
|
|
131
|
+
state: { triggeringUserId: null as string | null },
|
|
132
|
+
metadata(state) {
|
|
133
|
+
return { triggeringUserId: state.triggeringUserId };
|
|
134
|
+
},
|
|
135
|
+
routes: [],
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Metadata failures are non-destructive. If the callback throws, returns a non-record, or returns
|
|
140
|
+
non-string values, Ash logs a warning, drops the invalid metadata, and continues the model call.
|
|
141
|
+
Thenables are rejected; the callback is intentionally synchronous. Keys beginning with `ash.` are
|
|
142
|
+
reserved, so authored metadata cannot override framework metadata. Instrumentation projections
|
|
143
|
+
containing values outside the JSON shape, such as `Date` or `Map`, are dropped with a warning.
|
|
56
144
|
|
|
57
145
|
## Trace Hierarchy
|
|
58
146
|
|
|
@@ -70,8 +158,9 @@ ash.turn {ash.session.id, ash.turn.id}
|
|
|
70
158
|
```
|
|
71
159
|
|
|
72
160
|
Ash creates the `ash.turn` parent span per turn and passes enriched telemetry to the AI SDK so model
|
|
73
|
-
calls and tool executions are traced automatically. Session
|
|
74
|
-
`ash.
|
|
161
|
+
calls and tool executions are traced automatically. Session, turn, step, and channel context
|
|
162
|
+
(`ash.version`, `ash.session.id`, `ash.environment`, `ash.turn.id`, `ash.turn.sequence`,
|
|
163
|
+
`ash.step.index`, `ash.channel.kind`) is injected into span metadata.
|
|
75
164
|
|
|
76
165
|
## What To Read Next
|
|
77
166
|
|
|
@@ -39,7 +39,7 @@ my-agent/
|
|
|
39
39
|
| `instrumentation.ts` | Telemetry config | OTel exporter setup and AI SDK span settings; auto-discovered and run before agent code |
|
|
40
40
|
| `channels/` | HTTP or messaging entrypoints | Root-only today |
|
|
41
41
|
| `connections/` | External service connections (MCP) | Each file defines one connection; name derived from filename |
|
|
42
|
-
| `hooks/` | Lifecycle and stream-event subscribers | Module-backed only. Recursive directories supported. See [Hooks](./hooks.
|
|
42
|
+
| `hooks/` | Lifecycle and stream-event subscribers | Module-backed only. Recursive directories supported. See [Hooks](./hooks.mdx). |
|
|
43
43
|
| `skills/` | On-demand procedures and capability packs | Flat markdown, module-backed skills, or packaged skills |
|
|
44
44
|
| `lib/` | Shared authored helper code | Import-only source, not mounted into the workspace |
|
|
45
45
|
| `sandbox/` or `sandbox.ts` | The agent's single sandbox. Use top-level `sandbox.ts` for a definition-only override; use `sandbox/sandbox.ts` + optional `sandbox/workspace/**` when you also want seeded files. Framework default applies when neither is authored. | Supported on the root agent and local subagents |
|
|
@@ -156,15 +156,15 @@ Use:
|
|
|
156
156
|
- `channels/` for HTTP or messaging ingress and delivery
|
|
157
157
|
- `lib/` for shared helper modules imported by the slots above
|
|
158
158
|
|
|
159
|
-
See [Connections](./connections.
|
|
159
|
+
See [Connections](./connections.mdx) for the connection authorization shape, including the
|
|
160
160
|
`@vercel/connect/ash` helper for OAuth-backed connections.
|
|
161
161
|
|
|
162
162
|
## What To Read Next
|
|
163
163
|
|
|
164
164
|
- [`agent.ts`](./agent-ts.md)
|
|
165
165
|
- [Context Control](./context-control.md)
|
|
166
|
-
- [Connections](./connections.
|
|
167
|
-
- [Hooks](./hooks.
|
|
166
|
+
- [Connections](./connections.mdx)
|
|
167
|
+
- [Hooks](./hooks.mdx)
|
|
168
168
|
- [Skills](./skills.md)
|
|
169
|
-
- [Tools](./tools.
|
|
169
|
+
- [Tools](./tools.mdx)
|
|
170
170
|
- [Channels](./channels/README.md)
|
|
@@ -13,6 +13,10 @@ The key client model is:
|
|
|
13
13
|
- `POST /ash/v1/session/:sessionId` sends a follow-up message
|
|
14
14
|
- `GET /ash/v1/session/:sessionId/stream` lets you watch the session in real time
|
|
15
15
|
|
|
16
|
+
React apps can use [`useAshAgent()`](../frontend/use-ash-agent.md) instead of calling these
|
|
17
|
+
routes directly. Next.js apps can use [`withAsh()`](../frontend/nextjs.md) to proxy these
|
|
18
|
+
routes to the Ash runtime from the same origin.
|
|
19
|
+
|
|
16
20
|
Ash keeps those separate on purpose:
|
|
17
21
|
|
|
18
22
|
- channels own `continuationToken` as the resume handle
|
|
@@ -109,6 +113,8 @@ Important behavior:
|
|
|
109
113
|
|
|
110
114
|
## What To Read Next
|
|
111
115
|
|
|
116
|
+
- [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
117
|
+
- [Next.js](../frontend/nextjs.md)
|
|
112
118
|
- [Session Context](./session-context.md)
|
|
113
|
-
- [Subagents](./subagents.
|
|
114
|
-
- [Schedules](./schedules.
|
|
119
|
+
- [Subagents](./subagents.mdx)
|
|
120
|
+
- [Schedules](./schedules.mdx)
|
|
@@ -14,6 +14,9 @@ Source of truth:
|
|
|
14
14
|
- tools subpath: [`../../packages/ash/src/public/tools/index.ts`](../../packages/ash/src/public/tools/index.ts)
|
|
15
15
|
- sandbox subpath: [`../../packages/ash/src/public/sandbox/index.ts`](../../packages/ash/src/public/sandbox/index.ts)
|
|
16
16
|
- channel subpaths: [`../../packages/ash/src/public/channels/index.ts`](../../packages/ash/src/public/channels/index.ts)
|
|
17
|
+
- Next.js subpath: [`../../packages/ash/src/public/next/index.ts`](../../packages/ash/src/public/next/index.ts)
|
|
18
|
+
- React subpath: [`../../packages/ash/src/react/index.ts`](../../packages/ash/src/react/index.ts)
|
|
19
|
+
- client subpath: [`../../packages/ash/src/client/index.ts`](../../packages/ash/src/client/index.ts)
|
|
17
20
|
- evals subpath: [`../../packages/ash/src/evals/index.ts`](../../packages/ash/src/evals/index.ts)
|
|
18
21
|
|
|
19
22
|
## Definition Helpers
|
|
@@ -69,6 +72,26 @@ Related exported types by subpath:
|
|
|
69
72
|
Ash also exports lower-level runtime primitives such as `createToolLoopHarness(...)`
|
|
70
73
|
and `createWorkflowRuntime(...)`.
|
|
71
74
|
|
|
75
|
+
Next.js helpers exported from `experimental-ash/next`:
|
|
76
|
+
|
|
77
|
+
- `withAsh(config, options?)` - wraps a Next.js config so same-origin Ash protocol routes proxy to an Ash service
|
|
78
|
+
- `ASH_NEXT_SERVICE_PREFIX` - default private Vercel service prefix for the Ash service
|
|
79
|
+
- `WithAshOptions` - options for `ashRoot`, `ashBuildCommand`, `configureVercelJson`, and `servicePrefix`
|
|
80
|
+
|
|
81
|
+
React helpers exported from `experimental-ash/react`:
|
|
82
|
+
|
|
83
|
+
- `useAshAgent(options?)` - React hook for sending turns, streaming events, projecting UI state, and tracking a session cursor
|
|
84
|
+
- `defaultMessageReducer()` - default chat-style event projection used by `useAshAgent()`
|
|
85
|
+
- `UseAshAgentOptions`, `UseAshAgentHelpers`, `UseAshAgentSnapshot`, `UseAshAgentStatus` - hook configuration and state types
|
|
86
|
+
- `AshMessageData`, `AshMessage`, `AshMessagePart`, `AshDynamicToolPart` - default message projection types
|
|
87
|
+
|
|
88
|
+
Client helpers exported from `experimental-ash/client`:
|
|
89
|
+
|
|
90
|
+
- `Client` - HTTP client for an Ash server
|
|
91
|
+
- `ClientSession` - one durable session cursor with `send(...)`, `sendMessage(...)`, and stream helpers
|
|
92
|
+
- `defaultMessageReducer()` - reducer shared with the React package
|
|
93
|
+
- `SessionState`, `SendTurnInput`, `SendMessageOptions`, `ClientOptions` - client request and session types
|
|
94
|
+
|
|
72
95
|
Channel and Slack types exported from `experimental-ash/channels/slack`:
|
|
73
96
|
|
|
74
97
|
- `slackChannel` - Slack channel factory; zero-config by default, accepts a `SlackChannelConfig`
|
|
@@ -231,7 +254,7 @@ import {
|
|
|
231
254
|
} from "experimental-ash/tools/defaults";
|
|
232
255
|
```
|
|
233
256
|
|
|
234
|
-
See [Tools](./tools.
|
|
257
|
+
See [Tools](./tools.mdx) for the full override patterns.
|
|
235
258
|
|
|
236
259
|
### Runtime Mode
|
|
237
260
|
|
|
@@ -239,6 +262,24 @@ See [Tools](./tools.md) for the full override patterns.
|
|
|
239
262
|
import type { RunMode } from "experimental-ash";
|
|
240
263
|
```
|
|
241
264
|
|
|
265
|
+
### Next.js Integration
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
import { withAsh } from "experimental-ash/next";
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### React Client
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
import { useAshAgent } from "experimental-ash/react";
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### HTTP Client
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
import { Client } from "experimental-ash/client";
|
|
281
|
+
```
|
|
282
|
+
|
|
242
283
|
### Eval Suite
|
|
243
284
|
|
|
244
285
|
```ts
|
|
@@ -252,14 +293,16 @@ import { Braintrust } from "experimental-ash/evals/reporters";
|
|
|
252
293
|
|
|
253
294
|
- `defineAgent` -> [`agent.ts`](./agent-ts.md)
|
|
254
295
|
- `defineChannel` and channel factories -> [Channels](./channels/README.md)
|
|
255
|
-
- `defineTool`, `disableTool`, `defineBashTool`, `defineReadFileTool`, `defineWriteFileTool`, and `experimental-ash/tools/defaults` -> [Tools](./tools.
|
|
256
|
-
- `defineHook`, `HookContext`, and lifecycle/event types -> [Hooks](./hooks.
|
|
296
|
+
- `defineTool`, `disableTool`, `defineBashTool`, `defineReadFileTool`, `defineWriteFileTool`, and `experimental-ash/tools/defaults` -> [Tools](./tools.mdx)
|
|
297
|
+
- `defineHook`, `HookContext`, and lifecycle/event types -> [Hooks](./hooks.mdx)
|
|
257
298
|
- `defineSandbox` and `ctx.getSandbox()` -> [Sandboxes](./sandbox.md)
|
|
258
299
|
- `defineSkill` and `ctx.getSkill()` -> [Skills](./skills.md)
|
|
259
300
|
- `ctx.session` -> [Session Context](./session-context.md)
|
|
260
|
-
-
|
|
261
|
-
- `
|
|
262
|
-
-
|
|
301
|
+
- `withAsh` -> [Next.js](../frontend/nextjs.md)
|
|
302
|
+
- `useAshAgent` -> [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
303
|
+
- subagents (authored with `defineAgent` under `subagents/<id>/agent.ts`) -> [Subagents](./subagents.mdx)
|
|
304
|
+
- `defineSchedule` -> [Schedules](./schedules.mdx)
|
|
305
|
+
- `defineEvalSuite`, loaders, reporters, and scorers -> [Evals](./evals.mdx)
|
|
263
306
|
|
|
264
307
|
## Practical Advice
|
|
265
308
|
|
|
@@ -106,4 +106,4 @@ This is useful for smoke tests against preview or production environments.
|
|
|
106
106
|
|
|
107
107
|
- [Workspace](./workspace.md)
|
|
108
108
|
- [Sandboxes](./sandbox.md)
|
|
109
|
-
- [Auth And Route Protection](./auth-and-route-protection.
|
|
109
|
+
- [Auth And Route Protection](./auth-and-route-protection.mdx)
|