eve 0.10.0 → 0.11.1
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 +17 -0
- package/README.md +14 -0
- package/dist/src/cli/banner.d.ts +6 -3
- package/dist/src/cli/banner.js +1 -1
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/agent-header.js +1 -1
- package/dist/src/cli/run.js +1 -1
- package/dist/src/evals/runner/run-evals.d.ts +1 -1
- package/dist/src/execution/sandbox/bindings/docker.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +2 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-errors.d.ts +1 -0
- package/dist/src/execution/sandbox/bindings/vercel-errors.js +1 -2
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +0 -5
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/harness/input-requests.d.ts +20 -1
- package/dist/src/harness/input-requests.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/protocol/message.d.ts +11 -2
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/public/next/index.d.ts +1 -7
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/next/vercel-output-config.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +27 -4
- package/dist/src/setup/scaffold/update/channels.js +1 -1
- package/docs/README.md +19 -5
- package/docs/agent-config.md +16 -19
- package/docs/channels/custom.mdx +24 -18
- package/docs/channels/discord.mdx +25 -13
- package/docs/channels/eve.mdx +24 -6
- package/docs/channels/github.mdx +41 -10
- package/docs/channels/linear.mdx +29 -36
- package/docs/channels/overview.mdx +16 -4
- package/docs/channels/slack.mdx +59 -32
- package/docs/channels/teams.mdx +19 -7
- package/docs/channels/telegram.mdx +23 -9
- package/docs/channels/twilio.mdx +28 -6
- package/docs/concepts/context-control.md +24 -41
- package/docs/concepts/default-harness.md +19 -9
- package/docs/concepts/execution-model-and-durability.md +14 -14
- package/docs/concepts/security-model.md +32 -8
- package/docs/concepts/sessions-runs-and-streaming.md +11 -9
- package/docs/connections.mdx +49 -29
- package/docs/evals/assertions.mdx +30 -29
- package/docs/evals/cases.mdx +10 -10
- package/docs/evals/judge.mdx +14 -14
- package/docs/evals/overview.mdx +15 -17
- package/docs/evals/reporters.mdx +19 -7
- package/docs/evals/running.mdx +2 -2
- package/docs/evals/targets.mdx +15 -4
- package/docs/getting-started.mdx +72 -31
- package/docs/guides/auth-and-route-protection.md +18 -12
- package/docs/guides/client/continuations.mdx +5 -13
- package/docs/guides/client/messages.mdx +2 -2
- package/docs/guides/client/output-schema.mdx +2 -2
- package/docs/guides/client/overview.mdx +4 -4
- package/docs/guides/client/streaming.mdx +6 -5
- package/docs/guides/deployment.md +22 -20
- package/docs/guides/dev-tui.md +85 -13
- package/docs/guides/dynamic-capabilities.md +24 -8
- package/docs/guides/dynamic-workflows.md +33 -12
- package/docs/guides/frontend/nextjs.mdx +28 -14
- package/docs/guides/frontend/nuxt.mdx +21 -4
- package/docs/guides/frontend/overview.mdx +11 -11
- package/docs/guides/frontend/sveltekit.mdx +20 -3
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +106 -14
- package/docs/guides/frontend/use-eve-agent-vue.mdx +108 -15
- package/docs/guides/hooks.md +14 -60
- package/docs/guides/instrumentation.md +24 -18
- package/docs/guides/remote-agents.md +19 -15
- package/docs/guides/session-context.md +12 -12
- package/docs/guides/state.md +25 -9
- package/docs/instructions.mdx +18 -10
- package/docs/{introduction.md → introduction.mdx} +14 -12
- package/docs/reference/cli.md +99 -53
- package/docs/reference/meta.json +1 -1
- package/docs/reference/project-layout.md +39 -32
- package/docs/reference/typescript-api.md +1 -1
- package/docs/responsible-use.md +14 -0
- package/docs/sandbox.mdx +25 -19
- package/docs/schedules.mdx +16 -14
- package/docs/skills.mdx +8 -6
- package/docs/subagents.mdx +39 -13
- package/docs/tools.mdx +13 -9
- package/docs/tutorial/connect-a-warehouse.mdx +16 -7
- package/docs/tutorial/first-agent.mdx +21 -11
- package/docs/tutorial/guard-the-spend.mdx +11 -9
- package/docs/tutorial/how-it-runs.mdx +10 -8
- package/docs/tutorial/query-sample-data.mdx +8 -8
- package/docs/tutorial/remember-definitions.mdx +5 -5
- package/docs/tutorial/run-analysis.mdx +13 -11
- package/docs/tutorial/ship-it.mdx +70 -14
- package/docs/tutorial/team-playbooks.mdx +33 -10
- package/package.json +1 -1
package/docs/guides/dev-tui.md
CHANGED
|
@@ -1,44 +1,116 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Dev TUI"
|
|
3
|
-
description: "Drive an Eve agent locally in an interactive terminal UI
|
|
3
|
+
description: "Drive an Eve agent locally in an interactive terminal UI. Chat, stream, approve tools, answer questions, tune the display, and point it at a deployment."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
`eve dev` boots the local runtime and drops you into an interactive terminal UI. You chat with the agent, watch it stream, approve its tool calls, and answer the questions it asks back
|
|
6
|
+
`eve dev` boots the local runtime and drops you into an interactive terminal UI. You chat with the agent, watch it stream, approve its tool calls, and answer the questions it asks back.
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
9
|
eve dev
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
On startup the TUI prints a brand line with your agent's name, plus a rotating tip (local sessions only)
|
|
12
|
+
On startup the TUI prints a brand line with your agent's name, plus a rotating tip (local sessions only).
|
|
13
13
|
|
|
14
14
|
```text
|
|
15
15
|
eve weather-agent
|
|
16
16
|
Use /channels to add more ways to reach your agent.
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
If agent discovery reported problems, an error
|
|
19
|
+
If agent discovery reported problems, an error and warning count renders between the two lines. Instructions, tools, skills, and subagents are one `eve info` away, and `/help` lists every command. The TUI also runs a startup check. A missing model-provider setup surfaces as an attention line (`⚠ 1 setup issue: model provider not linked · /model`) so the fix is visible before the first message fails, with each command's outcome hanging under it on a `⎿` connector.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
## Reading the transcript
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
The conversation streams straight into your terminal's normal scrollback, so you keep native scrolling, copy and paste, and a transcript that persists after you exit. The scrollback holds your prompts, the agent's replies, reasoning, tool calls, nested subagents, connection-authorization prompts, and any captured `stdout`, `stderr`, or sandbox lifecycle lines.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Each turn renders without boxes. A colored gutter glyph marks who is speaking, tool calls collapse to a one-line summary (`✓ get_weather city="SF" → 73°F`), and a subagent's work is indented beneath its `◆` header. When input is ready, the prompt stays bare until you type. While a turn or setup action owns the terminal, only its live status shows.
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
A persistent line beneath the prompt or status shows the model, the session's token flow (`↑ 394.4K ↓ 4.3K`), the linked Vercel project and team (`▲ my-agent (acme)`), and a yellow `/deploy pending` marker once a channel added this session still needs `/deploy`. The Vercel segment stays hidden until the directory is linked.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Errors render compactly with docs links highlighted. A code bug escaping your agent's own code shows its stack trace dim beneath the error headline. Dev-server rebuilds condense into one status row that updates in place (`tui/setup-panel.ts changed · rebuilding…`, then `· rebuilt`); only the latest rebuild shows, and paths shrink to their last two components.
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
## Slash commands
|
|
32
|
+
|
|
33
|
+
Each command echoes as an invocation line, asks through a bordered panel that takes the input area's place (one question at a time, separate from the chat transcript), and finishes with a one-line `⎿` result. Loading states stay on the ephemeral status line instead of piling into the transcript.
|
|
34
|
+
|
|
35
|
+
| Command | Does |
|
|
36
|
+
| ----------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
37
|
+
| `/model` | Opens a configure menu that loops until Done (or Esc). See [Configure the model and provider](#configure-the-model-and-provider). |
|
|
38
|
+
| `/channels` | Shows the agent's channel list and adds the one you pick. See [Add a channel](#add-a-channel). |
|
|
39
|
+
| `/deploy` | Ships the agent to Vercel production, linking the directory first when it is unlinked. |
|
|
40
|
+
| `/loglevel` | Switches which logs the transcript shows. See [Control what logs show](#control-what-logs-show). |
|
|
41
|
+
| `/new` | Starts a fresh session. |
|
|
42
|
+
| `/exit` | Quits the TUI. |
|
|
43
|
+
| `/help` | Lists every command. |
|
|
44
|
+
|
|
45
|
+
`/model`, `/channels`, and `/deploy` manage the project and are available only when `eve dev` runs the server locally, not when connected to a remote server with `--url`.
|
|
46
|
+
|
|
47
|
+
### Configure the model and provider
|
|
48
|
+
|
|
49
|
+
Bare `/model` opens the configure menu. "Change model" runs the same searchable model picker setup uses (the Vercel AI Gateway catalog, pre-selected on the model the runtime is serving). A model change is written into your agent's authored source, and the command reports success only after Eve confirms the new id. `/model <provider/model-id>` applies one directly, skipping the menu.
|
|
50
|
+
|
|
51
|
+
The provider row opens the provider questions: which model provider to use, and how to connect. Picking something other than Vercel AI Gateway shows wiring instructions for your own provider and stops there, leaving any existing setup untouched. For Vercel AI Gateway, you either paste your own `AI_GATEWAY_API_KEY` (saved straight to `.env.local`) or connect via a project. Connecting via a project asks for a Vercel team, opens that team's existing-project list (picking again re-links), then pulls the project's environment so an AI Gateway credential lands in `.env.local`. The dev server reloads env files automatically, with no restart needed.
|
|
52
|
+
|
|
53
|
+
The provider row demands attention (a bold yellow "Configure provider" with "Required to enable the agent") until a link or gateway credential is detected, then names the connection afterward (for example "AI Gateway (Linked to my-project in my-team)"). Each action's latest outcome stays visible beneath the menu (for example "✓ Model changed to openai/gpt-5.5"). When a turn fails because AI Gateway authentication is missing or stale, the error points you at `/model` directly.
|
|
54
|
+
|
|
55
|
+
### Add a channel
|
|
56
|
+
|
|
57
|
+
`/channels` shows the agent's channel list. Already-registered channels render as checked, focusable rows with an "Already installed" hint. Picking one adds it (including the Slack Connect provisioning), then installs the dependencies the scaffold added so the dev server can load the new channels right away. After each addition the list repaints with the channel checked, until Done (or Esc) leaves the flow.
|
|
58
|
+
|
|
59
|
+
## Keyboard shortcuts
|
|
60
|
+
|
|
61
|
+
The prompt input behaves like a shell line editor.
|
|
62
|
+
|
|
63
|
+
| Key | Action |
|
|
64
|
+
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
65
|
+
| `Enter` | Send the message. |
|
|
66
|
+
| `Ctrl+C` | Interrupt a running turn, or quit at the prompt. |
|
|
67
|
+
| `↑` / `↓` | Cycle through the messages you have sent this session. |
|
|
68
|
+
| `←` / `→`, `Home` / `End`, `Ctrl+A` / `Ctrl+E` | Move the caret. |
|
|
69
|
+
| `Ctrl+U` / `Ctrl+K` / `Ctrl+W` | Kill the whole line, the rest of the line, or the previous word. |
|
|
70
|
+
| `Ctrl+L` | Cycle the log display mode (`none → all → stderr → sandbox → none`) and briefly show the mode in the status line. |
|
|
71
|
+
| `Ctrl+R` | Redraw the screen. |
|
|
72
|
+
|
|
73
|
+
If a turn fails terminally (the server session dies or the connection drops), the TUI starts a fresh session and notes it inline so you can keep going. Server-side context resets with the old session.
|
|
74
|
+
|
|
75
|
+
## Answer the agent inline
|
|
76
|
+
|
|
77
|
+
When the agent needs something from you, the TUI asks inline.
|
|
78
|
+
|
|
79
|
+
- Tool approvals are a `y` or `n`.
|
|
80
|
+
- Option questions let you pick with `↑` / `↓` and `Enter`, or you can type a freeform answer.
|
|
81
|
+
- If a tool needs an authorized [connection](../connections), the URL shows up right in the transcript, and the turn picks back up once you finish the flow.
|
|
82
|
+
|
|
83
|
+
## Control what logs show
|
|
84
|
+
|
|
85
|
+
By default, `eve dev` shows `stderr` and keeps stdout and sandbox lines buffered but hidden. Captured server `stdout` and `stderr` render as dim, indented log runs behind a `│` rule (consecutive lines from the same source share one label), while sandbox lifecycle lines use their own label.
|
|
86
|
+
|
|
87
|
+
- `/loglevel <all|stderr|sandbox|none>` switches what the transcript shows, retroactively. Bare `/loglevel` reports the current mode.
|
|
88
|
+
- `--logs <all|stderr|sandbox|none>` sets the starting mode at launch (default `stderr`).
|
|
89
|
+
- `Ctrl+L` at the idle prompt cycles `none → all → stderr → sandbox → none`.
|
|
90
|
+
|
|
91
|
+
## Display flags
|
|
92
|
+
|
|
93
|
+
Density flags control how much of each section renders. They accept `full`, `collapsed`, `auto-collapsed`, or `hidden`.
|
|
32
94
|
|
|
33
95
|
```bash
|
|
34
96
|
eve dev --tools full --assistant-response-stats tokens --context-size 200000
|
|
35
97
|
```
|
|
36
98
|
|
|
37
|
-
|
|
99
|
+
| Flag | Values | Effect |
|
|
100
|
+
| ----------------------------------- | -------------------------------------------------- | ------------------------------------------------------- |
|
|
101
|
+
| `--tools <mode>` | `full` / `collapsed` / `auto-collapsed` / `hidden` | How tool calls render (default `auto-collapsed`). |
|
|
102
|
+
| `--reasoning <mode>` | `full` / `collapsed` / `auto-collapsed` / `hidden` | How reasoning renders (default `full`). |
|
|
103
|
+
| `--subagents <mode>` | `full` / `collapsed` / `auto-collapsed` / `hidden` | How subagent sections render. |
|
|
104
|
+
| `--connection-auth <mode>` | `full` / `collapsed` / `auto-collapsed` / `hidden` | How connection authorization renders. |
|
|
105
|
+
| `--assistant-response-stats <mode>` | `tokens` / `tokensPerSecond` | Which statistic the assistant header shows. |
|
|
106
|
+
| `--context-size <tokens>` | a token count | Model context window size, shown as a usage percentage. |
|
|
107
|
+
| `--logs <mode>` | `all` / `stderr` / `sandbox` / `none` | Which server and agent logs to show (default `stderr`). |
|
|
108
|
+
|
|
109
|
+
Connection flags: `--host` and `--port` bind the local server, and `--no-ui` runs headless (also the automatic fallback when stdout is not a TTY). See the [CLI](../reference/cli) for the full flag list.
|
|
38
110
|
|
|
39
111
|
## Remote: `eve dev <url>`
|
|
40
112
|
|
|
41
|
-
Pass a URL and the TUI talks to a running deployment instead of
|
|
113
|
+
Pass a URL and the TUI talks to a running deployment instead of starting a local server, which is handy for a Vercel preview or your production app.
|
|
42
114
|
|
|
43
115
|
```bash
|
|
44
116
|
eve dev https://<your-app>
|
|
@@ -48,5 +120,5 @@ The bare URL is shorthand for `--url`. `--host`, `--port`, and `--no-ui` are ign
|
|
|
48
120
|
|
|
49
121
|
## What to read next
|
|
50
122
|
|
|
51
|
-
- [
|
|
123
|
+
- [Observability](./instrumentation): OpenTelemetry, run tags, and common failures.
|
|
52
124
|
- [CLI](../reference/cli): every command and flag.
|
|
@@ -3,13 +3,13 @@ title: "Dynamic Capabilities"
|
|
|
3
3
|
description: "Resolve tools, skills, and instructions at runtime with defineDynamic: the resolver events, execution order, and how dynamic tools survive step boundaries."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
`defineDynamic` resolves tools, skills, and instructions at runtime from a session event instead of declaring them up front. Reach for it when the right capabilities aren't known until the session starts, because they hinge on who the caller is, what tenant they belong to, feature flags, or external data. The [tools](../tools), [skills](../skills), and [instructions](../instructions) guides each point here for their dynamic form.
|
|
7
7
|
|
|
8
8
|
## Dynamic tools
|
|
9
9
|
|
|
10
10
|
Pass `defineDynamic` an `events` object whose handlers return either a single `defineTool(...)`, a `Record<string, defineTool(...)>`, or `null` for no tools. Wrap every entry in `defineTool()`. The wrapper stamps them so their `execute` functions survive workflow step boundaries.
|
|
11
11
|
|
|
12
|
-
The example below builds one tool per warehouse table. A map return names tools `slug__key`, so the model sees `query__orders`, `query__users`, and so on
|
|
12
|
+
The example below builds one tool per warehouse table. A map return names tools `slug__key`, so the model sees `query__orders`, `query__users`, and so on.
|
|
13
13
|
|
|
14
14
|
```ts title="agent/tools/query.ts"
|
|
15
15
|
import { defineDynamic, defineTool } from "eve/tools";
|
|
@@ -33,6 +33,10 @@ export default defineDynamic({
|
|
|
33
33
|
});
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
### `execute` must be an inline function
|
|
37
|
+
|
|
38
|
+
Write `execute` as an inline function expression, arrow, or method shorthand placed directly as the property value. The bundler transform does not detect `execute: myFn` or `execute: makeFn()`, so those tools work on the first step but do not survive replay (re-running a step after a crash or resume; see [Execution model & durability](../concepts/execution-model-and-durability)). On later steps the transform reconstructs each `execute` from its stored closure variables instead of re-running the resolver, which is why it has to be inline.
|
|
39
|
+
|
|
36
40
|
### Naming
|
|
37
41
|
|
|
38
42
|
| Return shape | File | Tool name(s) |
|
|
@@ -51,33 +55,45 @@ A single return produces one tool named after the file slug, identical to a stat
|
|
|
51
55
|
| `turn.started` | Once per turn | Every model call in the turn |
|
|
52
56
|
| `step.started` | Before each model call | That model call |
|
|
53
57
|
|
|
54
|
-
**Limitation.** `execute` must be an inline function (function expression, arrow, or method shorthand written directly as the property value). `execute: myFn` or `execute: makeFn()` is not detected by the transform, so the tool works on the first step but won't survive replay.
|
|
55
|
-
|
|
56
58
|
### Execution order
|
|
57
59
|
|
|
58
|
-
When a stream event fires, three things happen in order
|
|
60
|
+
When a stream event fires, three things happen in order.
|
|
61
|
+
|
|
62
|
+
1. The channel adapter handler runs and the event is written to the durable stream.
|
|
63
|
+
2. Stream-event [hooks](./hooks) fire.
|
|
64
|
+
3. Dynamic tool resolvers subscribed to that event run and update the tool set.
|
|
65
|
+
|
|
66
|
+
The tool loop reads the current set right before each model call, so a mid-turn update is visible on the next call.
|
|
59
67
|
|
|
60
68
|
A single file can declare handlers for several events, and the most recently fired one owns that file's tool set. Re-resolve on `turn.started` to replace what `session.started` returned:
|
|
61
69
|
|
|
62
70
|
```ts title="agent/tools/catalog.ts"
|
|
71
|
+
import { defineDynamic, defineTool } from "eve/tools";
|
|
72
|
+
import { z } from "zod";
|
|
73
|
+
import { runReadOnly, searchCatalog } from "../lib/catalog.js";
|
|
74
|
+
|
|
63
75
|
export default defineDynamic({
|
|
64
76
|
events: {
|
|
65
77
|
"session.started": async (_event, ctx) => ({
|
|
66
78
|
query: defineTool({
|
|
67
|
-
|
|
79
|
+
description: "Run a read-only query.",
|
|
80
|
+
inputSchema: z.object({ sql: z.string() }),
|
|
81
|
+
execute: ({ sql }) => runReadOnly(sql),
|
|
68
82
|
}),
|
|
69
83
|
}),
|
|
70
84
|
// On each turn, re-resolve. Replaces this file's session.started tools for later calls.
|
|
71
85
|
"turn.started": async (_event, ctx) => ({
|
|
72
86
|
search: defineTool({
|
|
73
|
-
|
|
87
|
+
description: "Search the catalog.",
|
|
88
|
+
inputSchema: z.object({ term: z.string() }),
|
|
89
|
+
execute: ({ term }) => searchCatalog(term),
|
|
74
90
|
}),
|
|
75
91
|
}),
|
|
76
92
|
},
|
|
77
93
|
});
|
|
78
94
|
```
|
|
79
95
|
|
|
80
|
-
Resolvers across files run concurrently.
|
|
96
|
+
Resolvers across files run concurrently.
|
|
81
97
|
|
|
82
98
|
## Dynamic skills
|
|
83
99
|
|
|
@@ -3,11 +3,11 @@ title: "Dynamic Workflows"
|
|
|
3
3
|
description: "The experimental Workflow tool: let the model orchestrate its own subagents from model-authored JavaScript as one durable step."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
The experimental `Workflow` tool lets the model write JavaScript that coordinates the agent's own subagents as a single durable step
|
|
6
|
+
The experimental `Workflow` tool lets the model write JavaScript that coordinates the agent's own subagents as a single durable step. The program can run them in sequence, feed one result into the next, fan out over a list, and combine the results. You enable the capability and the model decides and runs the orchestration. It is the agents-only slice of [code mode](../agent-config#other-defineagent-fields) (the broader `codeMode` flag that routes all of an agent's tools through model-authored JavaScript).
|
|
7
7
|
|
|
8
|
-
A single turn can already call several subagents, and parallel tool calls dispatch concurrently. What a workflow adds is _programmatic_ coordination
|
|
8
|
+
A single turn can already call several subagents, and parallel tool calls dispatch concurrently. What a workflow adds is _programmatic_ coordination. The program decides how many subagents to run based on an earlier result, which output feeds which call, and how to combine everything. That is logic the model cannot express as a few one-off calls.
|
|
9
9
|
|
|
10
|
-
## Enable
|
|
10
|
+
## Enable the Workflow tool
|
|
11
11
|
|
|
12
12
|
Re-export the opt-in marker as the default export of `agent/tools/workflow.ts`. The marker name carries the "experimental" warning, but the tool the model actually sees is named `Workflow`.
|
|
13
13
|
|
|
@@ -26,27 +26,48 @@ export default defineAgent({
|
|
|
26
26
|
});
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
When asked for a weekly business review, the model picks the metrics, runs one `analyst` per metric in parallel, and combines the findings. The program below is the kind of JavaScript the model authors. It fans `analyst` out over a runtime-decided list of metrics and merges the results:
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
```js
|
|
32
|
+
const metrics = ["revenue", "signups", "churn"];
|
|
33
|
+
const findings = await Promise.all(
|
|
34
|
+
metrics.map((metric) => tools.analyst({ message: `Summarize last week's ${metric}.` })),
|
|
35
|
+
);
|
|
36
|
+
return findings.join("\n\n");
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Each `tools.analyst(...)` call dispatches a child subagent, so the parent stream records one `subagent.called` per metric and one `subagent.completed` as each finishes:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{ "type": "subagent.called", "data": { "name": "analyst", "toolName": "analyst", "callId": "call_1", "childSessionId": "ses_a1", "sequence": 0 } }
|
|
43
|
+
{ "type": "subagent.called", "data": { "name": "analyst", "toolName": "analyst", "callId": "call_2", "childSessionId": "ses_a2", "sequence": 1 } }
|
|
44
|
+
{ "type": "subagent.called", "data": { "name": "analyst", "toolName": "analyst", "callId": "call_3", "childSessionId": "ses_a3", "sequence": 2 } }
|
|
45
|
+
{ "type": "subagent.completed", "data": { "subagentName": "analyst", "callId": "call_1", "output": "..." } }
|
|
46
|
+
{ "type": "subagent.completed", "data": { "subagentName": "analyst", "callId": "call_2", "output": "..." } }
|
|
47
|
+
{ "type": "subagent.completed", "data": { "subagentName": "analyst", "callId": "call_3", "output": "..." } }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## What a workflow can orchestrate
|
|
32
51
|
|
|
33
|
-
A workflow reaches only this agent's own agents: the built-in `agent` (a copy of itself), declared [subagents](../subagents), and [remote agents](./remote-agents). That
|
|
52
|
+
A workflow reaches only this agent's own agents: the built-in `agent` (a copy of itself), declared [subagents](../subagents), and [remote agents](./remote-agents). That is the whole list. No files, network, shell, skills, or connections. A workflow is a coordination layer over subagents, not a place to do other work. Each call can still request structured output via `outputSchema`, exactly like a direct subagent delegation.
|
|
34
53
|
|
|
35
54
|
## Where the JavaScript runs
|
|
36
55
|
|
|
37
|
-
The orchestration code never touches the agent's process. The runtime hands the program text to a small isolated JavaScript engine (a QuickJS sandbox) and runs it there. Nothing from the host realm crosses in
|
|
56
|
+
The orchestration code never touches the agent's process. The runtime hands the program text to a small isolated JavaScript engine (a QuickJS sandbox) and runs it there. Nothing from the host realm crosses in, so there is no `process`, no `globalThis` from the agent, and no `import`/`require`. The program can reach exactly two things, the agent functions bridged in as `tools.<name>` and the ordinary language built-ins.
|
|
38
57
|
|
|
39
|
-
That
|
|
58
|
+
That is an allowlist, not a denylist. The sandbox cannot read files, open a socket, or see an environment variable because those are not present, not because each one is blocked in turn. When the program calls an agent function, that call bridges back out to the runtime, which dispatches it exactly like a direct delegation. The orchestration glue stays inside the sandbox.
|
|
40
59
|
|
|
41
|
-
##
|
|
60
|
+
## Durability, approvals, and observability
|
|
42
61
|
|
|
43
|
-
- **Durable.** The whole orchestration counts as one step. Subagents dispatched together run concurrently, and if a run parks on a long-running or human-gated child, it resumes where it left off after a restart.
|
|
44
|
-
- **
|
|
62
|
+
- **Durable.** The whole orchestration counts as one step. Subagents dispatched together run concurrently, and if a run parks (suspends durably without holding compute; see [Execution model & durability](../concepts/execution-model-and-durability)) on a long-running or human-gated child, it resumes where it left off after a restart.
|
|
63
|
+
- **Approval-safe.** A subagent that needs human approval (HITL, human-in-the-loop) mid-run surfaces its request to the user, and the workflow picks back up once that is answered, same as direct delegation.
|
|
45
64
|
- **Observable.** Every orchestrated subagent emits the usual `subagent.called` / `subagent.completed` events on the parent stream and gets its own child session and stream. The telemetry matches direct delegation, so existing dashboards and cost attribution keep working.
|
|
46
65
|
|
|
47
66
|
## Relationship to code mode
|
|
48
67
|
|
|
49
|
-
Code mode is the broader version
|
|
68
|
+
[Code mode](../agent-config#other-defineagent-fields) is the broader version, where the model drives _all_ of an agent's tools (files, shell, web, and agents) from JavaScript. A workflow covers only the subagents. The two do not interfere. Enabling the `Workflow` tool leaves code mode untouched, and an agent can run both at once.
|
|
69
|
+
|
|
70
|
+
`codeMode` is experimental and may change or be removed.
|
|
50
71
|
|
|
51
72
|
## What to read next
|
|
52
73
|
|
|
@@ -3,7 +3,13 @@ title: "Next.js"
|
|
|
3
3
|
description: "Run an Eve agent and a Next.js app as one project with withEve."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
`eve/next`
|
|
6
|
+
`eve/next` ships a Next.js frontend and an Eve agent as a single project. Wrap your config with `withEve()` to run both from one dev server and one Vercel deploy. [`useEveAgent`](./overview) finds the mounted routes on its own, so there's no CORS to configure and no URL env vars to keep in sync.
|
|
7
|
+
|
|
8
|
+
## Prerequisites
|
|
9
|
+
|
|
10
|
+
- The `eve` package installed in your project (`npm install eve@latest`).
|
|
11
|
+
- An existing Eve agent directory. If you don't have one, start from [Getting started](../../getting-started).
|
|
12
|
+
- A Next.js app to mount the agent in.
|
|
7
13
|
|
|
8
14
|
## Wrap the Next.js config
|
|
9
15
|
|
|
@@ -16,7 +22,7 @@ const nextConfig: NextConfig = {};
|
|
|
16
22
|
export default withEve(nextConfig);
|
|
17
23
|
```
|
|
18
24
|
|
|
19
|
-
By default `withEve()` looks for an `agent/` folder
|
|
25
|
+
By default `withEve()` looks for an `agent/` folder inside your Next.js project root. If the agent lives somewhere else, point at it with `eveRoot`:
|
|
20
26
|
|
|
21
27
|
```ts
|
|
22
28
|
export default withEve(nextConfig, {
|
|
@@ -28,15 +34,14 @@ export default withEve(nextConfig, {
|
|
|
28
34
|
|
|
29
35
|
All fields are optional.
|
|
30
36
|
|
|
31
|
-
| Option
|
|
32
|
-
|
|
|
33
|
-
| `eveRoot`
|
|
34
|
-
| `eveBuildCommand`
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `devServerTimeoutMs` | `number` | `180000` | Maximum time to wait for the Eve development server to become available. |
|
|
37
|
+
| Option | Type | Default | Purpose |
|
|
38
|
+
| -------------------- | -------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
|
+
| `eveRoot` | `string` | Next.js app root | Path to the Eve app root, relative to `process.cwd()` unless absolute. Set it when the agent lives outside the Next.js project. |
|
|
40
|
+
| `eveBuildCommand` | `string` | `"eve build"` | Build command for the generated Eve Vercel service. Use it when the Eve service needs project-specific prework, without changing the Next.js build. |
|
|
41
|
+
| `servicePrefix` | `string` | `"/_eve_internal/eve"` | Private Vercel route namespace for the Eve service. Must match the Eve service's mount in your Vercel Build Output config when you set it manually. |
|
|
42
|
+
| `devServerTimeoutMs` | `number` | `180000` | Maximum time to wait for the Eve development server to become available. |
|
|
38
43
|
|
|
39
|
-
For
|
|
44
|
+
For slow cold starts, increase the development timeout:
|
|
40
45
|
|
|
41
46
|
```ts
|
|
42
47
|
export default withEve(nextConfig, {
|
|
@@ -46,7 +51,7 @@ export default withEve(nextConfig, {
|
|
|
46
51
|
|
|
47
52
|
## Call the hook
|
|
48
53
|
|
|
49
|
-
With `withEve()` in `next.config.ts`, the Eve routes are same-origin, so client code can call [`useEveAgent`](./overview) without naming a host. Cookie-based auth
|
|
54
|
+
With `withEve()` in `next.config.ts`, the Eve routes are same-origin, so client code can call [`useEveAgent`](./overview) without naming a host. Cookie-based auth (Auth.js or any session cookie) needs no extra wiring, since the browser already sends those cookies on every Eve request. For non-cookie schemes, attach the credentials yourself:
|
|
50
55
|
|
|
51
56
|
```tsx
|
|
52
57
|
const agent = useEveAgent({
|
|
@@ -56,7 +61,16 @@ const agent = useEveAgent({
|
|
|
56
61
|
});
|
|
57
62
|
```
|
|
58
63
|
|
|
59
|
-
|
|
64
|
+
The default Eve channel is fail-closed. With no `agent/channels/eve.ts` authored, Eve registers `eveChannel({ auth: [localDev(), vercelOidc()] })`: `localDev()` opens the routes on localhost, `vercelOidc()` admits Vercel OIDC callers in production, and everything else gets a `401`. To run your app's own auth policy, add `agent/channels/eve.ts`:
|
|
65
|
+
|
|
66
|
+
```ts title="agent/channels/eve.ts"
|
|
67
|
+
import { eveChannel } from "eve/channels/eve";
|
|
68
|
+
import { localDev, vercelOidc } from "eve/channels/auth";
|
|
69
|
+
|
|
70
|
+
export default eveChannel({ auth: [localDev(), vercelOidc()] });
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
For a public demo, use `none()` (also from `eve/channels/auth`) to skip authentication. See [Channels](../../channels/overview) and [Auth & route protection](../auth-and-route-protection).
|
|
60
74
|
|
|
61
75
|
## Dev vs deploy topology
|
|
62
76
|
|
|
@@ -69,13 +83,13 @@ Before deploying a user-facing app, add `agent/channels/eve.ts` so production re
|
|
|
69
83
|
});
|
|
70
84
|
```
|
|
71
85
|
|
|
72
|
-
- **Local production build.** `next build && next start` proxies Eve routes to `
|
|
86
|
+
- **Local production build.** `next build && next start` serves the Eve runtime from its built `.output/server/index.mjs` on a stable local port (`4274`) and proxies the Eve routes to it. Run `eve build` first so that output exists. Change the port with `EVE_NEXT_PRODUCTION_PORT`:
|
|
73
87
|
|
|
74
88
|
```bash
|
|
75
89
|
EVE_NEXT_PRODUCTION_PORT=5000 npm run build && npm start
|
|
76
90
|
```
|
|
77
91
|
|
|
78
|
-
- **Non-Vercel hosts.**
|
|
92
|
+
- **Non-Vercel hosts.** When the Eve service lives on a separate origin, tell Next.js where to find it with `EVE_NEXT_PRODUCTION_ORIGIN`:
|
|
79
93
|
|
|
80
94
|
```bash
|
|
81
95
|
EVE_NEXT_PRODUCTION_ORIGIN=https://agent.example.com npm run build
|
|
@@ -3,7 +3,13 @@ title: "Nuxt"
|
|
|
3
3
|
description: "Run an Eve agent and a Nuxt app as one project with the eve/nuxt module."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
The `eve/nuxt` module
|
|
6
|
+
The `eve/nuxt` module runs a Nuxt frontend and an Eve agent as a single project from one dev server and one Vercel deploy. The auto-imported [`useEveAgent`](./use-eve-agent-vue) composable finds the mounted routes on its own, so there's no CORS to configure and no URL env vars to keep in sync.
|
|
7
|
+
|
|
8
|
+
## Prerequisites
|
|
9
|
+
|
|
10
|
+
- The `eve` package installed in your project (`npm install eve@latest`).
|
|
11
|
+
- An existing Eve agent directory. If you don't have one, start from [Getting started](../../getting-started).
|
|
12
|
+
- A Nuxt app to mount the agent in.
|
|
7
13
|
|
|
8
14
|
## Register the module
|
|
9
15
|
|
|
@@ -24,9 +30,11 @@ export default defineNuxtConfig({
|
|
|
24
30
|
});
|
|
25
31
|
```
|
|
26
32
|
|
|
33
|
+
The `eve` key accepts only two options, `eveRoot` and `eveBuildCommand`.
|
|
34
|
+
|
|
27
35
|
## Call the composable
|
|
28
36
|
|
|
29
|
-
`useEveAgent` (`eve/vue`) is auto-imported, so a component
|
|
37
|
+
`useEveAgent` (`eve/vue`) is auto-imported, so a component calls it without an explicit import and without naming a host:
|
|
30
38
|
|
|
31
39
|
```vue
|
|
32
40
|
<script setup lang="ts">
|
|
@@ -52,7 +60,16 @@ async function handleSubmit() {
|
|
|
52
60
|
</template>
|
|
53
61
|
```
|
|
54
62
|
|
|
55
|
-
|
|
63
|
+
The default Eve channel is fail-closed. With no `agent/channels/eve.ts` authored, Eve registers `eveChannel({ auth: [localDev(), vercelOidc()] })`: `localDev()` opens the routes on localhost, `vercelOidc()` admits Vercel OIDC callers in production, and everything else gets a `401`. To run your own auth policy, add `agent/channels/eve.ts`:
|
|
64
|
+
|
|
65
|
+
```ts title="agent/channels/eve.ts"
|
|
66
|
+
import { eveChannel } from "eve/channels/eve";
|
|
67
|
+
import { localDev, vercelOidc } from "eve/channels/auth";
|
|
68
|
+
|
|
69
|
+
export default eveChannel({ auth: [localDev(), vercelOidc()] });
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
For a public demo, use `none()` (also from `eve/channels/auth`) to skip authentication. See [Channels](../../channels/overview) and [Auth & route protection](../auth-and-route-protection).
|
|
56
73
|
|
|
57
74
|
## Dev vs deploy topology
|
|
58
75
|
|
|
@@ -68,7 +85,7 @@ Out of the box the module gives Eve a framework default channel. When you want t
|
|
|
68
85
|
});
|
|
69
86
|
```
|
|
70
87
|
|
|
71
|
-
- **Non-Vercel hosts.** Point Nuxt at a separate Eve origin with `EVE_NUXT_PRODUCTION_ORIGIN`. To override the local port (
|
|
88
|
+
- **Non-Vercel hosts.** Point Nuxt at a separate Eve origin with `EVE_NUXT_PRODUCTION_ORIGIN`. To override the local port (default `4274`), use `EVE_NUXT_PRODUCTION_PORT`:
|
|
72
89
|
|
|
73
90
|
```bash
|
|
74
91
|
EVE_NUXT_PRODUCTION_ORIGIN=https://agent.example.com npm run build
|
|
@@ -3,22 +3,22 @@ title: "Overview"
|
|
|
3
3
|
description: "Put an Eve agent behind a browser chat UI with useEveAgent."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
The frontend helpers put a browser chat or agent UI on top of an Eve agent. `useEveAgent()`
|
|
6
|
+
The frontend helpers put a browser chat or agent UI on top of an Eve agent. `useEveAgent()` opens a durable session, sends turns, streams the reply back, and turns the raw event stream into render-ready state. React is the reference implementation; [Vue](./use-eve-agent-vue) and [Svelte](./use-eve-agent-svelte) ship the same surface.
|
|
7
7
|
|
|
8
8
|
## The integration model
|
|
9
9
|
|
|
10
|
-
A browser UI is
|
|
10
|
+
A browser UI is a client of the agent's HTTP routes (the [Eve channel](../../channels/overview)). Two layers wire it up:
|
|
11
11
|
|
|
12
12
|
- **The framework integration** mounts the Eve routes on your app's origin, so the browser never crosses a CORS boundary or reads an env var to find the agent. Pick yours: [Next.js](./nextjs) (`withEve`), [Nuxt](./nuxt) (the `eve/nuxt` module), or [SvelteKit](./sveltekit) (the `eveSvelteKit` Vite plugin). On any other stack the hook talks to same-origin `/eve/v1/*` routes directly, or you pass an explicit `host`.
|
|
13
13
|
- **The hook** (`useEveAgent`) holds the session state, streaming, errors, and composer status. It defaults to same-origin Eve routes such as `/eve/v1/session`.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
The per-framework pages below walk through the wiring step by step: [Next.js](./nextjs), [Nuxt](./nuxt), and [SvelteKit](./sveltekit).
|
|
16
16
|
|
|
17
17
|
For scripts, server-to-server calls, evals, tests, or custom clients that do not need framework UI state, use the [TypeScript SDK](../client/overview) directly.
|
|
18
18
|
|
|
19
19
|
## Basic chat (React)
|
|
20
20
|
|
|
21
|
-
The hook lives in `eve/react`. Render `data.messages`, gate the composer on `status`, and send text with `send
|
|
21
|
+
The hook lives in `eve/react`. Render `data.messages`, gate the composer on `status`, and send text with `send`:
|
|
22
22
|
|
|
23
23
|
```tsx
|
|
24
24
|
"use client";
|
|
@@ -72,7 +72,7 @@ export function Chat() {
|
|
|
72
72
|
| `stop` | Abort the active request. |
|
|
73
73
|
| `reset` | Clear local events, data, errors, and the local session cursor. |
|
|
74
74
|
|
|
75
|
-
Most chat UIs only need `data.messages` and `status`. Drop down to `events`
|
|
75
|
+
Most chat UIs only need `data.messages` and `status`. Drop down to `events` to render lower-level activity such as tool calls and reasoning deltas that the default reducer doesn't surface.
|
|
76
76
|
|
|
77
77
|
`data.messages` are `EveMessage[]` following the AI SDK `UIMessage` convention, so they drop straight into any AI SDK UI primitive that accepts a `UIMessage[]`. Parts include user text, assistant text, reasoning, tool calls, tool results, and input requests.
|
|
78
78
|
|
|
@@ -96,7 +96,7 @@ await agent.send({
|
|
|
96
96
|
});
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
Assistant text, reasoning, tool calls, and tool results stream into `data` as they arrive, and `status` moves from `ready` to `submitted` to `streaming` and back. Call `stop()` to abort the active request
|
|
99
|
+
Assistant text, reasoning, tool calls, and tool results stream into `data` as they arrive, and `status` moves from `ready` to `submitted` to `streaming` and back. Call `stop()` to abort the active request, and `reset()` to clear local state so the next send starts a fresh durable session.
|
|
100
100
|
|
|
101
101
|
## Human-in-the-loop prompts
|
|
102
102
|
|
|
@@ -115,11 +115,11 @@ if (request) {
|
|
|
115
115
|
}
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
-
`request.prompt` and `request.options` give you what you need to render the approve and deny UI. The default reducer marks the part as responded
|
|
118
|
+
`request.prompt` and `request.options` give you what you need to render the approve and deny UI. The default reducer marks the part as responded immediately, then updates it again once Eve streams the resumed result.
|
|
119
119
|
|
|
120
120
|
## Attach page context per turn
|
|
121
121
|
|
|
122
|
-
`clientContext` adds ephemeral context for the next model call
|
|
122
|
+
`clientContext` adds ephemeral context for the next model call only. Strings (or an array of strings) become user-role context messages; an object is JSON-serialized into one. It rides along with a message or HITL response, so it never dispatches a turn on its own and never lands in durable session history. Pass it directly to `send()`:
|
|
123
123
|
|
|
124
124
|
```tsx
|
|
125
125
|
await agent.send({
|
|
@@ -182,11 +182,11 @@ const agent = useEveAgent({ reducer: toolCounter });
|
|
|
182
182
|
// agent.data is ToolLog
|
|
183
183
|
```
|
|
184
184
|
|
|
185
|
-
`reduce(data, event)` receives both authoritative Eve stream events and client projection events (`client.message.submitted`, `client.message.failed`, `client.input.responded`). Handle the client events too if you want optimistic and HITL state in your projection. Otherwise,
|
|
185
|
+
`reduce(data, event)` receives both authoritative Eve stream events and client projection events (`client.message.submitted`, `client.message.failed`, `client.input.responded`). Handle the client events too if you want optimistic and HITL state in your projection. Otherwise, return `data` unchanged for them.
|
|
186
186
|
|
|
187
187
|
## Resumable sessions
|
|
188
188
|
|
|
189
|
-
The browser conversation lives durably on the server. Persist the `session` cursor
|
|
189
|
+
The browser conversation lives durably on the server. Persist the `session` cursor to pick it back up after a reload:
|
|
190
190
|
|
|
191
191
|
```tsx
|
|
192
192
|
const [initialSession] = useState(() => {
|
|
@@ -231,4 +231,4 @@ const agent = useEveAgent({
|
|
|
231
231
|
- [Sessions, runs & streaming](../../concepts/sessions-runs-and-streaming): the event stream and session cursor
|
|
232
232
|
- [Channels](../../channels/overview): the HTTP routes the hook talks to
|
|
233
233
|
- [TypeScript SDK](../client/overview): the lower-level client underneath the frontend hooks
|
|
234
|
-
- [
|
|
234
|
+
- [Next.js](./nextjs): step-by-step setup for wiring Eve into a Next.js app
|
|
@@ -3,7 +3,13 @@ title: "SvelteKit"
|
|
|
3
3
|
description: "Run an Eve agent and a SvelteKit app as one project with the eveSvelteKit Vite plugin."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
`eve/sveltekit`
|
|
6
|
+
`eve/sveltekit` runs a SvelteKit frontend and an Eve agent as one project instead of two services. The `eveSvelteKit()` Vite plugin puts both on one dev server and one Vercel deploy, and [`useEveAgent`](./use-eve-agent-svelte) finds the mounted routes on its own. There's no CORS to configure and no URL env vars to keep in sync.
|
|
7
|
+
|
|
8
|
+
## Prerequisites
|
|
9
|
+
|
|
10
|
+
- The `eve` package installed in your project (`npm install eve@latest`).
|
|
11
|
+
- An existing Eve agent directory. If you don't have one, start from [Getting started](../../getting-started).
|
|
12
|
+
- A SvelteKit app to mount the agent in.
|
|
7
13
|
|
|
8
14
|
## Register the Vite plugin
|
|
9
15
|
|
|
@@ -32,6 +38,8 @@ export default defineConfig({
|
|
|
32
38
|
});
|
|
33
39
|
```
|
|
34
40
|
|
|
41
|
+
The plugin accepts only two options, `eveRoot` and `eveBuildCommand`.
|
|
42
|
+
|
|
35
43
|
## Call the binding
|
|
36
44
|
|
|
37
45
|
With the plugin in `vite.config.ts`, components call [`useEveAgent`](./use-eve-agent-svelte) from `eve/svelte` and don't pass a host:
|
|
@@ -61,11 +69,20 @@ With the plugin in `vite.config.ts`, components call [`useEveAgent`](./use-eve-a
|
|
|
61
69
|
</form>
|
|
62
70
|
```
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
The default Eve channel is fail-closed. With no `agent/channels/eve.ts` authored, Eve registers `eveChannel({ auth: [localDev(), vercelOidc()] })`: `localDev()` opens the routes on localhost, `vercelOidc()` admits Vercel OIDC callers in production, and everything else gets a `401`. To set your own auth policy, add `agent/channels/eve.ts`:
|
|
73
|
+
|
|
74
|
+
```ts title="agent/channels/eve.ts"
|
|
75
|
+
import { eveChannel } from "eve/channels/eve";
|
|
76
|
+
import { localDev, vercelOidc } from "eve/channels/auth";
|
|
77
|
+
|
|
78
|
+
export default eveChannel({ auth: [localDev(), vercelOidc()] });
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For a public demo, use `none()` (also from `eve/channels/auth`) to skip authentication. See [Channels](../../channels/overview) and [Auth & route protection](../auth-and-route-protection).
|
|
65
82
|
|
|
66
83
|
## Dev vs deploy topology
|
|
67
84
|
|
|
68
|
-
- **Local dev.** `npm run dev` boots the Eve dev server next to SvelteKit and proxies the Eve routes to it, so the browser only ever hits the SvelteKit origin. `npm run build && npm run preview` behaves the same: the preview server gets its own Eve route proxy and either reuses the shared Eve server or starts one.
|
|
85
|
+
- **Local dev.** `npm run dev` boots the Eve dev server next to SvelteKit and proxies the Eve routes to it, so the browser only ever hits the SvelteKit origin. `npm run build && npm run preview` behaves the same way: the preview server gets its own Eve route proxy and either reuses the shared Eve server or starts one.
|
|
69
86
|
- **Vercel.** The SvelteKit app and the Eve runtime deploy as a single project. The web app is public; the Eve runtime sits behind it on the same origin. Use `eveBuildCommand` for a project-specific agent build:
|
|
70
87
|
|
|
71
88
|
```ts
|