experimental-ash 0.60.0 → 0.61.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 (42) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/docs/public/advanced/auth-and-route-protection.mdx +8 -6
  3. package/dist/docs/public/agent-ts.md +17 -47
  4. package/dist/docs/public/channels/README.md +60 -0
  5. package/dist/docs/public/channels/ash.mdx +103 -0
  6. package/dist/docs/public/channels/custom.mdx +288 -0
  7. package/dist/docs/public/channels/discord.mdx +1 -3
  8. package/dist/docs/public/channels/github.md +1 -1
  9. package/dist/docs/public/channels/meta.json +3 -0
  10. package/dist/docs/public/channels/slack.mdx +29 -1
  11. package/dist/docs/public/channels/teams.mdx +1 -3
  12. package/dist/docs/public/channels/telegram.mdx +1 -3
  13. package/dist/docs/public/channels/twilio.mdx +1 -3
  14. package/dist/docs/public/frontend/nextjs.md +24 -8
  15. package/dist/docs/public/onboarding.md +4 -3
  16. package/dist/docs/public/schedules.mdx +4 -4
  17. package/dist/docs/public/tools.mdx +1 -1
  18. package/dist/src/channel/compiled-channel.d.ts +2 -6
  19. package/dist/src/channel/routes.d.ts +75 -7
  20. package/dist/src/channel/routes.js +1 -1
  21. package/dist/src/compiler/manifest.d.ts +4 -4
  22. package/dist/src/compiler/manifest.js +1 -1
  23. package/dist/src/internal/application/package.js +1 -1
  24. package/dist/src/internal/nitro/host/channel-routes.d.ts +2 -2
  25. package/dist/src/internal/nitro/host/channel-routes.js +2 -1
  26. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  27. package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +2 -0
  28. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  29. package/dist/src/internal/vercel-agent-summary.d.ts +2 -2
  30. package/dist/src/internal/vercel-agent-summary.js +1 -1
  31. package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
  32. package/dist/src/public/channels/index.d.ts +1 -1
  33. package/dist/src/public/channels/index.js +1 -1
  34. package/dist/src/public/definitions/channel.d.ts +7 -0
  35. package/dist/src/public/definitions/defineChannel.d.ts +3 -6
  36. package/dist/src/public/definitions/defineChannel.js +1 -1
  37. package/dist/src/runtime/framework-channels/index.js +1 -1
  38. package/dist/src/runtime/resolve-channel.js +1 -1
  39. package/dist/src/runtime/types.d.ts +8 -3
  40. package/package.json +1 -1
  41. package/dist/docs/public/channels/attachments.md +0 -71
  42. package/dist/docs/public/channels/index.md +0 -661
@@ -1 +1 @@
1
- import{setChannelInstrumentationKind}from"#channel/compiled-channel.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeChannelDefinition}from"#internal/authored-definition/channel.js";import{ResolveAgentError,createResolvedModuleSourceRef,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";async function resolveChannelDefinition(r,i,a){try{let t=normalizeChannelDefinition(await loadResolvedModuleExport({definition:r,kindLabel:`channel`,moduleMap:i,nodeId:a}),`Expected the channel export "${r.exportName??`default`}" from "${r.logicalPath}" to match the public Ash shape.`),n=createResolvedModuleSourceRef({exportName:r.exportName,logicalPath:r.logicalPath,sourceId:r.sourceId}),o=t.routes.find(e=>e.method.toUpperCase()===r.method.toUpperCase()&&e.path===r.urlPath),s=`channel:${r.name}`;setChannelInstrumentationKind(t,s);let c=t.adapter;return c&&c.kind!==HTTP_ADAPTER_KIND&&(c.kind=s),{name:r.name,method:r.method,urlPath:r.urlPath,fetch:async(e,t)=>o?o.handler(e,t):Response.json({error:`No matching route handler.`,ok:!1},{status:404}),handler:o?.handler,receive:t.receive,definition:t,adapter:c,...n}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the channel definition from "${r.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:r.logicalPath,sourceId:r.sourceId})}}export{resolveChannelDefinition};
1
+ import{setChannelInstrumentationKind}from"#channel/compiled-channel.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeChannelDefinition}from"#internal/authored-definition/channel.js";import{ResolveAgentError,createResolvedModuleSourceRef,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";import{isHttpRouteDefinition,isWebSocketRouteDefinition}from"#channel/routes.js";async function resolveChannelDefinition(r,i,a){try{let t=normalizeChannelDefinition(await loadResolvedModuleExport({definition:r,kindLabel:`channel`,moduleMap:i,nodeId:a}),`Expected the channel export "${r.exportName??`default`}" from "${r.logicalPath}" to match the public Ash shape.`),n=createResolvedModuleSourceRef({exportName:r.exportName,logicalPath:r.logicalPath,sourceId:r.sourceId}),o=t.routes.find(e=>e.method.toUpperCase()===r.method.toUpperCase()&&e.path===r.urlPath),s=`channel:${r.name}`;setChannelInstrumentationKind(t,s);let c=t.adapter;c&&c.kind!==HTTP_ADAPTER_KIND&&(c.kind=s);let l=resolveHttpRoute(r,o),u=resolveWebSocketRoute(r,o);return{name:r.name,method:r.method,urlPath:r.urlPath,fetch:async(e,t)=>l?l.handler(e,t):Response.json({error:`No matching route handler.`,ok:!1},{status:404}),handler:l?.handler,websocket:u?.handler,receive:t.receive,definition:t,adapter:c,...n}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the channel definition from "${r.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:r.logicalPath,sourceId:r.sourceId})}}function resolveHttpRoute(e,t){if(!(t===void 0||e.method===`WEBSOCKET`||!isHttpRouteDefinition(t)))return t}function resolveWebSocketRoute(e,t){if(!(t===void 0||e.method!==`WEBSOCKET`||!isWebSocketRouteDefinition(t)))return t}export{resolveChannelDefinition};
@@ -3,8 +3,8 @@ import type { ChannelAdapter } from "#channel/adapter.js";
3
3
  import type { CompiledChannel } from "#channel/compiled-channel.js";
4
4
  import type { HeadersValue } from "#client/types.js";
5
5
  import type { DiscoverDiagnosticsSummary } from "#discover/diagnostics.js";
6
- import type { ChannelMethod, RouteContext } from "#public/definitions/channel.js";
7
- import type { RouteHandler } from "#channel/routes.js";
6
+ import type { ChannelRouteMethod, RouteContext } from "#public/definitions/channel.js";
7
+ import type { RouteHandler, WebSocketRouteHandler } from "#channel/routes.js";
8
8
  import type { OutboundAuthFn } from "#public/agents/auth.js";
9
9
  import type { StreamEventHook } from "#public/definitions/hook.js";
10
10
  import type { CompactionInput, CompactionHookResult, NeedsApprovalContext, ToolModelOutput } from "#public/definitions/tool.js";
@@ -189,7 +189,7 @@ export interface ResolvedHookDefinition extends ResolvedModuleSourceRef {
189
189
  */
190
190
  export interface ResolvedChannelDefinition extends ResolvedModuleSourceRef {
191
191
  readonly name: string;
192
- readonly method: ChannelMethod;
192
+ readonly method: ChannelRouteMethod;
193
193
  readonly adapter?: ChannelAdapter;
194
194
  readonly urlPath: string;
195
195
  readonly fetch: (req: Request, ctx: RouteContext) => Promise<Response>;
@@ -219,6 +219,11 @@ export interface ResolvedChannelDefinition extends ResolvedModuleSourceRef {
219
219
  * dispatch layer uses this instead of `fetch`.
220
220
  */
221
221
  readonly handler?: RouteHandler;
222
+ /**
223
+ * New-style websocket route handler from CompiledChannel. Present only for
224
+ * routes declared via `WS()`.
225
+ */
226
+ readonly websocket?: WebSocketRouteHandler;
222
227
  }
223
228
  /**
224
229
  * Runtime-owned local subagent node resolved from one compiled local
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "experimental-ash",
3
- "version": "0.60.0",
3
+ "version": "0.61.0",
4
4
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
5
5
  "keywords": [
6
6
  "agent-framework",
@@ -1,71 +0,0 @@
1
- ---
2
- title: "Channel file uploads"
3
- description: "Deliver inbound file attachments to the agent."
4
- ---
5
-
6
- This guide explains how channels deliver inbound files to the agent.
7
-
8
- ## How it works
9
-
10
- `send()` accepts `string | UserContent`. To include file attachments,
11
- pass a `UserContent` array mixing text and file parts:
12
-
13
- ### Inline bytes
14
-
15
- Use for small files where bytes are available in the route handler:
16
-
17
- ```ts
18
- await send(
19
- [
20
- { type: "text", text: body.message },
21
- { type: "file", data: imageBytes, mediaType: "image/png" },
22
- ],
23
- { auth, continuationToken },
24
- );
25
- ```
26
-
27
- ### URL-based files with fetchFile
28
-
29
- For platforms like Slack where files are behind authenticated URLs,
30
- put a `URL` object in `FilePart.data` and declare `fetchFile` on the
31
- channel config:
32
-
33
- ```ts
34
- defineChannel({
35
- fetchFile(url) {
36
- if (!url.startsWith("https://files.slack.com/")) return null;
37
- return fetch(url, { headers: { authorization: `Bearer ${token}` } })
38
- .then((r) => r.arrayBuffer())
39
- .then((b) => ({ bytes: Buffer.from(b) }));
40
- },
41
-
42
- routes: [
43
- POST("/webhook", async (req, { send }) => {
44
- await send(
45
- [
46
- { type: "text", text: message.text },
47
- ...message.attachments.map((a) => ({
48
- type: "file" as const,
49
- data: new URL(a.url),
50
- mediaType: a.mediaType,
51
- })),
52
- ],
53
- { auth, continuationToken, state },
54
- );
55
- }),
56
- ],
57
- });
58
- ```
59
-
60
- The `URL` object survives the queue boundary as a string and is
61
- reconstituted inside the workflow step. The staging pipeline calls
62
- `fetchFile(url)` — return bytes to stage the file to the sandbox,
63
- or return `null` to let the URL pass through to the model provider.
64
-
65
- ## What the framework handles
66
-
67
- - Staging bytes to the sandbox
68
- - Enforcing upload policy (size and media-type limits)
69
- - Hydrating files for the model call (inline bytes for images/PDFs, text
70
- references for everything else)
71
- - Reconstituting `URL` objects after queue serialization