experimental-ash 0.7.3 → 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 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
@@ -6,7 +6,7 @@ import { ASH_PACKAGE_NAME } from "#package-name.js";
6
6
  let cachedPackageInfo;
7
7
  // The package build stamps the published version into `dist` so bundled
8
8
  // deployments can still report package metadata without resolving package.json.
9
- const BUNDLED_FALLBACK_PACKAGE_VERSION = "0.7.3";
9
+ const BUNDLED_FALLBACK_PACKAGE_VERSION = "0.7.4";
10
10
  const BUNDLED_FALLBACK_PACKAGE_VERSION_PLACEHOLDER = "__ASH_PACKAGE_VERSION_PLACEHOLDER__";
11
11
  const WORKFLOW_MODULE_ALIASES = {
12
12
  "workflow/api": "src/compiled/@workflow/core/runtime.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "experimental-ash",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "bin": {
5
5
  "ash": "./bin/ash.js",
6
6
  "experimental-ash": "./bin/ash.js"
@@ -8,6 +8,7 @@
8
8
  "files": [
9
9
  "bin",
10
10
  "dist",
11
+ "CHANGELOG.md",
11
12
  "README.md"
12
13
  ],
13
14
  "type": "module",