experimental-ash 0.62.0 → 0.63.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 +14 -0
- package/dist/docs/public/advanced/hooks.mdx +8 -2
- package/dist/docs/public/advanced/runs-and-streaming.md +6 -3
- package/dist/docs/public/advanced/typescript-api.md +32 -0
- package/dist/docs/public/channels/custom.mdx +23 -0
- package/dist/docs/public/frontend/README.md +8 -4
- package/dist/docs/public/frontend/meta.json +9 -1
- package/dist/docs/public/frontend/nextjs.md +4 -4
- package/dist/docs/public/frontend/nuxt.md +168 -0
- package/dist/docs/public/frontend/sveltekit.md +177 -0
- package/dist/docs/public/frontend/use-ash-agent-svelte.md +185 -0
- package/dist/docs/public/frontend/use-ash-agent-vue.md +236 -0
- package/dist/docs/public/frontend/use-ash-agent.md +14 -14
- package/dist/docs/public/getting-started.mdx +2 -0
- package/dist/src/channel/websocket-upgrade-server.d.ts +26 -0
- package/dist/src/channel/websocket-upgrade-server.js +1 -0
- package/dist/src/chunks/use-ash-agent-BQJLh7KU.js +1224 -0
- package/dist/src/chunks/use-ash-agent-CRWVA4i-.js +1192 -0
- package/dist/src/client/ash-agent-store.d.ts +61 -0
- package/dist/src/client/ash-agent-store.js +2 -0
- package/dist/src/client/index.d.ts +2 -0
- package/dist/src/client/index.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +3 -3
- package/dist/src/compiled/@chat-adapter/slack/index.js +25 -25
- package/dist/src/compiled/@workflow/core/events-consumer.d.ts +8 -0
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +1 -0
- package/dist/src/compiled/@workflow/core/runtime.js +29 -29
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/errors/error-codes.d.ts +2 -0
- package/dist/src/compiled/@workflow/errors/index.d.ts +14 -0
- package/dist/src/compiled/@workflow/errors/index.js +1 -1
- package/dist/src/compiled/@workflow/world/queue.d.ts +8 -0
- package/dist/src/compiled/_chunks/workflow/dist-zpK2YVVA.js +3 -0
- package/dist/src/compiled/_chunks/workflow/resume-hook-BFK9mgsb.js +12 -0
- package/dist/src/compiled/_chunks/workflow/{sleep-Bg0t23kF.js → sleep-CeJckNg2.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{symbols-u476uwyR.js → symbols-BWCAoPHE.js} +1 -1
- package/dist/src/internal/application/package.d.ts +1 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/nitro/host/channel-routes.js +2 -2
- package/dist/src/internal/workflow-bundle/ash-service-route-output.js +11 -1
- package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
- package/dist/src/public/channels/index.d.ts +1 -0
- package/dist/src/public/channels/index.js +1 -1
- package/dist/src/public/nuxt/dev-server.d.ts +24 -0
- package/dist/src/public/nuxt/dev-server.js +1 -0
- package/dist/src/public/nuxt/index.d.ts +1 -0
- package/dist/src/public/nuxt/index.js +1 -0
- package/dist/src/public/nuxt/module.d.ts +31 -0
- package/dist/src/public/nuxt/module.js +1 -0
- package/dist/src/public/nuxt/routing.d.ts +55 -0
- package/dist/src/public/nuxt/routing.js +1 -0
- package/dist/src/public/nuxt/vercel-json.d.ts +17 -0
- package/dist/src/public/nuxt/vercel-json.js +1 -0
- package/dist/src/public/sveltekit/dev-server.d.ts +24 -0
- package/dist/src/public/sveltekit/dev-server.js +1 -0
- package/dist/src/public/sveltekit/index.d.ts +39 -0
- package/dist/src/public/sveltekit/index.js +1 -0
- package/dist/src/public/sveltekit/routing.d.ts +32 -0
- package/dist/src/public/sveltekit/routing.js +1 -0
- package/dist/src/public/sveltekit/vercel-json.d.ts +17 -0
- package/dist/src/public/sveltekit/vercel-json.js +1 -0
- package/dist/src/react/use-ash-agent.d.ts +5 -27
- package/dist/src/react/use-ash-agent.js +1 -2
- package/dist/src/svelte/index.d.ts +3 -0
- package/dist/src/svelte/index.js +3 -0
- package/dist/src/svelte/use-ash-agent.d.ts +80 -0
- package/dist/src/svelte/use-ash-agent.js +3 -0
- package/dist/src/vue/index.d.ts +3 -0
- package/dist/src/vue/index.js +3 -0
- package/dist/src/vue/use-ash-agent.d.ts +78 -0
- package/dist/src/vue/use-ash-agent.js +3 -0
- package/package.json +51 -6
- package/dist/src/compiled/_chunks/workflow/dist-C4EHshZE.js +0 -3
- package/dist/src/compiled/_chunks/workflow/resume-hook-BlALLgSA.js +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# experimental-ash
|
|
2
2
|
|
|
3
|
+
## 0.63.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 524cae7: Add `createWebSocketUpgradeServer()` as an escape hatch for `WS()` routes that need to adapt SDKs or frameworks which bind directly to Node `http.Server` upgrade events.
|
|
8
|
+
- a491826: Add Svelte 5 and SvelteKit integrations, including a `useAshAgent` binding, a SvelteKit Vite plugin for Ash route proxying, Vercel services configuration, docs, tests, and an example app.
|
|
9
|
+
- a491826: Add Vue composable (`useAshAgent`) and Nuxt module (`experimental-ash/nuxt`) for building agent UIs with Vue and Nuxt. The shared `AshAgentStore` class is now exported from `experimental-ash/client` for framework-agnostic consumption.
|
|
10
|
+
|
|
11
|
+
## 0.62.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- d141e9e: Update `@workflow/*` dependencies to the latest beta: `@workflow/core` 5.0.0-beta.12, `@workflow/errors` 5.0.0-beta.7, `@workflow/world` 5.0.0-beta.7, and `@workflow/world-local` 5.0.0-beta.13.
|
|
16
|
+
|
|
3
17
|
## 0.62.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
|
@@ -6,8 +6,10 @@ url: /hooks
|
|
|
6
6
|
|
|
7
7
|
Hooks are Ash's authored extension points for the runtime event stream.
|
|
8
8
|
|
|
9
|
-
This page is about `agent/hooks/*.ts` runtime hooks. For the
|
|
10
|
-
see [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
9
|
+
This page is about `agent/hooks/*.ts` runtime hooks. For the client-side hook,
|
|
10
|
+
see [`useAshAgent`](../frontend/use-ash-agent.md) (React) or
|
|
11
|
+
[`useAshAgent` (Vue)](../frontend/use-ash-agent-vue.md) or
|
|
12
|
+
[`useAshAgent` (Svelte)](../frontend/use-ash-agent-svelte.md).
|
|
11
13
|
|
|
12
14
|
Use a hook when you want to observe stream events (audit, metrics,
|
|
13
15
|
alerting) without writing a tool, a context provider, or a channel
|
|
@@ -188,7 +190,11 @@ when both are registered.
|
|
|
188
190
|
## What to read next
|
|
189
191
|
|
|
190
192
|
- [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
193
|
+
- [`useAshAgent` (Vue)](../frontend/use-ash-agent-vue.md)
|
|
194
|
+
- [`useAshAgent` (Svelte)](../frontend/use-ash-agent-svelte.md)
|
|
191
195
|
- [Next.js](../frontend/nextjs.md)
|
|
196
|
+
- [Nuxt](../frontend/nuxt.md)
|
|
197
|
+
- [SvelteKit](../frontend/sveltekit.md)
|
|
192
198
|
- [Tools](./tools.mdx)
|
|
193
199
|
- [Context Control](./context-control.md)
|
|
194
200
|
- [Sessions And Streaming](./runs-and-streaming.md)
|
|
@@ -13,9 +13,10 @@ The key client model is:
|
|
|
13
13
|
- `POST /ash/v1/session/:sessionId` sends a follow-up message
|
|
14
14
|
- `GET /ash/v1/session/:sessionId/stream` lets you watch the session in real time
|
|
15
15
|
|
|
16
|
-
React apps can use [`useAshAgent()`](../frontend/use-ash-agent.md)
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
React apps can use [`useAshAgent()`](../frontend/use-ash-agent.md) and Vue apps can use
|
|
17
|
+
[`useAshAgent()` (Vue)](../frontend/use-ash-agent-vue.md) instead of calling these routes
|
|
18
|
+
directly. [Next.js](../frontend/nextjs.md) and [Nuxt](../frontend/nuxt.md) apps can proxy
|
|
19
|
+
these routes to the Ash runtime from the same origin.
|
|
19
20
|
|
|
20
21
|
Ash keeps those separate on purpose:
|
|
21
22
|
|
|
@@ -127,7 +128,9 @@ channel has already updated its state and the projection is current.
|
|
|
127
128
|
## What To Read Next
|
|
128
129
|
|
|
129
130
|
- [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
131
|
+
- [`useAshAgent` (Vue)](../frontend/use-ash-agent-vue.md)
|
|
130
132
|
- [Next.js](../frontend/nextjs.md)
|
|
133
|
+
- [Nuxt](../frontend/nuxt.md)
|
|
131
134
|
- [Session Context](./session-context.md)
|
|
132
135
|
- [Subagents](./subagents.mdx)
|
|
133
136
|
- [Schedules](./schedules.mdx)
|
|
@@ -18,6 +18,10 @@ Source of truth:
|
|
|
18
18
|
- React subpath: [`../../packages/ash/src/react/index.ts`](../../packages/ash/src/react/index.ts)
|
|
19
19
|
- client subpath: [`../../packages/ash/src/client/index.ts`](../../packages/ash/src/client/index.ts)
|
|
20
20
|
- evals subpath: [`../../packages/ash/src/evals/index.ts`](../../packages/ash/src/evals/index.ts)
|
|
21
|
+
- vue subpath: [`../../packages/ash/src/vue/index.ts`](../../packages/ash/src/vue/index.ts)
|
|
22
|
+
- nuxt subpath: [`../../packages/ash/src/public/nuxt/index.ts`](../../packages/ash/src/public/nuxt/index.ts)
|
|
23
|
+
- svelte subpath: [`../../packages/ash/src/svelte/index.ts`](../../packages/ash/src/svelte/index.ts)
|
|
24
|
+
- SvelteKit subpath: [`../../packages/ash/src/public/sveltekit/index.ts`](../../packages/ash/src/public/sveltekit/index.ts)
|
|
21
25
|
|
|
22
26
|
## Definition Helpers
|
|
23
27
|
|
|
@@ -85,6 +89,32 @@ React helpers exported from `experimental-ash/react`:
|
|
|
85
89
|
- `UseAshAgentOptions`, `UseAshAgentHelpers`, `UseAshAgentSnapshot`, `UseAshAgentStatus` - hook configuration and state types
|
|
86
90
|
- `AshMessageData`, `AshMessage`, `AshMessagePart`, `AshDynamicToolPart` - default message projection types
|
|
87
91
|
|
|
92
|
+
Nuxt helpers exported from `experimental-ash/nuxt`:
|
|
93
|
+
|
|
94
|
+
- `default` - the Nuxt module that runs the Ash agent alongside your Nuxt app
|
|
95
|
+
- `ASH_NUXT_SERVICE_PREFIX` - default private Vercel service prefix for the Ash service
|
|
96
|
+
- `AshNuxtModuleOptions` - options for `ashRoot`, `ashBuildCommand`, `configureVercelJson`, and `servicePrefix`
|
|
97
|
+
|
|
98
|
+
Vue helpers exported from `experimental-ash/vue`:
|
|
99
|
+
|
|
100
|
+
- `useAshAgent(options?)` - Vue composable for sending turns, streaming events, projecting reactive UI state, and tracking a session cursor
|
|
101
|
+
- `defaultMessageReducer()` - default chat-style event projection used by `useAshAgent()`
|
|
102
|
+
- `UseAshAgentOptions`, `UseAshAgentReturn`, `UseAshAgentSnapshot`, `UseAshAgentStatus`, `PrepareSend` - composable configuration and state types
|
|
103
|
+
- `AshAgentReducer`, `AshMessageData`, `AshMessage`, `AshMessagePart`, `AshDynamicToolPart` - reducer and default message projection types
|
|
104
|
+
|
|
105
|
+
SvelteKit helpers exported from `experimental-ash/sveltekit`:
|
|
106
|
+
|
|
107
|
+
- `ashSvelteKit(options?)` - Vite plugin that runs the Ash agent alongside your SvelteKit app
|
|
108
|
+
- `ASH_SVELTEKIT_SERVICE_PREFIX` - default private Vercel service prefix for the Ash service
|
|
109
|
+
- `AshSvelteKitPluginOptions` - options for `ashRoot`, `ashBuildCommand`, `configureVercelJson`, and `servicePrefix`
|
|
110
|
+
|
|
111
|
+
Svelte helpers exported from `experimental-ash/svelte`:
|
|
112
|
+
|
|
113
|
+
- `useAshAgent(options?)` - Svelte 5 binding for sending turns, streaming events, projecting rune-friendly UI state, and tracking a session cursor
|
|
114
|
+
- `defaultMessageReducer()` - default chat-style event projection used by `useAshAgent()`
|
|
115
|
+
- `UseAshAgentOptions`, `UseAshAgentReturn`, `UseAshAgentSnapshot`, `UseAshAgentStatus`, `PrepareSend` - binding configuration and state types
|
|
116
|
+
- `AshAgentReducer`, `AshMessageData`, `AshMessage`, `AshMessagePart`, `AshDynamicToolPart` - reducer and default message projection types
|
|
117
|
+
|
|
88
118
|
Client helpers exported from `experimental-ash/client`:
|
|
89
119
|
|
|
90
120
|
- `Client` - HTTP client for an Ash server
|
|
@@ -321,6 +351,8 @@ import { Braintrust } from "experimental-ash/evals/reporters";
|
|
|
321
351
|
- `ctx.session` -> [Session Context](./session-context.md)
|
|
322
352
|
- `withAsh` -> [Next.js](../frontend/nextjs.md)
|
|
323
353
|
- `useAshAgent` -> [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
354
|
+
- `useAshAgent` (Vue) and `defaultMessageReducer` -> [`useAshAgent` (Vue)](../frontend/use-ash-agent-vue.md)
|
|
355
|
+
- Nuxt module (`experimental-ash/nuxt`) -> [Nuxt](../frontend/nuxt.md)
|
|
324
356
|
- subagents (authored with `defineAgent` under `subagents/<id>/agent.ts`) -> [Subagents](./subagents.mdx)
|
|
325
357
|
- `defineSchedule` -> [Schedules](./schedules.mdx)
|
|
326
358
|
- `defineEvalSuite`, loaders, reporters, and scorers -> [Evals](./evals.mdx)
|
|
@@ -89,6 +89,29 @@ export default defineChannel({
|
|
|
89
89
|
`params`, `waitUntil`, and `requestIp`. The returned hooks are Ash-owned structural types compatible
|
|
90
90
|
with Nitro/H3 websocket routing, including `upgrade`, `open`, `message`, `close`, and `error`.
|
|
91
91
|
|
|
92
|
+
### Node upgrade server escape hatch
|
|
93
|
+
|
|
94
|
+
Prefer the `WS()` lifecycle hooks above when you own the websocket behavior. Ash also exposes
|
|
95
|
+
`createWebSocketUpgradeServer()` for the narrower case where a third-party SDK or framework expects
|
|
96
|
+
to bind directly to a Node `http.Server` with `server.on("upgrade", ...)`.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { defineChannel, WS, createWebSocketUpgradeServer } from "experimental-ash/channels";
|
|
100
|
+
|
|
101
|
+
const bridge = createWebSocketUpgradeServer();
|
|
102
|
+
|
|
103
|
+
thirdPartySdk.attach(bridge.server);
|
|
104
|
+
|
|
105
|
+
export default defineChannel({
|
|
106
|
+
routes: [WS("/vendor/ws", bridge.route)],
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The bridge server does not listen on its own port. It receives only upgrade events that matched the
|
|
111
|
+
Ash route, and only on hosts where Nitro exposes the raw Node upgrade request, socket, and head. Treat
|
|
112
|
+
it as a compatibility adapter for libraries with server-binding APIs, not as the primary way to build
|
|
113
|
+
websocket channels in Ash.
|
|
114
|
+
|
|
92
115
|
## Cross-channel hand-off
|
|
93
116
|
|
|
94
117
|
Route handlers can start a session on a different channel via `args.receive(channel, ...)`. Use this
|
|
@@ -4,13 +4,17 @@ description: "Wire your web app to an Ash agent."
|
|
|
4
4
|
url: /frontend
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Ash ships first-class helpers for the
|
|
7
|
+
Ash ships first-class helpers for the most common ways to put an agent
|
|
8
8
|
behind a web UI:
|
|
9
9
|
|
|
10
10
|
- [Next.js](./nextjs.md) — `withAsh()` runs the Ash agent alongside your
|
|
11
11
|
Next.js app.
|
|
12
|
-
- [
|
|
13
|
-
|
|
12
|
+
- [Nuxt](./nuxt.md) — `experimental-ash/nuxt` module runs the Ash agent
|
|
13
|
+
alongside your Nuxt app.
|
|
14
|
+
- [`useAshAgent` (React)](./use-ash-agent.md) — React hook for chat and agent
|
|
15
|
+
UIs in any React app.
|
|
16
|
+
- [`useAshAgent` (Vue)](./use-ash-agent-vue.md) — Vue composable for chat and
|
|
17
|
+
agent UIs in any Vue app.
|
|
14
18
|
|
|
15
19
|
For other stacks, call Ash directly over its HTTP routes —
|
|
16
|
-
see [Sessions And Streaming](../runs-and-streaming.md).
|
|
20
|
+
see [Sessions And Streaming](../advanced/runs-and-streaming.md).
|
|
@@ -198,11 +198,11 @@ next call only). See [`useAshAgent`](./use-ash-agent.md#add-per-turn-client-cont
|
|
|
198
198
|
for the full pattern.
|
|
199
199
|
|
|
200
200
|
For server-side enrichment (policy, durable context, dynamic skills), use
|
|
201
|
-
runtime lifecycle hooks instead. See [Hooks](../hooks.
|
|
201
|
+
runtime lifecycle hooks instead. See [Hooks](../advanced/hooks.mdx).
|
|
202
202
|
|
|
203
203
|
## What To Read Next
|
|
204
204
|
|
|
205
205
|
- [`useAshAgent`](./use-ash-agent.md)
|
|
206
|
-
- [Auth And Route Protection](../auth-and-route-protection.
|
|
207
|
-
- [Hooks](../hooks.
|
|
208
|
-
- [Sessions And Streaming](../runs-and-streaming.md)
|
|
206
|
+
- [Auth And Route Protection](../advanced/auth-and-route-protection.mdx)
|
|
207
|
+
- [Hooks](../advanced/hooks.mdx)
|
|
208
|
+
- [Sessions And Streaming](../advanced/runs-and-streaming.md)
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Nuxt"
|
|
3
|
+
description: "Add an Ash agent to a Nuxt app and call it from the browser."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`experimental-ash/nuxt` lets you ship a Nuxt frontend and an Ash agent as
|
|
7
|
+
one project. Come in from either side: drop it into an existing Nuxt app
|
|
8
|
+
to add an agent, or start with an agent and point a Nuxt project at it.
|
|
9
|
+
|
|
10
|
+
- **One dev server.** `nuxt dev` runs the app and the agent together.
|
|
11
|
+
- **One deploy.** Vercel ships them as a single project; no extra service to operate.
|
|
12
|
+
- **Zero URL plumbing.** `useAshAgent()` finds the mounted routes automatically; no CORS, no env vars.
|
|
13
|
+
|
|
14
|
+
## Add Ash To Nuxt
|
|
15
|
+
|
|
16
|
+
Register the module in your Nuxt config:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
// nuxt.config.ts
|
|
20
|
+
export default defineNuxtConfig({
|
|
21
|
+
modules: ["experimental-ash/nuxt"],
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
By default, the module looks for an `agent/` folder inside your Nuxt
|
|
26
|
+
project root. Pass `ashRoot` when the agent lives somewhere else:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
export default defineNuxtConfig({
|
|
30
|
+
modules: ["experimental-ash/nuxt"],
|
|
31
|
+
ash: {
|
|
32
|
+
ashRoot: "../my-agent",
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Add The Ash Channel
|
|
38
|
+
|
|
39
|
+
Skip this section if the framework default channel works for you. The module
|
|
40
|
+
already wires Ash up without it.
|
|
41
|
+
|
|
42
|
+
Create `agent/channels/ash.ts` when you want to choose the route auth policy
|
|
43
|
+
explicitly:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// agent/channels/ash.ts
|
|
47
|
+
import { ashChannel } from "experimental-ash/channels/ash";
|
|
48
|
+
import { none } from "experimental-ash/channels/auth";
|
|
49
|
+
|
|
50
|
+
export default ashChannel({
|
|
51
|
+
auth: none(),
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
For protected apps, replace `none()` with a channel auth helper such as
|
|
56
|
+
`vercelOidc()`, `oidc(...)`, or `httpBasic(...)`.
|
|
57
|
+
|
|
58
|
+
## Use The Vue Composable
|
|
59
|
+
|
|
60
|
+
Once the module is in `nuxt.config.ts`, browser code can use
|
|
61
|
+
[`useAshAgent()`](./use-ash-agent-vue.md) without a custom host. The module
|
|
62
|
+
auto-imports the composable, so no explicit import is needed:
|
|
63
|
+
|
|
64
|
+
```vue
|
|
65
|
+
<script setup lang="ts">
|
|
66
|
+
const { status, sendMessage } = useAshAgent();
|
|
67
|
+
|
|
68
|
+
const isBusy = computed(() => status.value === "submitted" || status.value === "streaming");
|
|
69
|
+
|
|
70
|
+
const message = ref("");
|
|
71
|
+
|
|
72
|
+
async function handleSubmit() {
|
|
73
|
+
const text = message.value.trim();
|
|
74
|
+
if (!text || isBusy.value) return;
|
|
75
|
+
message.value = "";
|
|
76
|
+
await sendMessage(text);
|
|
77
|
+
}
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<template>
|
|
81
|
+
<form @submit.prevent="handleSubmit">
|
|
82
|
+
<input v-model="message" :disabled="isBusy" />
|
|
83
|
+
<button type="submit" :disabled="isBusy">Send</button>
|
|
84
|
+
</form>
|
|
85
|
+
</template>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The composable handles conversation state, streaming updates, errors, and
|
|
89
|
+
messages for you. See [`useAshAgent` (Vue)](./use-ash-agent-vue.md) for the
|
|
90
|
+
full API.
|
|
91
|
+
|
|
92
|
+
## Local Development
|
|
93
|
+
|
|
94
|
+
`pnpm dev` is enough. The module boots the Ash dev server alongside Nuxt
|
|
95
|
+
and proxies the Ash routes to it, so your browser keeps talking to the
|
|
96
|
+
Nuxt origin.
|
|
97
|
+
|
|
98
|
+
## Vercel Deployments
|
|
99
|
+
|
|
100
|
+
On Vercel, the module keeps the web app public and the Ash runtime tucked
|
|
101
|
+
behind it. Users visit the Nuxt app, and the browser talks to the agent
|
|
102
|
+
through the same site origin.
|
|
103
|
+
|
|
104
|
+
Use `ashBuildCommand` when the agent needs a project-specific build command:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
export default defineNuxtConfig({
|
|
108
|
+
modules: ["experimental-ash/nuxt"],
|
|
109
|
+
ash: {
|
|
110
|
+
ashBuildCommand: "pnpm build:ash",
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Non-Vercel Production Hosts
|
|
116
|
+
|
|
117
|
+
If you deploy somewhere other than Vercel and the Ash service runs on a
|
|
118
|
+
separate origin, point Nuxt at it with `ASH_NUXT_PRODUCTION_ORIGIN`:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
ASH_NUXT_PRODUCTION_ORIGIN=https://agent.example.com pnpm build
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Set `ASH_NUXT_PRODUCTION_PORT` to use a different local port (default `4274`):
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
ASH_NUXT_PRODUCTION_PORT=5000 pnpm build && pnpm preview
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Authenticated Requests
|
|
131
|
+
|
|
132
|
+
Because the agent runs on the same origin as your Nuxt app, the auth you
|
|
133
|
+
already use for the rest of the app applies to it for free. Cookie-based
|
|
134
|
+
sessions work without extra wiring: the browser already sends those cookies
|
|
135
|
+
on every Ash request.
|
|
136
|
+
|
|
137
|
+
For non-cookie schemes (bearer tokens, custom headers), attach them from the
|
|
138
|
+
client instead:
|
|
139
|
+
|
|
140
|
+
```vue
|
|
141
|
+
<script setup lang="ts">
|
|
142
|
+
const agent = useAshAgent({
|
|
143
|
+
headers: async () => ({
|
|
144
|
+
authorization: `Bearer ${await getAccessToken()}`,
|
|
145
|
+
}),
|
|
146
|
+
});
|
|
147
|
+
</script>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Prefer function values for short-lived credentials. Ash re-resolves them
|
|
151
|
+
before each HTTP request, including reconnects.
|
|
152
|
+
|
|
153
|
+
## Add Per-Turn Page Context
|
|
154
|
+
|
|
155
|
+
`useAshAgent()` accepts a `prepareSend` callback for attaching one-turn page
|
|
156
|
+
state (pathname, selected ids, anything else the model should see for the
|
|
157
|
+
next call only). See [`useAshAgent` (Vue)](./use-ash-agent-vue.md#add-per-turn-client-context)
|
|
158
|
+
for the full pattern.
|
|
159
|
+
|
|
160
|
+
For server-side enrichment (policy, durable context, dynamic skills), use
|
|
161
|
+
runtime lifecycle hooks instead. See [Hooks](../advanced/hooks.mdx).
|
|
162
|
+
|
|
163
|
+
## What To Read Next
|
|
164
|
+
|
|
165
|
+
- [`useAshAgent` (Vue)](./use-ash-agent-vue.md)
|
|
166
|
+
- [Auth And Route Protection](../advanced/auth-and-route-protection.mdx)
|
|
167
|
+
- [Hooks](../advanced/hooks.mdx)
|
|
168
|
+
- [Sessions And Streaming](../advanced/runs-and-streaming.md)
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "SvelteKit"
|
|
3
|
+
description: "Add an Ash agent to a SvelteKit app and call it from the browser."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`experimental-ash/sveltekit` lets you ship a SvelteKit frontend and an Ash
|
|
7
|
+
agent as one project. Add the Vite plugin to an existing SvelteKit app, or
|
|
8
|
+
start with an agent and point a SvelteKit project at it.
|
|
9
|
+
|
|
10
|
+
- **One dev server.** `vite dev` runs the app and the agent together.
|
|
11
|
+
- **One deploy.** Vercel ships them as a single project; no extra service to operate.
|
|
12
|
+
- **Zero URL plumbing.** `useAshAgent()` finds the mounted routes automatically; no CORS, no env vars.
|
|
13
|
+
|
|
14
|
+
## Add Ash To SvelteKit
|
|
15
|
+
|
|
16
|
+
Register the plugin in your Vite config:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
// vite.config.ts
|
|
20
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
21
|
+
import { ashSvelteKit } from "experimental-ash/sveltekit";
|
|
22
|
+
import { defineConfig } from "vite";
|
|
23
|
+
|
|
24
|
+
export default defineConfig({
|
|
25
|
+
plugins: [ashSvelteKit(), sveltekit()],
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
By default, the plugin looks for an `agent/` folder inside your SvelteKit
|
|
30
|
+
project root. Pass `ashRoot` when the agent lives somewhere else:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
export default defineConfig({
|
|
34
|
+
plugins: [
|
|
35
|
+
ashSvelteKit({
|
|
36
|
+
ashRoot: "../my-agent",
|
|
37
|
+
}),
|
|
38
|
+
sveltekit(),
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Add The Ash Channel
|
|
44
|
+
|
|
45
|
+
Skip this section if the framework default channel works for you. The plugin
|
|
46
|
+
already wires Ash up without it.
|
|
47
|
+
|
|
48
|
+
Create `agent/channels/ash.ts` when you want to choose the route auth policy
|
|
49
|
+
explicitly:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// agent/channels/ash.ts
|
|
53
|
+
import { ashChannel } from "experimental-ash/channels/ash";
|
|
54
|
+
import { none } from "experimental-ash/channels/auth";
|
|
55
|
+
|
|
56
|
+
export default ashChannel({
|
|
57
|
+
auth: none(),
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For protected apps, replace `none()` with a channel auth helper such as
|
|
62
|
+
`vercelOidc()`, `oidc(...)`, or `httpBasic(...)`.
|
|
63
|
+
|
|
64
|
+
## Use The Svelte Binding
|
|
65
|
+
|
|
66
|
+
Once the plugin is in `vite.config.ts`, browser code can use
|
|
67
|
+
[`useAshAgent()`](./use-ash-agent-svelte.md) without a custom host:
|
|
68
|
+
|
|
69
|
+
```svelte
|
|
70
|
+
<script lang="ts">
|
|
71
|
+
import { useAshAgent } from "experimental-ash/svelte";
|
|
72
|
+
|
|
73
|
+
const agent = useAshAgent();
|
|
74
|
+
let message = $state("");
|
|
75
|
+
let isBusy = $derived(agent.status === "submitted" || agent.status === "streaming");
|
|
76
|
+
|
|
77
|
+
async function handleSubmit() {
|
|
78
|
+
const text = message.trim();
|
|
79
|
+
if (!text || isBusy) return;
|
|
80
|
+
message = "";
|
|
81
|
+
await agent.sendMessage(text);
|
|
82
|
+
}
|
|
83
|
+
</script>
|
|
84
|
+
|
|
85
|
+
<form onsubmit={(event) => {
|
|
86
|
+
event.preventDefault();
|
|
87
|
+
void handleSubmit();
|
|
88
|
+
}}>
|
|
89
|
+
<input bind:value={message} disabled={isBusy} />
|
|
90
|
+
<button type="submit" disabled={isBusy}>Send</button>
|
|
91
|
+
</form>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The binding handles conversation state, streaming updates, errors, and messages
|
|
95
|
+
for you. See [`useAshAgent` (Svelte)](./use-ash-agent-svelte.md) for the full
|
|
96
|
+
API.
|
|
97
|
+
|
|
98
|
+
## Local Development
|
|
99
|
+
|
|
100
|
+
`pnpm dev` is enough. The plugin boots the Ash dev server alongside SvelteKit
|
|
101
|
+
and proxies the Ash routes to it, so your browser keeps talking to the
|
|
102
|
+
SvelteKit origin.
|
|
103
|
+
|
|
104
|
+
`pnpm build && pnpm preview` works the same way for local production preview:
|
|
105
|
+
the preview server gets its own Ash route proxy and reuses or starts the shared
|
|
106
|
+
Ash server automatically.
|
|
107
|
+
|
|
108
|
+
## Vercel Deployments
|
|
109
|
+
|
|
110
|
+
On Vercel, the plugin keeps the web app public and the Ash runtime tucked
|
|
111
|
+
behind it. Users visit the SvelteKit app, and the browser talks to the agent
|
|
112
|
+
through the same site origin.
|
|
113
|
+
|
|
114
|
+
Use `ashBuildCommand` when the agent needs a project-specific build command:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
export default defineConfig({
|
|
118
|
+
plugins: [
|
|
119
|
+
ashSvelteKit({
|
|
120
|
+
ashBuildCommand: "pnpm build:ash",
|
|
121
|
+
}),
|
|
122
|
+
sveltekit(),
|
|
123
|
+
],
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Non-Vercel Production Hosts
|
|
128
|
+
|
|
129
|
+
If you deploy somewhere other than Vercel and the Ash service runs on a
|
|
130
|
+
separate origin, pass `host` directly to `useAshAgent`:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const agent = useAshAgent({
|
|
134
|
+
host: "https://agent.example.com",
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Authenticated Requests
|
|
139
|
+
|
|
140
|
+
Because the agent runs on the same origin as your SvelteKit app, the auth you
|
|
141
|
+
already use for the rest of the app applies to it for free. Cookie-based
|
|
142
|
+
sessions work without extra wiring: the browser already sends those cookies on
|
|
143
|
+
every Ash request.
|
|
144
|
+
|
|
145
|
+
For non-cookie schemes (bearer tokens, custom headers), attach them from the
|
|
146
|
+
client instead:
|
|
147
|
+
|
|
148
|
+
```svelte
|
|
149
|
+
<script lang="ts">
|
|
150
|
+
const agent = useAshAgent({
|
|
151
|
+
headers: async () => ({
|
|
152
|
+
authorization: `Bearer ${await getAccessToken()}`,
|
|
153
|
+
}),
|
|
154
|
+
});
|
|
155
|
+
</script>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Prefer function values for short-lived credentials. Ash re-resolves them before
|
|
159
|
+
each HTTP request, including reconnects.
|
|
160
|
+
|
|
161
|
+
## Add Per-Turn Page Context
|
|
162
|
+
|
|
163
|
+
`useAshAgent()` accepts a `prepareSend` callback for attaching one-turn page
|
|
164
|
+
state (pathname, selected ids, anything else the model should see for the next
|
|
165
|
+
call only). See
|
|
166
|
+
[`useAshAgent` (Svelte)](./use-ash-agent-svelte.md#add-per-turn-client-context)
|
|
167
|
+
for the full pattern.
|
|
168
|
+
|
|
169
|
+
For server-side enrichment (policy, durable context, dynamic skills), use
|
|
170
|
+
runtime lifecycle hooks instead. See [Hooks](../advanced/hooks.mdx).
|
|
171
|
+
|
|
172
|
+
## What To Read Next
|
|
173
|
+
|
|
174
|
+
- [`useAshAgent` (Svelte)](./use-ash-agent-svelte.md)
|
|
175
|
+
- [Auth And Route Protection](../advanced/auth-and-route-protection.mdx)
|
|
176
|
+
- [Hooks](../advanced/hooks.mdx)
|
|
177
|
+
- [Sessions And Streaming](../advanced/runs-and-streaming.md)
|