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.
- package/CHANGELOG.md +6 -0
- package/dist/docs/public/advanced/auth-and-route-protection.mdx +8 -6
- package/dist/docs/public/agent-ts.md +17 -47
- package/dist/docs/public/channels/README.md +60 -0
- package/dist/docs/public/channels/ash.mdx +103 -0
- package/dist/docs/public/channels/custom.mdx +288 -0
- package/dist/docs/public/channels/discord.mdx +1 -3
- package/dist/docs/public/channels/github.md +1 -1
- package/dist/docs/public/channels/meta.json +3 -0
- package/dist/docs/public/channels/slack.mdx +29 -1
- package/dist/docs/public/channels/teams.mdx +1 -3
- package/dist/docs/public/channels/telegram.mdx +1 -3
- package/dist/docs/public/channels/twilio.mdx +1 -3
- package/dist/docs/public/frontend/nextjs.md +24 -8
- package/dist/docs/public/onboarding.md +4 -3
- package/dist/docs/public/schedules.mdx +4 -4
- package/dist/docs/public/tools.mdx +1 -1
- package/dist/src/channel/compiled-channel.d.ts +2 -6
- package/dist/src/channel/routes.d.ts +75 -7
- package/dist/src/channel/routes.js +1 -1
- package/dist/src/compiler/manifest.d.ts +4 -4
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/host/channel-routes.d.ts +2 -2
- package/dist/src/internal/nitro/host/channel-routes.js +2 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +2 -0
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/vercel-agent-summary.d.ts +2 -2
- package/dist/src/internal/vercel-agent-summary.js +1 -1
- package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/index.js +1 -1
- package/dist/src/public/definitions/channel.d.ts +7 -0
- package/dist/src/public/definitions/defineChannel.d.ts +3 -6
- package/dist/src/public/definitions/defineChannel.js +1 -1
- package/dist/src/runtime/framework-channels/index.js +1 -1
- package/dist/src/runtime/resolve-channel.js +1 -1
- package/dist/src/runtime/types.d.ts +8 -3
- package/package.json +1 -1
- package/dist/docs/public/channels/attachments.md +0 -71
- 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;
|
|
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 {
|
|
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:
|
|
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,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
|