experimental-ash 0.61.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.
Files changed (130) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/dist/docs/public/advanced/hooks.mdx +8 -2
  3. package/dist/docs/public/advanced/runs-and-streaming.md +6 -3
  4. package/dist/docs/public/advanced/typescript-api.md +32 -0
  5. package/dist/docs/public/channels/custom.mdx +23 -0
  6. package/dist/docs/public/frontend/README.md +8 -4
  7. package/dist/docs/public/frontend/meta.json +9 -1
  8. package/dist/docs/public/frontend/nextjs.md +4 -4
  9. package/dist/docs/public/frontend/nuxt.md +168 -0
  10. package/dist/docs/public/frontend/sveltekit.md +177 -0
  11. package/dist/docs/public/frontend/use-ash-agent-svelte.md +185 -0
  12. package/dist/docs/public/frontend/use-ash-agent-vue.md +236 -0
  13. package/dist/docs/public/frontend/use-ash-agent.md +14 -14
  14. package/dist/docs/public/getting-started.mdx +2 -0
  15. package/dist/skills/ash-add-agent/SKILL.md +29 -17
  16. package/dist/skills/ash-add-next/SKILL.md +58 -8
  17. package/dist/src/channel/websocket-upgrade-server.d.ts +26 -0
  18. package/dist/src/channel/websocket-upgrade-server.js +1 -0
  19. package/dist/src/chunks/use-ash-agent-BQJLh7KU.js +1224 -0
  20. package/dist/src/chunks/use-ash-agent-CRWVA4i-.js +1192 -0
  21. package/dist/src/client/ash-agent-store.d.ts +61 -0
  22. package/dist/src/client/ash-agent-store.js +2 -0
  23. package/dist/src/client/index.d.ts +2 -0
  24. package/dist/src/client/index.js +1 -1
  25. package/dist/src/compiled/.vendor-stamp.json +9 -9
  26. package/dist/src/compiled/@ai-sdk/anthropic/_provider-utils.d.ts +1 -1
  27. package/dist/src/compiled/@ai-sdk/anthropic/index.d.ts +3 -3
  28. package/dist/src/compiled/@ai-sdk/anthropic/index.js +2 -2
  29. package/dist/src/compiled/@ai-sdk/google/index.d.ts +52 -2
  30. package/dist/src/compiled/@ai-sdk/google/index.js +6 -6
  31. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  32. package/dist/src/compiled/@ai-sdk/openai/index.d.ts +32 -2
  33. package/dist/src/compiled/@ai-sdk/openai/index.js +2 -2
  34. package/dist/src/compiled/@ai-sdk/provider/index.d.ts +507 -1
  35. package/dist/src/compiled/@chat-adapter/slack/index.js +25 -25
  36. package/dist/src/compiled/@workflow/core/events-consumer.d.ts +8 -0
  37. package/dist/src/compiled/@workflow/core/index.js +2 -2
  38. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +1 -0
  39. package/dist/src/compiled/@workflow/core/runtime.js +29 -29
  40. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  41. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  42. package/dist/src/compiled/@workflow/errors/error-codes.d.ts +2 -0
  43. package/dist/src/compiled/@workflow/errors/index.d.ts +14 -0
  44. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  45. package/dist/src/compiled/@workflow/world/queue.d.ts +8 -0
  46. package/dist/src/compiled/_chunks/workflow/{dist-Chj-QcBs.js → dist-gEXVSMPU.js} +1 -1
  47. package/dist/src/compiled/_chunks/workflow/dist-zpK2YVVA.js +3 -0
  48. package/dist/src/compiled/_chunks/workflow/resume-hook-BFK9mgsb.js +12 -0
  49. package/dist/src/compiled/_chunks/workflow/{sleep-Bg0t23kF.js → sleep-CeJckNg2.js} +1 -1
  50. package/dist/src/compiled/_chunks/workflow/{symbols-u476uwyR.js → symbols-BWCAoPHE.js} +1 -1
  51. package/dist/src/compiler/manifest.d.ts +12 -0
  52. package/dist/src/compiler/manifest.js +1 -1
  53. package/dist/src/compiler/normalize-connection.d.ts +10 -2
  54. package/dist/src/compiler/normalize-connection.js +1 -1
  55. package/dist/src/execution/sandbox/bindings/local.js +1 -1
  56. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  57. package/dist/src/internal/application/package.d.ts +1 -0
  58. package/dist/src/internal/application/package.js +1 -1
  59. package/dist/src/internal/authored-definition/connection.d.ts +9 -0
  60. package/dist/src/internal/authored-definition/connection.js +1 -1
  61. package/dist/src/internal/nitro/host/build-application.js +1 -1
  62. package/dist/src/internal/nitro/host/build-vercel-agent-summary.js +1 -1
  63. package/dist/src/internal/nitro/host/channel-routes.js +2 -2
  64. package/dist/src/internal/vercel-agent-summary.d.ts +6 -4
  65. package/dist/src/internal/workflow-bundle/ash-service-route-output.js +11 -1
  66. package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
  67. package/dist/src/public/channels/auth.d.ts +1 -1
  68. package/dist/src/public/channels/index.d.ts +1 -0
  69. package/dist/src/public/channels/index.js +1 -1
  70. package/dist/src/public/connections/index.d.ts +3 -2
  71. package/dist/src/public/connections/index.js +1 -1
  72. package/dist/src/public/definitions/connections/mcp.d.ts +4 -12
  73. package/dist/src/public/definitions/connections/mcp.js +1 -1
  74. package/dist/src/public/definitions/connections/openapi.d.ts +100 -0
  75. package/dist/src/public/definitions/connections/openapi.js +1 -0
  76. package/dist/src/public/definitions/connections/protocol.d.ts +12 -0
  77. package/dist/src/public/definitions/connections/protocol.js +1 -0
  78. package/dist/src/public/next/index.d.ts +6 -6
  79. package/dist/src/public/next/index.js +1 -1
  80. package/dist/src/public/next/{vercel-json.d.ts → vercel-output-config.d.ts} +3 -3
  81. package/dist/src/public/next/vercel-output-config.js +1 -0
  82. package/dist/src/public/nuxt/dev-server.d.ts +24 -0
  83. package/dist/src/public/nuxt/dev-server.js +1 -0
  84. package/dist/src/public/nuxt/index.d.ts +1 -0
  85. package/dist/src/public/nuxt/index.js +1 -0
  86. package/dist/src/public/nuxt/module.d.ts +31 -0
  87. package/dist/src/public/nuxt/module.js +1 -0
  88. package/dist/src/public/nuxt/routing.d.ts +55 -0
  89. package/dist/src/public/nuxt/routing.js +1 -0
  90. package/dist/src/public/nuxt/vercel-json.d.ts +17 -0
  91. package/dist/src/public/{next → nuxt}/vercel-json.js +1 -1
  92. package/dist/src/public/sveltekit/dev-server.d.ts +24 -0
  93. package/dist/src/public/sveltekit/dev-server.js +1 -0
  94. package/dist/src/public/sveltekit/index.d.ts +39 -0
  95. package/dist/src/public/sveltekit/index.js +1 -0
  96. package/dist/src/public/sveltekit/routing.d.ts +32 -0
  97. package/dist/src/public/sveltekit/routing.js +1 -0
  98. package/dist/src/public/sveltekit/vercel-json.d.ts +17 -0
  99. package/dist/src/public/sveltekit/vercel-json.js +1 -0
  100. package/dist/src/react/use-ash-agent.d.ts +5 -27
  101. package/dist/src/react/use-ash-agent.js +1 -2
  102. package/dist/src/runtime/connections/openapi-client.d.ts +43 -0
  103. package/dist/src/runtime/connections/openapi-client.js +1 -0
  104. package/dist/src/runtime/connections/openapi-operations.d.ts +30 -0
  105. package/dist/src/runtime/connections/openapi-operations.js +1 -0
  106. package/dist/src/runtime/connections/openapi-schema.d.ts +39 -0
  107. package/dist/src/runtime/connections/openapi-schema.js +1 -0
  108. package/dist/src/runtime/connections/openapi-security.d.ts +41 -0
  109. package/dist/src/runtime/connections/openapi-security.js +1 -0
  110. package/dist/src/runtime/connections/openapi-spec.d.ts +20 -0
  111. package/dist/src/runtime/connections/openapi-spec.js +1 -0
  112. package/dist/src/runtime/connections/registry.d.ts +5 -7
  113. package/dist/src/runtime/connections/registry.js +1 -1
  114. package/dist/src/runtime/connections/types.d.ts +23 -0
  115. package/dist/src/runtime/resolve-connection.js +1 -1
  116. package/dist/src/runtime/types.d.ts +15 -1
  117. package/dist/src/shared/sandbox-session.d.ts +1 -1
  118. package/dist/src/shared/vercel-output-directory.d.ts +2 -0
  119. package/dist/src/shared/vercel-output-directory.js +1 -0
  120. package/dist/src/svelte/index.d.ts +3 -0
  121. package/dist/src/svelte/index.js +3 -0
  122. package/dist/src/svelte/use-ash-agent.d.ts +80 -0
  123. package/dist/src/svelte/use-ash-agent.js +3 -0
  124. package/dist/src/vue/index.d.ts +3 -0
  125. package/dist/src/vue/index.js +3 -0
  126. package/dist/src/vue/use-ash-agent.d.ts +78 -0
  127. package/dist/src/vue/use-ash-agent.js +3 -0
  128. package/package.json +59 -14
  129. package/dist/src/compiled/_chunks/workflow/dist-C4EHshZE.js +0 -3
  130. package/dist/src/compiled/_chunks/workflow/resume-hook-BlALLgSA.js +0 -12
package/CHANGELOG.md CHANGED
@@ -1,5 +1,77 @@
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
+
17
+ ## 0.62.0
18
+
19
+ ### Minor Changes
20
+
21
+ - b4dd090: Harden `defineOpenAPIConnection` for a wider range of real-world specs:
22
+
23
+ - **YAML specs**: fetched specs are now parsed as JSON or YAML (previously
24
+ JSON only), so `spec` URLs pointing at `.yaml`/`.yml` documents work.
25
+ - **Cookie parameters**: `in: cookie` parameters are now supported and
26
+ serialized into the request `Cookie` header (alongside path, query, and
27
+ header parameters).
28
+ - **Security schemes**: the document's `securitySchemes` and effective
29
+ `security` requirement (operation-level overriding document-level) are
30
+ now honored. The resolved credential is placed where the scheme says —
31
+ `apiKey` in a header, query param, or cookie; `http basic` as
32
+ `Authorization: Basic`; `http bearer` / `oauth2` / `openIdConnect` as
33
+ `Authorization: Bearer` (the previous default).
34
+ - **`nullable` down-conversion**: OpenAPI 3.0's `nullable: true` (dropped in
35
+ 3.1 / JSON Schema 2020-12) is converted to a `"null"` type so strict
36
+ providers accept the generated tool schemas. Surfaced by validating the
37
+ Vercel OpenAPI spec, which previously produced 6 non-compliant schemas.
38
+
39
+ - 2bbd6d9: Add `defineOpenAPIConnection` for authoring connections backed by an
40
+ OpenAPI 3.x document. Point it at a spec URL (or inline object) and every
41
+ operation becomes a connection tool the model can discover and call —
42
+ requests are reconstructed from the operation's path, query, header, and
43
+ body parameters, with auth and headers resolved the same way as MCP
44
+ connections. Connections now carry a `protocol` discriminator so MCP and
45
+ OpenAPI connections coexist.
46
+
47
+ `baseUrl` is optional: when omitted, the request base URL is derived from
48
+ the document's first usable `servers` entry (`{var}` placeholders are
49
+ filled from each variable's `default`, and a relative server URL is
50
+ resolved against the spec URL). Provide `baseUrl` to override it or when
51
+ the document declares no absolute server.
52
+
53
+ The auth shape shared by every connection factory is now exported as the
54
+ protocol-agnostic `ConnectionAuthDefinition` (renamed from
55
+ `McpClientAuthDefinition`).
56
+
57
+ The Vercel agent summary now reports each connection's protocol as its
58
+ `type` (`"mcp" | "openapi"`) instead of always `"mcp"`, so the dashboard
59
+ can distinguish OpenAPI connections from MCP servers.
60
+
61
+ Operation tool names are sanitized to characters model providers accept,
62
+ and generated input schemas are emitted as valid JSON Schema (draft
63
+ 2020-12) — deeply nested or recursive specs keep their `type`,
64
+ `required`, and `oneOf`/`anyOf`/`allOf` shapes intact, and invalid `type`
65
+ values from imperfect real-world specs are dropped — so strict gateways
66
+ (e.g. Anthropic) accept the whole tool list.
67
+
68
+ - e69978e: `withAsh()` now writes generated Vercel `experimentalServices` to the closest existing `.vercel/output/config.json`, falling back to the current working directory instead of mutating `vercel.json`. The Next helper option for disabling this generation is now `configureVercelOutput`.
69
+
70
+ ### Patch Changes
71
+
72
+ - 5637096: Default the `AuthFn` event type to `Request` so HTTP authentication callbacks can use the type without an explicit generic.
73
+ - 7669e2c: chore(ash): update AI SDK dependencies, import modified `Experimental_SandboxSession` and support passing `env` vars to `spawn()` and `run()`
74
+
3
75
  ## 0.61.0
4
76
 
5
77
  ### 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 React client hook,
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) instead of calling these
17
- routes directly. Next.js apps can use [`withAsh()`](../frontend/nextjs.md) to proxy these
18
- routes to the Ash runtime from the same origin.
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 two most common ways to put an agent
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
- - [`useAshAgent`](./use-ash-agent.md) — React hook for chat and agent UIs in any
13
- React app.
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).
@@ -1,3 +1,11 @@
1
1
  {
2
- "pages": ["README", "nextjs", "use-ash-agent"]
2
+ "pages": [
3
+ "README",
4
+ "nextjs",
5
+ "nuxt",
6
+ "sveltekit",
7
+ "use-ash-agent",
8
+ "use-ash-agent-vue",
9
+ "use-ash-agent-svelte"
10
+ ]
3
11
  }
@@ -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.md).
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.md)
207
- - [Hooks](../hooks.md)
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)