experimental-ash 0.7.2 → 0.7.4
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 +205 -0
- package/dist/docs/internals/README.md +8 -8
- package/dist/docs/internals/context.md +1 -1
- package/dist/docs/internals/hooks.md +5 -5
- package/dist/docs/internals/message-runtime.md +2 -2
- package/dist/docs/public/README.md +22 -22
- package/dist/docs/public/agent-ts.md +21 -17
- package/dist/docs/public/auth-and-route-protection.md +3 -3
- package/dist/docs/public/channels/README.md +8 -8
- package/dist/docs/public/cli-build-and-debugging.md +3 -3
- package/dist/docs/public/connections.md +5 -5
- package/dist/docs/public/context-control.md +8 -8
- package/dist/docs/public/evals.md +3 -3
- package/dist/docs/public/getting-started.md +5 -5
- package/dist/docs/public/hooks.md +4 -4
- package/dist/docs/public/human-in-the-loop.md +3 -3
- package/dist/docs/public/instrumentation.md +4 -3
- package/dist/docs/public/project-layout.md +11 -11
- package/dist/docs/public/runs-and-streaming.md +3 -3
- package/dist/docs/public/sandbox.md +3 -3
- package/dist/docs/public/session-context.md +10 -6
- package/dist/docs/public/skills.md +5 -3
- package/dist/docs/public/subagents.md +2 -2
- package/dist/docs/public/tools.md +4 -5
- package/dist/docs/public/typescript-api.md +11 -11
- package/dist/docs/public/vercel-deployment.md +4 -4
- package/dist/docs/public/workspace.md +3 -3
- package/dist/src/channel/compiled-channel.d.ts +4 -2
- package/dist/src/channel/schedule.d.ts +11 -23
- package/dist/src/channel/schedule.js +18 -19
- package/dist/src/chunks/{dev-authored-source-watcher-D3ybKVO9.js → dev-authored-source-watcher-Druw92QN.js} +1 -1
- package/dist/src/chunks/{host-Ck0qkepf.js → host-CQ7AZID3.js} +2 -2
- package/dist/src/chunks/paths-DQbfjCIS.js +88 -0
- package/dist/src/chunks/{prewarm-DJtOdukm.js → prewarm-CcphIXc0.js} +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/run.js +1 -1
- package/dist/src/compiler/normalize-channel.d.ts +4 -4
- package/dist/src/compiler/normalize-channel.js +9 -22
- package/dist/src/evals/cli/eval.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/channel.d.ts +7 -9
- package/dist/src/internal/authored-definition/channel.js +9 -33
- package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +5 -3
- package/dist/src/internal/nitro/routes/channel-dispatch.js +8 -5
- package/dist/src/internal/nitro/routes/runtime-stack.js +1 -1
- package/dist/src/internal/nitro/routes/schedule-task.d.ts +3 -4
- package/dist/src/internal/nitro/routes/schedule-task.js +5 -7
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/definitions/channel.d.ts +1 -63
- package/dist/src/public/definitions/channel.js +0 -16
- package/dist/src/public/definitions/defineChannel.d.ts +7 -4
- package/dist/src/runtime/resolve-channel.d.ts +9 -4
- package/dist/src/runtime/resolve-channel.js +21 -28
- package/dist/src/runtime/types.d.ts +13 -8
- package/package.json +2 -1
- package/dist/src/chunks/paths-BFX2EgQO.js +0 -88
- package/dist/src/compiler/channel-url.d.ts +0 -5
- package/dist/src/compiler/channel-url.js +0 -14
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# experimental-ash
|
|
2
|
+
|
|
3
|
+
## 0.7.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ada9d2f: chore(pkg): ship `CHANGELOG.md` in the published tarball
|
|
8
|
+
|
|
9
|
+
Adds `CHANGELOG.md` to the `files` allowlist in `packages/ash/package.json`
|
|
10
|
+
and references it from the package README. Agents installing
|
|
11
|
+
`experimental-ash` can now read `node_modules/experimental-ash/CHANGELOG.md`
|
|
12
|
+
directly to evaluate the value of upgrading without leaving the project.
|
|
13
|
+
|
|
14
|
+
## 0.7.3
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 974071d: fix(slack,schedule): repair `ScheduleDispatcher` ↔ `slackChannel.receive` contract; honor `input.auth`
|
|
19
|
+
|
|
20
|
+
Every schedule targeting a Slack channel threw `TypeError: send is not
|
|
21
|
+
a function` at cron fire. `ScheduleDispatcher.trigger` called
|
|
22
|
+
`route.receive(input, { agent, waitUntil })`, but `slackChannel.receive`
|
|
23
|
+
was designed (per #474) to receive `{ send }`. The dispatcher was the
|
|
24
|
+
broken half — it never built a `send` via `createSendFn` and never
|
|
25
|
+
honored the contract `defineChannel` documents. `slackChannel.receive`
|
|
26
|
+
also hardcoded `auth: null` and ignored `ReceiveInput.auth`, so
|
|
27
|
+
schedules could not propagate `APP_AUTH` and no cross-channel
|
|
28
|
+
programmatic initiator could thread its principal through.
|
|
29
|
+
|
|
30
|
+
The fix lands the schedule dispatcher cleanly on the `receive` / `send`
|
|
31
|
+
/ `Session` vocabulary from #474: build `send` via `createSendFn`,
|
|
32
|
+
call `receive(input, { send })`, return the `Session`. Same
|
|
33
|
+
fire-and-forget discipline HTTP routes already use — the workflow
|
|
34
|
+
runtime owns terminal completion and its own failure observability,
|
|
35
|
+
so `dispatchScheduleTask` no longer awaits `handle.result` and drops
|
|
36
|
+
the logged-only `status` field from its return value.
|
|
37
|
+
`slackChannel.receive` propagates `input.auth` into `send(...)`, and
|
|
38
|
+
`ChannelConfig.receive` / `Channel.receive` / `CompiledChannel.receive`
|
|
39
|
+
gain `auth: SessionAuthContext | null` on the input shape so receive
|
|
40
|
+
implementers can read the caller's principal.
|
|
41
|
+
|
|
42
|
+
Type-system hardening so this kind of drift can't recur:
|
|
43
|
+
`ResolvedChannelDefinition.receive` was typed
|
|
44
|
+
`(...args: any[]) => Promise<any>` with an eslint-disable — the
|
|
45
|
+
escape hatch that let the dispatcher pass a wrong-shape ctx without a
|
|
46
|
+
typecheck error. Now typed precisely as `CompiledChannel["receive"]`.
|
|
47
|
+
The matching `as` casts in `resolve-channel.ts` and the `as` cast the
|
|
48
|
+
dispatcher used go away. The legacy authored `Route` shape
|
|
49
|
+
(`{ fetch, receive? }`) and every fallback that hedged between it and
|
|
50
|
+
`CompiledChannel` are deleted — dead in practice (everything authored
|
|
51
|
+
goes through `defineChannel`), and the union was the only reason the
|
|
52
|
+
`any[]` typing existed. Reintroducing the original bug shape
|
|
53
|
+
(destructuring `{ agent, waitUntil }`) now fails typecheck with
|
|
54
|
+
`Property 'agent' does not exist on type '{ send: SendFn<…> }'`
|
|
55
|
+
instead of crashing at cron fire.
|
|
56
|
+
|
|
57
|
+
## 0.7.2
|
|
58
|
+
|
|
59
|
+
### Patch Changes
|
|
60
|
+
|
|
61
|
+
- b01d908: refactor(channels): rename the canonical session channel from `http` to `ash`
|
|
62
|
+
|
|
63
|
+
The framework's built-in session channel — the routes documented in
|
|
64
|
+
`docs/external-agent-protocol.md` (`POST /ash/v1/session`, `POST
|
|
65
|
+
/ash/v1/session/:sessionId`, `GET /ash/v1/session/:sessionId/stream`) — is
|
|
66
|
+
now consistently named `"ash"` across every layer instead of being split
|
|
67
|
+
between `"http"` (in the function name) and `"default"` (in the override
|
|
68
|
+
file convention).
|
|
69
|
+
|
|
70
|
+
Breaking changes — agents that override the framework default must update:
|
|
71
|
+
|
|
72
|
+
- Import path `experimental-ash/channels/http` → `experimental-ash/channels/ash`.
|
|
73
|
+
- Function `httpChannel(...)` → `ashChannel(...)`.
|
|
74
|
+
- Type `HttpRouteInput` → `AshChannelInput`.
|
|
75
|
+
- Override file `agent/channels/default.ts` → `agent/channels/ash.ts`.
|
|
76
|
+
- Framework channel name `"default"` → `"ash"` (relevant if a project
|
|
77
|
+
uses `disableRoute()` to disable the framework default; the file must
|
|
78
|
+
now be named `ash.ts`).
|
|
79
|
+
- Auto-generated continuation tokens minted by the framework switch
|
|
80
|
+
from the `http:` prefix to `ash:`. The values stay opaque to clients;
|
|
81
|
+
the change is only visible in logs.
|
|
82
|
+
|
|
83
|
+
Why: "HTTP" said nothing useful (every channel is HTTP — Slack webhooks,
|
|
84
|
+
custom `defineChannel` routes, etc.), and "default" said nothing about
|
|
85
|
+
what the file actually was. The new name mirrors the URL prefix
|
|
86
|
+
(`/ash/v1/...`), the stream headers (`x-ash-session-id`,
|
|
87
|
+
`x-ash-stream-format`), and the package name itself, so the file convention
|
|
88
|
+
(`agent/channels/ash.ts`), the function (`ashChannel`), the import path
|
|
89
|
+
(`experimental-ash/channels/ash`), and the framework channel name (`"ash"`)
|
|
90
|
+
all say the same thing.
|
|
91
|
+
|
|
92
|
+
Migration for an existing app:
|
|
93
|
+
|
|
94
|
+
```diff
|
|
95
|
+
- // agent/channels/default.ts
|
|
96
|
+
- import { httpChannel } from "experimental-ash/channels/http";
|
|
97
|
+
+ // agent/channels/ash.ts
|
|
98
|
+
+ import { ashChannel } from "experimental-ash/channels/ash";
|
|
99
|
+
import { vercelOidc } from "experimental-ash/channels/auth";
|
|
100
|
+
|
|
101
|
+
- export default httpChannel({ auth: vercelOidc() });
|
|
102
|
+
+ export default ashChannel({ auth: vercelOidc() });
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## 0.7.1
|
|
106
|
+
|
|
107
|
+
### Patch Changes
|
|
108
|
+
|
|
109
|
+
- 3e4bc51: feat(slack): restore attachment ingest + fix HITL round-trip + defineChannel `attachments` field
|
|
110
|
+
|
|
111
|
+
Two regressions introduced by the 0.6 channel redesign (#474) that
|
|
112
|
+
deleted `createSlackBaseAdapter`, plus a focused public extension
|
|
113
|
+
point on `defineChannel` for channel-owned attachment resolution.
|
|
114
|
+
|
|
115
|
+
**Attachment ingest**
|
|
116
|
+
|
|
117
|
+
`slackChannel` now folds Slack file uploads into the user turn as AI
|
|
118
|
+
SDK `FilePart`s carrying opaque `ash-attachment:` refs, and declares
|
|
119
|
+
the matching `AttachmentResolver` via the new top-level `attachments`
|
|
120
|
+
config field on `defineChannel`. The framework's existing staging
|
|
121
|
+
pipeline resolves the refs with the bot token, writes the bytes to
|
|
122
|
+
`/workspace/attachments/<sha>/<name>` in the sandbox, and hands the
|
|
123
|
+
model either inline bytes (small images and PDFs) or a sandbox path
|
|
124
|
+
the agent's filesystem tools can open. Audio and video attachments
|
|
125
|
+
are skipped; oversized or disallowed-media attachments are dropped
|
|
126
|
+
with a warning so a single bad upload never blocks the text portion
|
|
127
|
+
of a mention. The new `SlackChannelConfig.uploadPolicy` mirrors
|
|
128
|
+
`httpChannel`'s policy shape; the default cap is 25 MB.
|
|
129
|
+
|
|
130
|
+
**HITL widget round-trip**
|
|
131
|
+
|
|
132
|
+
The default `input.requested` handler used to encode `action_id` as
|
|
133
|
+
`ash_input_<requestId>_<optionId>` and decode it by splitting on `_`.
|
|
134
|
+
Since `requestId` is the AI SDK `action.callId` and always contains
|
|
135
|
+
underscores (`call_…`, `toolu_…`), the decoder silently dropped every
|
|
136
|
+
HITL click. It also only rendered buttons and only read
|
|
137
|
+
`action.value`, so radio-button and static-select widgets could
|
|
138
|
+
neither be rendered by the default handler nor parsed by the channel
|
|
139
|
+
route.
|
|
140
|
+
|
|
141
|
+
Fixed by:
|
|
142
|
+
|
|
143
|
+
- Encoding `action_id` as `ash_input:<requestId>`. The colon
|
|
144
|
+
delimiter is not valid inside an AI SDK call id, so the decode is
|
|
145
|
+
unambiguous for any `requestId` shape.
|
|
146
|
+
- Rendering radio_buttons for select-display requests with ≤6 options
|
|
147
|
+
and a static_select dropdown above that, matching pre-redesign
|
|
148
|
+
behavior.
|
|
149
|
+
- Extracting `selected_option.value` for radio / static_select clicks
|
|
150
|
+
on the route handler.
|
|
151
|
+
- Exposing the parsed selection on
|
|
152
|
+
`SlackInteractionAction.selectedOptionValue` so end-user
|
|
153
|
+
`onInteraction` handlers that render custom radio / select widgets
|
|
154
|
+
can read it too.
|
|
155
|
+
|
|
156
|
+
**`defineChannel.attachments`**
|
|
157
|
+
|
|
158
|
+
`ChannelConfig` gains an optional top-level `attachments?:
|
|
159
|
+
AttachmentResolver` field, mirroring how `state`, `routes`, and
|
|
160
|
+
`events` are declared:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
defineChannel({
|
|
164
|
+
state: {
|
|
165
|
+
/* … */
|
|
166
|
+
},
|
|
167
|
+
routes: [
|
|
168
|
+
/* … */
|
|
169
|
+
],
|
|
170
|
+
events: {
|
|
171
|
+
/* … */
|
|
172
|
+
},
|
|
173
|
+
attachments: myResolver,
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
`AttachmentResolver` is now exported from `experimental-ash/channels`
|
|
178
|
+
so callers can type their resolver implementations cleanly. The Slack
|
|
179
|
+
channel is the first consumer; any future custom channel (Discord,
|
|
180
|
+
Teams, …) that needs an attachment resolver uses the same field.
|
|
181
|
+
|
|
182
|
+
## 0.7.0
|
|
183
|
+
|
|
184
|
+
### Minor Changes
|
|
185
|
+
|
|
186
|
+
- 6bf383a: chore(ash): rename `system` file to `instructions` file
|
|
187
|
+
|
|
188
|
+
## 0.6.2
|
|
189
|
+
|
|
190
|
+
### Patch Changes
|
|
191
|
+
|
|
192
|
+
- 4f875e3: Expose `messageTs` on `SlackInteractionAction` so `onInteraction` handlers can `chat.update` the clicked message in place. `ctx.slack.threadTs` resolves to the thread root when the component lives inside a thread reply, so updates targeting the clicked message previously had no way to learn its `ts`.
|
|
193
|
+
- 224743e: chore: abstract sandbox types to be shared, and reuse AI SDK `Sandbox` abstraction definition where reasonable
|
|
194
|
+
|
|
195
|
+
## 0.6.1
|
|
196
|
+
|
|
197
|
+
### Patch Changes
|
|
198
|
+
|
|
199
|
+
- ff9425d: Export `Channel` from `experimental-ash/channels` and `SlackChannelState` from `experimental-ash/channels/slack` so app authors can use `slack()` / `slackChannel()` from a `channels/slack.ts` module without the TypeScript "inferred type cannot be named" error when `declaration` is enabled. The slack helpers also stop redefining a private `SlackChannelState` and now share the canonical one from `slackChannel.ts`.
|
|
200
|
+
|
|
201
|
+
## 0.6.0
|
|
202
|
+
|
|
203
|
+
### Minor Changes
|
|
204
|
+
|
|
205
|
+
- 90ce74f: Initial changeset release
|
|
@@ -24,11 +24,11 @@ If you want the shortest path through the architecture, read these in order:
|
|
|
24
24
|
|
|
25
25
|
## Guides
|
|
26
26
|
|
|
27
|
-
- [
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
31
|
-
- [
|
|
32
|
-
- [
|
|
33
|
-
- [
|
|
34
|
-
- [
|
|
27
|
+
- [Ash Architecture](../../ARCHITECTURE.md) — the repo-level architecture map
|
|
28
|
+
- [Core Beliefs](./core-beliefs.md) — the principles behind Ash's architecture rules
|
|
29
|
+
- [Mechanical Invariants](./mechanical-invariants.md) — detailed constraints that should become lints or structural tests
|
|
30
|
+
- [Unified Context](./context.md) — the unified context system
|
|
31
|
+
- [Compiler and Artifacts](./compiler-and-artifacts.md) — how authored files become `.ash/` artifacts
|
|
32
|
+
- [Discovery](./discovery.md) — how the framework finds authored sources
|
|
33
|
+
- [Message Runtime](./message-runtime.md) — the HTTP surface and runtime execution
|
|
34
|
+
- [Testing](./testing.md) — test tiers and helpers
|
|
@@ -79,7 +79,7 @@ Framework providers use a superset `FrameworkContextProvider` that also receives
|
|
|
79
79
|
|
|
80
80
|
Authored hook lifecycle dispatch (`lifecycle.session`, `lifecycle.turn`)
|
|
81
81
|
runs inside step (4)'s ALS scope, before the harness step. See
|
|
82
|
-
[
|
|
82
|
+
[Hooks](./hooks.md) for the full pipeline and the
|
|
83
83
|
`SessionPreparedKey` flag's failure semantics.
|
|
84
84
|
|
|
85
85
|
## Channel Context
|
|
@@ -7,7 +7,7 @@ hooks answer the runtime.
|
|
|
7
7
|
This page explains the discovery → compile → resolve → dispatch pipeline
|
|
8
8
|
and the runtime contract every authored hook handler relies on. The
|
|
9
9
|
end-user-facing reference lives at
|
|
10
|
-
[
|
|
10
|
+
[Hooks](../public/hooks.md).
|
|
11
11
|
|
|
12
12
|
## Architectural Rationale
|
|
13
13
|
|
|
@@ -196,7 +196,7 @@ documented expectations:
|
|
|
196
196
|
|
|
197
197
|
## Related Pages
|
|
198
198
|
|
|
199
|
-
- [
|
|
200
|
-
- [
|
|
201
|
-
- [
|
|
202
|
-
- [
|
|
199
|
+
- [Hooks](../public/hooks.md) — author-facing reference
|
|
200
|
+
- [Discovery](./discovery.md) — discovery layout and the unified slot walker
|
|
201
|
+
- [Unified Context](./context.md) — `AshContext` surface shared by hooks
|
|
202
|
+
- [Message Runtime](./message-runtime.md) — runtime stream events
|
|
@@ -48,7 +48,7 @@ step.completed → turn.completed → session.waiting / session.completed
|
|
|
48
48
|
Failure variants: `step.failed`, `turn.failed`, `session.failed`.
|
|
49
49
|
A thrown `lifecycle.session` hook produces a terminal `session.failed`;
|
|
50
50
|
a thrown `lifecycle.turn` hook produces a recoverable `turn.failed`
|
|
51
|
-
cascade. See [
|
|
51
|
+
cascade. See [Hooks](./hooks.md).
|
|
52
52
|
|
|
53
53
|
`message.appended` and `reasoning.appended` carry both delta and cumulative text. `step.completed.data.finishReason` mirrors the model-step outcome (`tool-calls` means the turn continues).
|
|
54
54
|
|
|
@@ -64,4 +64,4 @@ The runtime stores both `auth.current` and `auth.initiator`. Follow-up messages
|
|
|
64
64
|
|
|
65
65
|
The runtime owns stream plumbing; the channel owns delivery policy. The runtime calls `channel.onEvent(event)` for each lifecycle event — the channel may transform it or perform platform side effects. The harness emits events without knowing the transport.
|
|
66
66
|
|
|
67
|
-
Authored stream-event hooks fan out alongside `callAdapterEventHandler` from the same `HarnessEmitFn` composer (`workflow-steps.ts` and `continuous-runtime.ts`). Hook errors propagate through the emit composer and are caught by the existing harness error path, which emits the recoverable `turn.failed` cascade. See [
|
|
67
|
+
Authored stream-event hooks fan out alongside `callAdapterEventHandler` from the same `HarnessEmitFn` composer (`workflow-steps.ts` and `continuous-runtime.ts`). Hook errors propagate through the emit composer and are caught by the existing harness error path, which emits the recoverable `turn.failed` cascade. See [Hooks](./hooks.md).
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
This folder is for app authors using Ash as a framework.
|
|
4
4
|
|
|
5
5
|
If you want to understand how to build agents with Ash, start here. If you want to understand how
|
|
6
|
-
the framework is implemented internally, read [
|
|
6
|
+
the framework is implemented internally, read [Internals](../internals/README.md).
|
|
7
7
|
|
|
8
8
|
Important naming note:
|
|
9
9
|
|
|
@@ -15,26 +15,26 @@ Important naming note:
|
|
|
15
15
|
|
|
16
16
|
Read in this order:
|
|
17
17
|
|
|
18
|
-
1. [
|
|
19
|
-
2. [
|
|
20
|
-
3. [agent
|
|
21
|
-
4. [
|
|
22
|
-
5. [
|
|
23
|
-
6. [
|
|
24
|
-
7. [
|
|
25
|
-
8. [
|
|
26
|
-
9. [
|
|
27
|
-
10. [
|
|
28
|
-
11. [
|
|
29
|
-
12. [
|
|
30
|
-
13. [
|
|
31
|
-
14. [
|
|
32
|
-
15. [
|
|
33
|
-
16. [
|
|
34
|
-
17. [
|
|
35
|
-
18. [
|
|
36
|
-
19. [
|
|
37
|
-
20. [
|
|
18
|
+
1. [Getting Started](./getting-started.md)
|
|
19
|
+
2. [Project Layout](./project-layout.md)
|
|
20
|
+
3. [`agent.ts`](./agent-ts.md)
|
|
21
|
+
4. [TypeScript API](./typescript-api.md)
|
|
22
|
+
5. [Context Control](./context-control.md)
|
|
23
|
+
6. [Skills](./skills.md)
|
|
24
|
+
7. [Tools](./tools.md)
|
|
25
|
+
8. [Connections](./connections.md)
|
|
26
|
+
9. [Workspace](./workspace.md)
|
|
27
|
+
10. [Sandboxes](./sandbox.md)
|
|
28
|
+
11. [Channels](./channels/README.md)
|
|
29
|
+
12. [Human In The Loop](./human-in-the-loop.md)
|
|
30
|
+
13. [Session Context](./session-context.md)
|
|
31
|
+
14. [Sessions And Streaming](./runs-and-streaming.md)
|
|
32
|
+
15. [Subagents](./subagents.md)
|
|
33
|
+
16. [Schedules](./schedules.md)
|
|
34
|
+
17. [Evals](./evals.md)
|
|
35
|
+
18. [Auth And Route Protection](./auth-and-route-protection.md)
|
|
36
|
+
19. [Vercel Deployment](./vercel-deployment.md)
|
|
37
|
+
20. [CLI, Build, And Debugging](./cli-build-and-debugging.md)
|
|
38
38
|
|
|
39
39
|
## The Public Mental Model
|
|
40
40
|
|
|
@@ -88,4 +88,4 @@ That is why Ash exposes two identifiers:
|
|
|
88
88
|
|
|
89
89
|
- Minimal end-to-end example: [`../../apps/weather-agent`](../../apps/weather-agent)
|
|
90
90
|
- Public API source of truth: [`../../packages/ash/src/public/index.ts`](../../packages/ash/src/public/index.ts)
|
|
91
|
-
- Framework internals: [
|
|
91
|
+
- Framework internals: [Internals](../internals/README.md)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "agent.ts"
|
|
3
|
-
description: "Configure your agent with agent.ts: model,
|
|
3
|
+
description: "Configure your agent with agent.ts: model, metadata, and runtime options."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
`agent.ts` is the additive runtime config entrypoint for an Ash agent.
|
|
@@ -13,7 +13,6 @@ Put instructions in `instructions.md`. Put runtime settings in `agent.ts`.
|
|
|
13
13
|
import { defineAgent } from "experimental-ash";
|
|
14
14
|
|
|
15
15
|
export default defineAgent({
|
|
16
|
-
name: "support-agent",
|
|
17
16
|
model: "openai/gpt-5.4-mini",
|
|
18
17
|
metadata: {
|
|
19
18
|
team: "support",
|
|
@@ -33,7 +32,6 @@ export default defineAgent({
|
|
|
33
32
|
Use `agent.ts` for:
|
|
34
33
|
|
|
35
34
|
- model selection
|
|
36
|
-
- stable agent name
|
|
37
35
|
- metadata you want preserved in runtime traces
|
|
38
36
|
- human-in-the-loop policy
|
|
39
37
|
- hosted-build packaging controls
|
|
@@ -41,7 +39,7 @@ Use `agent.ts` for:
|
|
|
41
39
|
- provider-specific model options
|
|
42
40
|
|
|
43
41
|
For OpenTelemetry configuration, use `instrumentation.ts` instead. See
|
|
44
|
-
[`instrumentation.
|
|
42
|
+
[`instrumentation.ts`](./instrumentation.md).
|
|
45
43
|
|
|
46
44
|
Do not use `agent.ts` for long-form instructions. Put those in `instructions.md` (or `instructions.ts`) and
|
|
47
45
|
`skills/`.
|
|
@@ -94,14 +92,21 @@ export default defineAgent({
|
|
|
94
92
|
});
|
|
95
93
|
```
|
|
96
94
|
|
|
97
|
-
##
|
|
95
|
+
## Agent Identity
|
|
98
96
|
|
|
99
|
-
|
|
97
|
+
The agent's name is derived at compile time from the filesystem layout:
|
|
98
|
+
|
|
99
|
+
- A root agent (its `agent.ts` sits at the app root or directly under `agent/`) takes its name
|
|
100
|
+
from the enclosing `package.json`'s `name` field.
|
|
101
|
+
- A nested agent takes its name from its own directory (e.g. `subagents/researcher/agent.ts` →
|
|
102
|
+
`"researcher"`).
|
|
103
|
+
|
|
104
|
+
## `metadata`
|
|
100
105
|
|
|
101
106
|
`metadata` is a simple string map for app-owned labels that should travel with the resolved agent
|
|
102
107
|
definition and related runtime metadata.
|
|
103
108
|
|
|
104
|
-
Use
|
|
109
|
+
Use it for environment labels or ownership metadata. Avoid secrets here.
|
|
105
110
|
|
|
106
111
|
## `build`
|
|
107
112
|
|
|
@@ -123,7 +128,7 @@ server output instead of being bundled.
|
|
|
123
128
|
- `model` optionally overrides the model used for compaction summaries
|
|
124
129
|
|
|
125
130
|
The shared per-run workspace is configured on the sandbox, not on `agent.ts`. See
|
|
126
|
-
[
|
|
131
|
+
[Workspace](./workspace.md) and [Sandboxes](./sandbox.md).
|
|
127
132
|
|
|
128
133
|
## `humanInTheLoop`
|
|
129
134
|
|
|
@@ -147,13 +152,13 @@ Supported fields:
|
|
|
147
152
|
Use `require-approval` when the default should be "ask first". Use `auto-allow` when the default
|
|
148
153
|
should be "run immediately" and only a few named tools should still require approval.
|
|
149
154
|
|
|
150
|
-
See [
|
|
155
|
+
See [Human In The Loop](./human-in-the-loop.md) for the runtime flow, `input.requested`
|
|
151
156
|
events, and HTTP response payloads.
|
|
152
157
|
|
|
153
158
|
## Telemetry
|
|
154
159
|
|
|
155
160
|
OpenTelemetry tracing is configured in `agent/instrumentation.ts`, not in `agent.ts`. See
|
|
156
|
-
[`instrumentation.
|
|
161
|
+
[`instrumentation.ts`](./instrumentation.md) for setup.
|
|
157
162
|
|
|
158
163
|
## Route Auth And Network Policy
|
|
159
164
|
|
|
@@ -161,8 +166,8 @@ OpenTelemetry tracing is configured in `agent/instrumentation.ts`, not in `agent
|
|
|
161
166
|
|
|
162
167
|
Those concerns live on the HTTP channel layer instead. See:
|
|
163
168
|
|
|
164
|
-
- [
|
|
165
|
-
- [
|
|
169
|
+
- [Auth And Route Protection](./auth-and-route-protection.md)
|
|
170
|
+
- [Channels](./channels/README.md)
|
|
166
171
|
|
|
167
172
|
## A Good Default
|
|
168
173
|
|
|
@@ -172,7 +177,6 @@ For many apps, `agent.ts` stays small:
|
|
|
172
177
|
import { defineAgent } from "experimental-ash";
|
|
173
178
|
|
|
174
179
|
export default defineAgent({
|
|
175
|
-
name: "weather-agent",
|
|
176
180
|
model: "openai/gpt-5.4-mini",
|
|
177
181
|
});
|
|
178
182
|
```
|
|
@@ -181,7 +185,7 @@ That is enough to start. Add build and compaction settings only when you need th
|
|
|
181
185
|
|
|
182
186
|
## What To Read Next
|
|
183
187
|
|
|
184
|
-
- [
|
|
185
|
-
- [
|
|
186
|
-
- [
|
|
187
|
-
- [
|
|
188
|
+
- [Context Control](./context-control.md)
|
|
189
|
+
- [Human In The Loop](./human-in-the-loop.md)
|
|
190
|
+
- [Workspace](./workspace.md)
|
|
191
|
+
- [Auth And Route Protection](./auth-and-route-protection.md)
|
|
@@ -140,6 +140,6 @@ export default ashChannel({
|
|
|
140
140
|
|
|
141
141
|
## What To Read Next
|
|
142
142
|
|
|
143
|
-
- [`agent
|
|
144
|
-
- [
|
|
145
|
-
- [
|
|
143
|
+
- [`agent.ts`](./agent-ts.md)
|
|
144
|
+
- [Session Context](./session-context.md)
|
|
145
|
+
- [Vercel Deployment](./vercel-deployment.md)
|
|
@@ -93,7 +93,7 @@ The framework ships its canonical session protocol on `experimental-ash/channels
|
|
|
93
93
|
- `ashChannel({ auth })`
|
|
94
94
|
|
|
95
95
|
This is the channel the Ash dev client and any deployed-agent SDK talk to — it mounts the routes
|
|
96
|
-
under `/ash/v1/session*` documented in [
|
|
96
|
+
under `/ash/v1/session*` documented in [Ash External Agent Protocol](../../external-agent-protocol.md).
|
|
97
97
|
|
|
98
98
|
It requires an auth function. Use `experimental-ash/channels/auth` for the common helpers such as
|
|
99
99
|
`vercelOidc()`, `httpBasic()`, and `none()`.
|
|
@@ -208,7 +208,7 @@ Each compiles down to the one below it:
|
|
|
208
208
|
- `slackChannel(config)` -> `defineChannel` + Chat SDK setup + typed event dispatch
|
|
209
209
|
- `defineChannel` -> the primitive
|
|
210
210
|
|
|
211
|
-
For a Slack app backed by Vercel Connex, see [
|
|
211
|
+
For a Slack app backed by Vercel Connex, see [Slack channel setup](./slack.md) to create the Connex client
|
|
212
212
|
and channel file.
|
|
213
213
|
|
|
214
214
|
## File Uploads
|
|
@@ -251,9 +251,9 @@ at send time.
|
|
|
251
251
|
|
|
252
252
|
## What To Read Next
|
|
253
253
|
|
|
254
|
-
- [
|
|
255
|
-
- [
|
|
256
|
-
- [
|
|
257
|
-
- [
|
|
258
|
-
- [
|
|
259
|
-
- [
|
|
254
|
+
- [Slack channel setup](./slack.md)
|
|
255
|
+
- [Channel attachments](./attachments.md)
|
|
256
|
+
- [Project Layout](../project-layout.md)
|
|
257
|
+
- [TypeScript API](../typescript-api.md)
|
|
258
|
+
- [Auth And Route Protection](../auth-and-route-protection.md)
|
|
259
|
+
- [Ash External Agent Protocol](../../external-agent-protocol.md)
|
|
@@ -80,6 +80,6 @@ When something is wrong:
|
|
|
80
80
|
|
|
81
81
|
## What To Read Next
|
|
82
82
|
|
|
83
|
-
- [
|
|
84
|
-
- [
|
|
85
|
-
- [
|
|
83
|
+
- [Project Layout](./project-layout.md)
|
|
84
|
+
- [Sessions And Streaming](./runs-and-streaming.md)
|
|
85
|
+
- [TypeScript API](./typescript-api.md)
|
|
@@ -124,7 +124,7 @@ when it needs a different cache and principal model:
|
|
|
124
124
|
(status pages, shared dashboards, system bots).
|
|
125
125
|
|
|
126
126
|
Ash resolves the active principal before every authorization call. See
|
|
127
|
-
[
|
|
127
|
+
[Session Context](./session-context.md) for how the principal flows through the runtime.
|
|
128
128
|
|
|
129
129
|
## Headers
|
|
130
130
|
|
|
@@ -157,7 +157,7 @@ export default defineMcpClientConnection({
|
|
|
157
157
|
```
|
|
158
158
|
|
|
159
159
|
`never()` allows all calls, `once()` requires approval the first time per session, `always()`
|
|
160
|
-
requires approval every time. See [
|
|
160
|
+
requires approval every time. See [Human In The Loop](./human-in-the-loop.md) for the approval
|
|
161
161
|
runtime.
|
|
162
162
|
|
|
163
163
|
## Tool Filters
|
|
@@ -177,6 +177,6 @@ Tools that don't pass the filter are silently excluded from `connection_search`.
|
|
|
177
177
|
|
|
178
178
|
## What To Read Next
|
|
179
179
|
|
|
180
|
-
- [
|
|
181
|
-
- [
|
|
182
|
-
- [
|
|
180
|
+
- [Tools](./tools.md) — authored tools live alongside connection-provided tools.
|
|
181
|
+
- [Human In The Loop](./human-in-the-loop.md) — interactive consent and approval runtime.
|
|
182
|
+
- [Session Context](./session-context.md) — how the active principal flows through the runtime.
|
|
@@ -88,7 +88,7 @@ prompt.
|
|
|
88
88
|
- flat markdown skills may omit frontmatter
|
|
89
89
|
- tools stay visible whether or not a skill is activated
|
|
90
90
|
|
|
91
|
-
See [
|
|
91
|
+
See [Skills](./skills.md) for the full authoring model and install notes.
|
|
92
92
|
|
|
93
93
|
## 4. Put Runtime Files In The Workspace, Not The Prompt
|
|
94
94
|
|
|
@@ -102,7 +102,7 @@ Today that mainly means:
|
|
|
102
102
|
- skill files are available under the active runtime workspace root
|
|
103
103
|
- the model can inspect them with the shared `bash` tool
|
|
104
104
|
|
|
105
|
-
See [
|
|
105
|
+
See [Workspace](./workspace.md) and [Sandboxes](./sandbox.md).
|
|
106
106
|
|
|
107
107
|
## 5. Delegate To A Specialist With A Subagent
|
|
108
108
|
|
|
@@ -115,7 +115,7 @@ Subagents are a context-control tool too:
|
|
|
115
115
|
- they can have their own tools and their own sandbox
|
|
116
116
|
- they run inside their own delegated subagent context instead of extending the root agent inline
|
|
117
117
|
|
|
118
|
-
See [
|
|
118
|
+
See [Subagents](./subagents.md).
|
|
119
119
|
|
|
120
120
|
## Choosing The Right Lever
|
|
121
121
|
|
|
@@ -139,8 +139,8 @@ For most agents:
|
|
|
139
139
|
|
|
140
140
|
## What To Read Next
|
|
141
141
|
|
|
142
|
-
- [
|
|
143
|
-
- [
|
|
144
|
-
- [
|
|
145
|
-
- [
|
|
146
|
-
- [
|
|
142
|
+
- [Tools](./tools.md)
|
|
143
|
+
- [Hooks](./hooks.md)
|
|
144
|
+
- [Skills](./skills.md)
|
|
145
|
+
- [Workspace](./workspace.md)
|
|
146
|
+
- [Subagents](./subagents.md)
|
|
@@ -287,6 +287,6 @@ For most apps:
|
|
|
287
287
|
|
|
288
288
|
## What To Read Next
|
|
289
289
|
|
|
290
|
-
- [
|
|
291
|
-
- [
|
|
292
|
-
- [
|
|
290
|
+
- [TypeScript API](./typescript-api.md)
|
|
291
|
+
- [Tools](./tools.md)
|
|
292
|
+
- [Sessions And Streaming](./runs-and-streaming.md)
|
|
@@ -157,8 +157,8 @@ curl -X POST http://127.0.0.1:3000/ash/v1/session/<sessionId> \
|
|
|
157
157
|
|
|
158
158
|
## What To Read Next
|
|
159
159
|
|
|
160
|
-
- [
|
|
161
|
-
- [`agent
|
|
162
|
-
- [
|
|
163
|
-
- [
|
|
164
|
-
- [
|
|
160
|
+
- [Project Layout](./project-layout.md) for every supported authored slot
|
|
161
|
+
- [`agent.ts`](./agent-ts.md) for runtime config
|
|
162
|
+
- [Skills](./skills.md) for on-demand procedures
|
|
163
|
+
- [Tools](./tools.md) for typed integrations
|
|
164
|
+
- [Sessions And Streaming](./runs-and-streaming.md) for the durable session model
|
|
@@ -230,7 +230,7 @@ when both are registered.
|
|
|
230
230
|
|
|
231
231
|
## What to read next
|
|
232
232
|
|
|
233
|
-
- [
|
|
234
|
-
- [
|
|
235
|
-
- [
|
|
236
|
-
- [
|
|
233
|
+
- [Tools](./tools.md)
|
|
234
|
+
- [Context Control](./context-control.md)
|
|
235
|
+
- [Sessions And Streaming](./runs-and-streaming.md)
|
|
236
|
+
- [Session Context](./session-context.md)
|
|
@@ -249,6 +249,6 @@ If you press `Escape` and then send a normal message, the pending requests are i
|
|
|
249
249
|
|
|
250
250
|
## What To Read Next
|
|
251
251
|
|
|
252
|
-
- [`agent
|
|
253
|
-
- [
|
|
254
|
-
- [
|
|
252
|
+
- [`agent.ts`](./agent-ts.md)
|
|
253
|
+
- [Tools](./tools.md)
|
|
254
|
+
- [Sessions And Streaming](./runs-and-streaming.md)
|
|
@@ -36,7 +36,8 @@ telemetry -- there is no separate `isEnabled` toggle.
|
|
|
36
36
|
|
|
37
37
|
The `setup` callback is invoked by the framework at server startup with the resolved agent name. Use
|
|
38
38
|
it to register your OTel provider (e.g. `registerOTel` from `@vercel/otel`). The
|
|
39
|
-
`context.agentName`
|
|
39
|
+
`context.agentName` is derived from the agent's filesystem path at compile time, so you never need
|
|
40
|
+
to hard-code a service name.
|
|
40
41
|
|
|
41
42
|
Any OTel-compatible backend works (Braintrust, Honeycomb, Datadog, Jaeger). Install the exporter
|
|
42
43
|
package you need and configure it in the callback.
|
|
@@ -73,5 +74,5 @@ calls and tool executions are traced automatically. Session context (`ash.versio
|
|
|
73
74
|
|
|
74
75
|
## What To Read Next
|
|
75
76
|
|
|
76
|
-
- [`agent
|
|
77
|
-
- [
|
|
77
|
+
- [`agent.ts`](./agent-ts.md)
|
|
78
|
+
- [Project Layout](./project-layout.md)
|