experimental-ash 0.8.3 → 0.9.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/dist/docs/public/channels/slack.md +53 -25
  3. package/dist/src/compiled/.vendor-stamp.json +14 -14
  4. package/dist/src/compiled/@ai-sdk/anthropic/index.js +2 -2
  5. package/dist/src/compiled/@ai-sdk/google/index.js +4 -4
  6. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  7. package/dist/src/compiled/@ai-sdk/openai/index.js +6 -6
  8. package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
  9. package/dist/src/compiled/@ai-sdk/provider/_json-schema.d.ts +5 -0
  10. package/dist/src/compiled/@ai-sdk/provider/index.d.ts +6632 -1
  11. package/dist/src/compiled/@chat-adapter/slack/_chat-adapter-shared.d.ts +9 -0
  12. package/dist/src/compiled/@chat-adapter/slack/index.d.ts +632 -54
  13. package/dist/src/compiled/@chat-adapter/slack/index.js +25 -29
  14. package/dist/src/compiled/@chat-adapter/slack/package.json +1 -1
  15. package/dist/src/compiled/@chat-adapter/state-memory/index.d.ts +41 -25
  16. package/dist/src/compiled/@chat-adapter/state-memory/package.json +1 -1
  17. package/dist/src/compiled/@standard-schema/spec/index.d.ts +115 -62
  18. package/dist/src/compiled/@vercel/sandbox/index.d.ts +4 -1
  19. package/dist/src/compiled/@vercel/sandbox/index.js +5 -5
  20. package/dist/src/compiled/@workflow/core/index.js +1 -1
  21. package/dist/src/compiled/@workflow/core/runtime.d.ts +6 -2
  22. package/dist/src/compiled/@workflow/core/runtime.js +4 -4
  23. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  24. package/dist/src/compiled/@workflow/errors/_ms.d.ts +4 -0
  25. package/dist/src/compiled/@workflow/errors/error-codes.d.ts +17 -0
  26. package/dist/src/compiled/@workflow/errors/index.d.ts +438 -56
  27. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  28. package/dist/src/compiled/_chunks/node/{auth-CdwuOxMs.js → auth-vbe4XEEK.js} +2 -2
  29. package/dist/src/compiled/_chunks/node/{dist-B6IOtzm1.js → dist-BdWHjlRQ.js} +12 -12
  30. package/dist/src/compiled/_chunks/node/retry-BOcy5BbJ.js +1 -0
  31. package/dist/src/compiled/_chunks/workflow/{context-errors-CXifqq6a.js → context-errors-zbKocOyk.js} +1 -1
  32. package/dist/src/compiled/_chunks/workflow/{dist-BuELZxm6.js → dist-Ci2brnHh.js} +3 -3
  33. package/dist/src/compiled/_chunks/workflow/{resume-hook-CgfgCU87.js → resume-hook-CL8Ed91K.js} +2 -2
  34. package/dist/src/compiled/_chunks/workflow/sleep-Dn3i9nxI.js +1 -0
  35. package/dist/src/compiled/chat/_mdast.d.ts +24 -0
  36. package/dist/src/compiled/chat/_workflow-serde.d.ts +5 -0
  37. package/dist/src/compiled/chat/index.d.ts +3851 -72
  38. package/dist/src/compiled/chat/index.js +1 -1
  39. package/dist/src/compiled/chat/jsx-runtime-DxGwoLu2.d.ts +782 -0
  40. package/dist/src/compiled/chat/package.json +1 -1
  41. package/dist/src/compiled/just-bash/index.js +1 -1
  42. package/dist/src/execution/authorization-challenge-defaults.d.ts +1 -1
  43. package/dist/src/execution/authorization-challenge-defaults.js +1 -1
  44. package/dist/src/internal/application/package.js +1 -1
  45. package/dist/src/public/channels/slack/slack.js +4 -1
  46. package/dist/src/public/channels/slack/slackChannel.d.ts +47 -4
  47. package/dist/src/public/channels/slack/slackChannel.js +49 -12
  48. package/dist/src/runtime/connections/authorization-tokens.d.ts +1 -1
  49. package/dist/src/runtime/connections/authorization-tokens.js +1 -1
  50. package/package.json +16 -16
  51. package/dist/src/compiled/_chunks/node/ms-B2k_qBoq.js +0 -1
  52. package/dist/src/compiled/_chunks/workflow/sleep-BzS_cSYx.js +0 -1
  53. /package/dist/src/compiled/_chunks/workflow/{dist-C9DdsXoK.js → dist-0iNBqPYp.js} +0 -0
  54. /package/dist/src/compiled/_chunks/workflow/{dist-BHbmiLmM.js → dist-D774SUM4.js} +0 -0
  55. /package/dist/src/compiled/_chunks/workflow/{src-CidBwKAD.js → src-ClRYdO4-.js} +0 -0
  56. /package/dist/src/compiled/_chunks/workflow/{symbols-BC0BVTM7.js → symbols-D-4tVV8x.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,85 @@
1
1
  # experimental-ash
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6a3f538: feat(slack): async `run`, new `onMention` pre-dispatch hook, and `onInteraction` docs
8
+
9
+ The previous `slackChannel` shape had a single Nitro-side callback — `run(ctx, message)` — that was synchronous and could only return `{ auth } | null`. That made it impossible to do any awaited pre-dispatch work (DB lookups, OAuth refresh, etc.) or to fire awaited side effects on the inbound webhook side before the workflow runtime cold-starts.
10
+
11
+ Three additive changes:
12
+
13
+ - **`run` is now sync-or-async.** Return type is `SlackRunResult | Promise<SlackRunResult>`. The framework `await`s the result before dispatching. Existing sync `run()` callers continue to work unchanged.
14
+ - **New `onMention(ctx, message)` hook.** Fires after `run()` accepts and before `send()` enqueues the turn. The framework awaits it; thrown errors are caught and logged so a misbehaving handler cannot block dispatch. Use this for free-form pre-dispatch side effects — starting a typing indicator, logging, etc. The framework still owns dispatch; to skip a turn, return `null` from `run()`.
15
+ - **`onInteraction` JSDoc.** Documented the existing handler's semantics: HITL `action_id` routing (`ash_input:*` is consumed by the framework before reaching this handler), `waitUntil` execution, error swallowing, and the limitations of the rebuilt `SlackContext`.
16
+
17
+ The higher-level `slack()` wrapper moves its `Thinking...` typing indicator into `onMention` so it fires on the inbound webhook side, not after the workflow runtime materializes. The existing `events["turn.started"]` handler still fires the indicator for subsequent in-session turns (HITL follow-ups, multi-turn tool loops).
18
+
19
+ Docs updated:
20
+
21
+ - `docs/public/channels/slack.md` now has a `Hooks` section explaining `run` vs `onMention` vs `onInteraction` vs `events`, and the `Typing Indicators` section uses `onMention` instead of an un-awaited `startTyping()` inside `run()` (which was a dangling-promise footgun).
22
+ - The `Customize Delivery` example now correctly nests event handlers under `events: { ... }` (the previous example showed them flat on the config object, which never worked).
23
+
24
+ No breaking changes.
25
+
26
+ ### Patch Changes
27
+
28
+ - 41947c0: fix(slack): forward `webhookVerifier` to the adapter rebuilt for event-handler context
29
+
30
+ Follow-up to the previous webhook-verifier fix. `slackChannel` instantiates Slack adapters in two places: `getChat()` for inbound webhook routing and `rebuildSlackContext()` for outbound event-handler dispatch (e.g. delivering `session.failed` at the end of a turn). The previous fix only plumbed `webhookVerifier` and `signingSecret` through the first site, so a Connect-credentialed channel that successfully accepted the inbound webhook would later crash when the runtime tried to materialize the channel context for terminal events:
31
+
32
+ ```
33
+ ValidationError: signingSecret or webhookVerifier is required.
34
+ at rebuildSlackContext (..., adapter: 'slack', code: 'VALIDATION_ERROR')
35
+ ```
36
+
37
+ Concretely:
38
+
39
+ - Extracted a single `resolveSlackAdapterCredentials(credentials)` helper that returns `{ botToken, signingSecret, webhookVerifier }` with the env-var fallback rules (skipping `SLACK_SIGNING_SECRET` when a verifier is supplied).
40
+ - Both `getChat()` and `rebuildSlackContext()` now resolve credentials through that helper and pass the full triple into `createSlackAdapter`, keeping the two adapter instantiation sites in lockstep so a future credential field cannot drift again.
41
+ - `rebuildSlackContext`'s signature now takes the full `SlackChannelCredentials | undefined` instead of just `botToken`.
42
+
43
+ No public API change.
44
+
45
+ - 06cd322: chore(vendor): vendor the `chat` package's real `.d.ts` instead of a hand-written stub so `ctx.thread` and friends expose the actual chat surface (`refresh()`, `startTyping()`, `post()`, `postEphemeral()`, …) instead of `any`.
46
+
47
+ Previously, `#compiled/chat/index.js` shipped an Ash-owned hand-written declaration that declared `Thread = any`, `Message = any`, `Author = any`, etc. The runtime value of `ctx.thread` was always a real `ThreadImpl` from the bundled chat package, so methods like `thread.refresh()` worked at runtime — they just typechecked as `any` regardless of whether the method existed. Hand-written stubs also silently drifted from upstream on every `chat` version bump.
48
+
49
+ What changed:
50
+
51
+ - The vendor step now copies `chat`'s real `dist/index.d.ts` verbatim into `.generated/compiled/chat/index.d.ts`, with three transforms applied at copy time:
52
+ - The sibling `jsx-runtime-<hash>.d.ts` chunk is co-copied so chat's relative import resolves locally. The chunk filename has a content hash, so it's discovered dynamically.
53
+ - `from '@workflow/serde'` is rewritten to a locally-emitted stub that declares just the `unique symbol`s chat references.
54
+ - `from 'mdast'` is rewritten to a locally-emitted stub that aliases the names chat references to `unknown` — consumers don't need to install `@types/mdast`.
55
+ - Any external the upstream `.d.ts` reaches for that has no rewrite rule is a hard error at vendor time so a future chat version can't sneak a new dependency past us.
56
+ - The same copy-from-package treatment is applied to `@chat-adapter/slack` and `@chat-adapter/state-memory`, whose types extend chat's `Adapter` / `StateAdapter` interfaces and have to satisfy them after the chat copy.
57
+ - `chat`, `@chat-adapter/slack`, and `@chat-adapter/state-memory` are bumped from `^4.27.0` to `4.28.1`. Every other direct dependency in `packages/ash/package.json` is also locked (no `^` ranges) so the vendored output is reproducible. Peer deps still use ranges so consumers control compatibility.
58
+ - `slackChannel.rebuildSlackContext` was assigning to `thread._adapter` directly; that field is `private` in the real chat types. Switched to `Reflect.set(thread, "_adapter", adapter)` which preserves runtime behavior without an unsafe cast.
59
+
60
+ What this means for agent code:
61
+
62
+ ```ts
63
+ // Before — typechecked as `any`, no autocomplete:
64
+ await ctx.thread.refresh();
65
+ await ctx.thread.startTyping("Working on it…");
66
+ const participants = await ctx.thread.getParticipants();
67
+
68
+ // After — typechecked against the actual chat@4.28.1 Thread interface
69
+ // with full autocomplete, JSDoc, and error reporting:
70
+ await ctx.thread.refresh();
71
+ await ctx.thread.startTyping("Working on it…");
72
+ const participants = await ctx.thread.getParticipants();
73
+ ```
74
+
75
+ If your handlers were calling methods that don't exist on `Thread` and were passing typecheck through `any`, you'll see real type errors now. The runtime behavior is unchanged.
76
+
77
+ Vendor-script refactor (internal, no public-API impact):
78
+
79
+ - `scripts/vendor-compiled.mjs` shrank from ~1500 lines to ~36 lines. Per-package configs moved to one file each under `scripts/vendor-compiled/`, mirroring npm package names (`@chat-adapter/slack.mjs`, `@workflow/core.mjs`, etc.).
80
+ - Inline `.d.ts` template-literal strings moved to real `.d.ts` files under `scripts/vendor-compiled/declarations/` with editor syntax highlighting.
81
+ - Reusable bundling primitives (`runVendor`, `createDeclarationCopier`, `buildUniqueSymbolStub`, `buildOpaqueTypesStub`, `createOptionalNativeStubPlugin`, `collectFilesRecursively`) live in `scripts/vendor-compiled/_shared.mjs` so other packages in the monorepo can adopt the same vendoring pipeline without duplication.
82
+
3
83
  ## 0.8.3
4
84
 
5
85
  ### Patch Changes
@@ -127,6 +127,7 @@ import { slackChannelCredentials } from "@vercel/connex/ash";
127
127
  import { slackChannel } from "experimental-ash/channels/slack";
128
128
 
129
129
  export default slackChannel({
130
+ credentials: slackChannelCredentials("slack/my-agent"),
130
131
  run(ctx, message) {
131
132
  return {
132
133
  auth: {
@@ -137,37 +138,57 @@ export default slackChannel({
137
138
  },
138
139
  };
139
140
  },
140
- "message.completed"(event, ctx) {
141
- if (event.finishReason === "tool-calls") return;
142
- if (event.message) ctx.thread.post(event.message);
143
- },
144
- "session.failed"(event, ctx) {
145
- ctx.thread.post("Something went wrong.");
141
+ events: {
142
+ "message.completed"(event, ctx) {
143
+ if (event.finishReason === "tool-calls") return;
144
+ if (event.message) ctx.thread.post(event.message);
145
+ },
146
+ "session.failed"(event, ctx) {
147
+ ctx.thread.post("Something went wrong.");
148
+ },
146
149
  },
147
- credentials: slackChannelCredentials("slack/my-agent"),
148
150
  });
149
151
  ```
150
152
 
153
+ ## Hooks
154
+
155
+ `slackChannel` exposes three places to plug in custom behavior:
156
+
157
+ - **`run(ctx, message)`** -- decides whether to dispatch a turn for an inbound `app_mention` and
158
+ with what `auth` context. Returns `{ auth }` to dispatch or `null` to silently drop the mention.
159
+ May be sync or async; the framework awaits the result before dispatching.
160
+ - **`onMention(ctx, message)`** -- free-form pre-dispatch side effects, invoked on the inbound
161
+ webhook side after `run()` accepts and before the turn is enqueued. Use it for work that should
162
+ fire immediately, before the workflow runtime cold-starts -- starting a typing indicator,
163
+ logging, etc. Errors are caught and logged; the turn still dispatches.
164
+ - **`onInteraction(action, ctx)`** -- handler for Slack `block_actions` callbacks (button clicks,
165
+ selects, etc.) that are not consumed by the framework's HITL pipeline. Runs on the inbound
166
+ webhook side via `waitUntil`, so the channel returns `200 OK` to Slack immediately.
167
+
168
+ `events: { ... }` handlers receive runtime events emitted by the harness after the turn dispatches
169
+ (`turn.started`, `message.completed`, `session.failed`, etc.). They run inside the workflow context,
170
+ not on the inbound webhook side.
171
+
151
172
  ## Typing Indicators
152
173
 
153
174
  Out of the box, `slack()` posts typing statuses so the user sees feedback before the agent starts
154
175
  thinking:
155
176
 
156
- - **`Thinking...`** -- posted by the default handler the moment a mention arrives, before the agent
157
- run starts.
177
+ - **`Thinking...`** -- posted by the default `onMention` hook the moment a mention arrives, on the
178
+ inbound webhook side, before the workflow runtime starts.
179
+ - **`Working...`** -- posted by the default `turn.started` event handler at the start of each turn
180
+ within the session, refreshing the typing indicator after the workflow runtime materializes.
158
181
  - **Tool status** -- when an `actions.requested` event fires, the default handler updates the typing
159
182
  indicator to show which tools are running.
160
183
 
161
- To customize typing indicators, use `slackChannel` and write your own event handlers:
184
+ To customize typing indicators, use `slackChannel` and supply your own `onMention` plus event
185
+ handlers:
162
186
 
163
187
  ```ts
164
188
  import { slackChannel } from "experimental-ash/channels/slack";
165
189
 
166
190
  export default slackChannel({
167
- run(ctx, message) {
168
- ctx.thread.startTyping(
169
- message.text.includes("weather") ? "Checking the weather..." : "Thinking...",
170
- );
191
+ run(_ctx, message) {
171
192
  return {
172
193
  auth: {
173
194
  principalId: message.author.userId,
@@ -177,21 +198,28 @@ export default slackChannel({
177
198
  },
178
199
  };
179
200
  },
180
- "actions.requested"(event, ctx) {
181
- const labels = event.actions.map((a) => (a.kind === "tool-call" ? a.toolName : a.kind));
182
- ctx.thread.startTyping(`Running ${labels.join(", ")}...`);
183
- },
184
- "message.completed"(event, ctx) {
185
- if (event.finishReason === "tool-calls") return;
186
- if (event.message) ctx.thread.post(event.message);
201
+ async onMention(ctx, message) {
202
+ await ctx.thread.startTyping(
203
+ message.text.includes("weather") ? "Checking the weather..." : "Thinking...",
204
+ );
187
205
  },
188
- "session.failed"(event, ctx) {
189
- ctx.thread.post("Something went wrong.");
206
+ events: {
207
+ async "actions.requested"(event, ctx) {
208
+ const labels = event.actions.map((a) => (a.kind === "tool-call" ? a.toolName : a.kind));
209
+ await ctx.thread.startTyping(`Running ${labels.join(", ")}...`);
210
+ },
211
+ async "message.completed"(event, ctx) {
212
+ if (event.finishReason === "tool-calls") return;
213
+ if (event.message) await ctx.thread.post(event.message);
214
+ },
215
+ async "session.failed"(_event, ctx) {
216
+ await ctx.thread.post("Something went wrong.");
217
+ },
190
218
  },
191
219
  });
192
220
  ```
193
221
 
194
- Event handlers are declared as named properties on the config object. They receive `(eventData, ctx)`
195
- where `ctx` carries platform handles like `ctx.thread` and `ctx.session`.
222
+ Event handlers are nested under `events: { ... }` and receive `(eventData, ctx)` where `ctx`
223
+ carries platform handles like `ctx.thread` and `ctx.slack`.
196
224
 
197
225
  See [Channels](/docs/channels) for the full channel surface.
@@ -1,24 +1,24 @@
1
1
  {
2
2
  "moduleVersions": {
3
- "turndown": "7.2.4",
4
- "zod-validation-error": "5.0.0",
5
- "zod": "4.4.3",
6
- "chat": "4.27.0",
7
- "@vercel/sandbox": "2.0.0-beta.14",
8
- "@ai-sdk/provider": "4.0.0-canary.16",
9
3
  "@ai-sdk/anthropic": "4.0.0-canary.46",
4
+ "chat": "4.28.1",
5
+ "@chat-adapter/slack": "4.28.1",
6
+ "@chat-adapter/state-memory": "4.28.1",
10
7
  "@ai-sdk/google": "4.0.0-canary.53",
11
- "@ai-sdk/openai": "4.0.0-canary.49",
8
+ "jose": "6.2.3",
9
+ "just-bash": "2.14.5",
12
10
  "@ai-sdk/mcp": "2.0.0-canary.41",
11
+ "@ai-sdk/openai": "4.0.0-canary.49",
13
12
  "@opentelemetry/api": "1.9.1",
13
+ "@ai-sdk/otel": "1.0.0-canary.77",
14
+ "@ai-sdk/provider": "4.0.0-canary.16",
15
+ "@standard-schema/spec": "1.1.0",
16
+ "turndown": "7.2.4",
17
+ "@vercel/sandbox": "2.0.0-beta.14",
14
18
  "@workflow/core": "5.0.0-beta.5",
15
19
  "@workflow/errors": "5.0.0-beta.2",
16
- "@ai-sdk/otel": "1.0.0-canary.77",
17
- "@chat-adapter/slack": "4.27.0",
18
- "@chat-adapter/state-memory": "4.27.0",
19
- "jose": "6.2.3",
20
- "just-bash": "2.14.5",
21
- "@standard-schema/spec": "1.1.0"
20
+ "zod": "4.4.3",
21
+ "zod-validation-error": "5.0.0"
22
22
  },
23
- "scriptHash": "520ce458abd555329457db163ebe68cdefda54855571c6d96b4f2a0fb76aa0c9"
23
+ "scriptHash": "ae1e079196d6cbf9f9fec8b3083fba06192d71d35e09f8980a9b99415c0d463a"
24
24
  }