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.
Files changed (98) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +14 -0
  3. package/dist/src/cli/banner.d.ts +6 -3
  4. package/dist/src/cli/banner.js +1 -1
  5. package/dist/src/cli/commands/init.js +1 -1
  6. package/dist/src/cli/dev/tui/agent-header.js +1 -1
  7. package/dist/src/cli/run.js +1 -1
  8. package/dist/src/evals/runner/run-evals.d.ts +1 -1
  9. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  10. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
  11. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +2 -1
  12. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
  13. package/dist/src/execution/sandbox/bindings/vercel-errors.d.ts +1 -0
  14. package/dist/src/execution/sandbox/bindings/vercel-errors.js +1 -2
  15. package/dist/src/execution/sandbox/bindings/vercel.d.ts +0 -5
  16. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  17. package/dist/src/harness/input-requests.d.ts +20 -1
  18. package/dist/src/harness/input-requests.js +1 -1
  19. package/dist/src/harness/tool-loop.js +1 -1
  20. package/dist/src/internal/application/package.js +1 -1
  21. package/dist/src/protocol/message.d.ts +11 -2
  22. package/dist/src/protocol/message.js +2 -2
  23. package/dist/src/public/next/index.d.ts +1 -7
  24. package/dist/src/public/next/index.js +1 -1
  25. package/dist/src/public/next/vercel-output-config.js +1 -1
  26. package/dist/src/setup/scaffold/create/project.js +1 -1
  27. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  28. package/dist/src/setup/scaffold/create/web-template.js +27 -4
  29. package/dist/src/setup/scaffold/update/channels.js +1 -1
  30. package/docs/README.md +19 -5
  31. package/docs/agent-config.md +16 -19
  32. package/docs/channels/custom.mdx +24 -18
  33. package/docs/channels/discord.mdx +25 -13
  34. package/docs/channels/eve.mdx +24 -6
  35. package/docs/channels/github.mdx +41 -10
  36. package/docs/channels/linear.mdx +29 -36
  37. package/docs/channels/overview.mdx +16 -4
  38. package/docs/channels/slack.mdx +59 -32
  39. package/docs/channels/teams.mdx +19 -7
  40. package/docs/channels/telegram.mdx +23 -9
  41. package/docs/channels/twilio.mdx +28 -6
  42. package/docs/concepts/context-control.md +24 -41
  43. package/docs/concepts/default-harness.md +19 -9
  44. package/docs/concepts/execution-model-and-durability.md +14 -14
  45. package/docs/concepts/security-model.md +32 -8
  46. package/docs/concepts/sessions-runs-and-streaming.md +11 -9
  47. package/docs/connections.mdx +49 -29
  48. package/docs/evals/assertions.mdx +30 -29
  49. package/docs/evals/cases.mdx +10 -10
  50. package/docs/evals/judge.mdx +14 -14
  51. package/docs/evals/overview.mdx +15 -17
  52. package/docs/evals/reporters.mdx +19 -7
  53. package/docs/evals/running.mdx +2 -2
  54. package/docs/evals/targets.mdx +15 -4
  55. package/docs/getting-started.mdx +72 -31
  56. package/docs/guides/auth-and-route-protection.md +18 -12
  57. package/docs/guides/client/continuations.mdx +5 -13
  58. package/docs/guides/client/messages.mdx +2 -2
  59. package/docs/guides/client/output-schema.mdx +2 -2
  60. package/docs/guides/client/overview.mdx +4 -4
  61. package/docs/guides/client/streaming.mdx +6 -5
  62. package/docs/guides/deployment.md +22 -20
  63. package/docs/guides/dev-tui.md +85 -13
  64. package/docs/guides/dynamic-capabilities.md +24 -8
  65. package/docs/guides/dynamic-workflows.md +33 -12
  66. package/docs/guides/frontend/nextjs.mdx +28 -14
  67. package/docs/guides/frontend/nuxt.mdx +21 -4
  68. package/docs/guides/frontend/overview.mdx +11 -11
  69. package/docs/guides/frontend/sveltekit.mdx +20 -3
  70. package/docs/guides/frontend/use-eve-agent-svelte.mdx +106 -14
  71. package/docs/guides/frontend/use-eve-agent-vue.mdx +108 -15
  72. package/docs/guides/hooks.md +14 -60
  73. package/docs/guides/instrumentation.md +24 -18
  74. package/docs/guides/remote-agents.md +19 -15
  75. package/docs/guides/session-context.md +12 -12
  76. package/docs/guides/state.md +25 -9
  77. package/docs/instructions.mdx +18 -10
  78. package/docs/{introduction.md → introduction.mdx} +14 -12
  79. package/docs/reference/cli.md +99 -53
  80. package/docs/reference/meta.json +1 -1
  81. package/docs/reference/project-layout.md +39 -32
  82. package/docs/reference/typescript-api.md +1 -1
  83. package/docs/responsible-use.md +14 -0
  84. package/docs/sandbox.mdx +25 -19
  85. package/docs/schedules.mdx +16 -14
  86. package/docs/skills.mdx +8 -6
  87. package/docs/subagents.mdx +39 -13
  88. package/docs/tools.mdx +13 -9
  89. package/docs/tutorial/connect-a-warehouse.mdx +16 -7
  90. package/docs/tutorial/first-agent.mdx +21 -11
  91. package/docs/tutorial/guard-the-spend.mdx +11 -9
  92. package/docs/tutorial/how-it-runs.mdx +10 -8
  93. package/docs/tutorial/query-sample-data.mdx +8 -8
  94. package/docs/tutorial/remember-definitions.mdx +5 -5
  95. package/docs/tutorial/run-analysis.mdx +13 -11
  96. package/docs/tutorial/ship-it.mdx +70 -14
  97. package/docs/tutorial/team-playbooks.mdx +33 -10
  98. package/package.json +1 -1
@@ -4,7 +4,7 @@ description: "Reach your agent over SMS and speech-transcribed phone calls with
4
4
  type: integration
5
5
  ---
6
6
 
7
- The Twilio channel puts your agent on a phone number, so people can text it or call it. Inbound SMS arrives as a webhook. Inbound calls get answered with TwiML `<Gather input="speech">`, and the resulting transcript feeds the same Eve session that SMS uses, so a caller and a texter look identical downstream. Every request is checked against `X-Twilio-Signature` before anything else runs. The raw continuation token is `From:To`. See [Channels](./overview) for the contract this builds on.
7
+ The Twilio channel puts your agent on a phone number, so people can text it or call it. Inbound SMS arrives as a webhook. Inbound calls are answered with TwiML `<Gather input="speech">`, and the resulting transcript feeds the same Eve session that SMS uses, so a caller and a texter look identical downstream. Every request is checked against `X-Twilio-Signature` before anything else runs. The raw continuation token is `From:To`. See [Channels](./overview) for the contract this builds on.
8
8
 
9
9
  ## Add the channel
10
10
 
@@ -22,7 +22,7 @@ TWILIO_ACCOUNT_SID=AC... # required for default outbound SMS
22
22
  TWILIO_AUTH_TOKEN=... # required for inbound signature verification
23
23
  ```
24
24
 
25
- If you'd rather not use env vars, pass the same values via `credentials: { accountSid, authToken }`. The channel mounts three routes:
25
+ To skip env vars, pass the same values via `credentials: { accountSid, authToken }`. The channel mounts three routes:
26
26
 
27
27
  - `POST /eve/v1/twilio/messages`: Messaging webhook
28
28
  - `POST /eve/v1/twilio/voice`: inbound call webhook
@@ -30,15 +30,17 @@ If you'd rather not use env vars, pass the same values via `credentials: { accou
30
30
 
31
31
  Point your Twilio number's Messaging webhook at `/messages` and Voice webhook at `/voice`, using the exact public URL Twilio will call.
32
32
 
33
- ## Affordances
33
+ ## How the channel handles messages
34
34
 
35
- **`allowFrom` is required.** It gates who can reach the inbound hooks. Pass a single number, a list, an async resolver, or `"*"`. The wildcard is dangerous: only use it with an explicit check inside `onText`/`onVoice`.
35
+ ### Dispatch
36
+
37
+ `allowFrom` is required. It gates who can reach the inbound hooks. Pass a single number, a list, an async resolver, or `"*"`. The wildcard is dangerous; only use it with an explicit check inside `onText`/`onVoice`.
36
38
 
37
39
  ```ts
38
40
  export default twilioChannel({ allowFrom: ["+15551234567", "+15557654321"] });
39
41
  ```
40
42
 
41
- **Hooks.** `onText` and `onVoiceTranscription` decide dispatch and `auth`: return `{ auth }` to proceed, or `null` to drop the message. `onVoice` fires the moment a call comes in. Return `null` to reject it, or return an object to override the spoken prompt, language, `<Say voice>`, and speech-recognition options.
43
+ `onText` and `onVoiceTranscription` decide dispatch and `auth`. Return `{ auth }` to proceed, or `null` to drop the message. `onVoice` fires the moment a call comes in. Return `null` to reject it, or return an object to override the spoken prompt, language, `<Say voice>`, and speech-recognition options.
42
44
 
43
45
  ```ts
44
46
  export default twilioChannel({
@@ -54,7 +56,27 @@ export default twilioChannel({
54
56
  });
55
57
  ```
56
58
 
57
- **Delivery.** The default `message.completed` handler sends the reply as SMS through Twilio's Messages API. A reply to an inbound message can reuse the webhook's `To` as the sender, but a proactive send has nothing to reuse, so it needs `messaging.from` or `messaging.messagingServiceSid`. Behind a proxy, set `webhookUrl` so signature verification matches the exact configured URL, and `publicBaseUrl` so voice TwiML can build absolute callback URLs.
59
+ ### Delivery
60
+
61
+ The default `message.completed` handler sends the reply as SMS through Twilio's Messages API. A reply to an inbound message can reuse the webhook's `To` as the sender, but a proactive send has nothing to reuse, so it needs `messaging.from` or `messaging.messagingServiceSid`. Behind a proxy, set `webhookUrl` so signature verification matches the exact configured URL, and `publicBaseUrl` so voice TwiML can build absolute callback URLs.
62
+
63
+ ### Human-in-the-loop (HITL)
64
+
65
+ SMS and voice have no native button or card affordance, so HITL prompts do not render as interactive controls. The agent's `input.requested` event reaches your `events["input.requested"]` handler if you declare one. Handle it by sending the prompt as text and mapping the caller's reply back to the input request yourself.
66
+
67
+ ### Proactive sessions
68
+
69
+ Start a session without an inbound message through `receive(twilio, { message, target, auth })` from a schedule `run` handler, or `args.receive(twilio, ...)` from another channel. `target.phoneNumber` is required, and the channel needs `messaging.from` or `messaging.messagingServiceSid` for the outbound sender.
70
+
71
+ ### Attachments
72
+
73
+ Inbound media attachments are not supported on this channel today.
74
+
75
+ ## Disclaimer
76
+
77
+ As the deployer, it is your responsibility to ensure your agent complies with applicable laws.
78
+
79
+ For example, you may be required to inform callers and texters that calls are recorded/transcribed and processed by an automated AI system, and obtain consent where required (including two-party-consent jurisdictions). For outbound SMS or calls you initiate, you may be required to get prior express consent, honor STOP/opt-out and quiet-hour rules, and complete required carrier registration.
58
80
 
59
81
  ## What to read next
60
82
 
@@ -1,17 +1,11 @@
1
1
  ---
2
2
  title: "Context Control"
3
- description: "Control what the model sees and when: instructions, skills, the workspace, and subagents."
3
+ description: "Control what an Eve agent's model sees and when, across instructions, skills, the workspace, and subagents."
4
4
  ---
5
5
 
6
- Eve gives you a few levers for controlling what the model sees and when it sees it.
6
+ Eve gives you a few levers for controlling what the model sees and when. `instructions.md` (or `instructions.ts`) is always on, `skills/` are available but loaded on demand, and the workspace and sandbox are visible through tools rather than pasted into the prompt.
7
7
 
8
- The most useful mental model is:
9
-
10
- - `instructions.md` (or `instructions.ts`) is always on.
11
- - `skills/` are available but loaded on demand.
12
- - The workspace and sandbox are visible through tools, not pasted into the prompt.
13
-
14
- ## 1. Base identity with `instructions.md`
8
+ ## Base identity with `instructions.md`
15
9
 
16
10
  Use `instructions.md` for the core contract of the agent.
17
11
 
@@ -22,9 +16,9 @@ used a tool.
22
16
 
23
17
  Keep this file focused on stable behavior that should apply on every turn.
24
18
 
25
- ## 2. Compose instructions in TypeScript with `instructions.ts`
19
+ ## Compose instructions in TypeScript with `instructions.ts`
26
20
 
27
- When you want to build the instructions prompt from typed helpers, lib code, or environment-derived values, author it as a module instead of markdown.
21
+ To build the instructions prompt from typed helpers, lib code, or environment-derived values, author it as a module instead of markdown.
28
22
 
29
23
  ```ts title="agent/instructions.ts"
30
24
  import { defineInstructions } from "eve/instructions";
@@ -37,13 +31,9 @@ export default defineInstructions({
37
31
 
38
32
  Module-backed instructions run once at build time. Eve captures the resulting markdown into the compiled manifest, so the runtime serves the same prompt every session without re-running the module.
39
33
 
40
- ## 3. Load procedures on demand with `skills/`
41
-
42
- Skills are not part of the always-on prompt by default.
43
-
44
- Instead, Eve advertises the available skills and adds a framework-owned `load_skill` tool. When the request clearly matches a skill description, or the user names a skill explicitly, the model activates that skill, and Eve appends the skill's markdown to the active instructions for later turn work.
34
+ ## Load procedures on demand with `skills/`
45
35
 
46
- That is how you keep rich procedures available without bloating every turn.
36
+ Skills stay out of the always-on prompt by default, which keeps rich procedures available without bloating every turn. Eve advertises the available skills and adds a framework-owned `load_skill` tool. When the request clearly matches a skill description, or the user names a skill explicitly, the model activates that skill, and Eve appends the skill's markdown to the active instructions for later turn work.
47
37
 
48
38
  ### Flat skill
49
39
 
@@ -62,48 +52,41 @@ When the task is novel or ambiguous, gather evidence first, then answer with the
62
52
  remaining uncertainty.
63
53
  ```
64
54
 
65
- Packaged skills are useful when you also want sibling files such as `references/`, `assets/`, or `scripts/` under the same skill directory. Those packaged paths show up under the runtime workspace root, so the model can inspect them with the normal file or shell tools instead of pasting all of that content into the prompt.
55
+ Packaged skills are useful when you also want sibling files such as `references/`, `assets/`, or `scripts/` under the same skill directory. Those paths show up under the runtime workspace root, so the model can inspect them with the normal file or shell tools instead of pasting their content into the prompt.
66
56
 
67
57
  See [Skills](../skills) for the full authoring model and install notes.
68
58
 
69
- ## 4. Put runtime files in the workspace, not the prompt
59
+ ## Put runtime files in the workspace, not the prompt
70
60
 
71
- Eve does not inline the entire authored surface into the prompt. Instead, it gives the model a shallow workspace hint and runtime tools to inspect deeper when needed. That keeps prompts smaller and makes file and command work explicit: skill files are available under the active workspace root, and the model can inspect them with the shared `bash` tool.
61
+ Eve does not inline the entire authored surface into the prompt. Instead, it gives the model a shallow workspace hint and runtime tools to inspect deeper when needed. Skill files are available under the active workspace root, and the model inspects them with the shared `bash` tool, which keeps prompts smaller and makes file and command work explicit.
72
62
 
73
63
  See [Sandbox](../sandbox) for the workspace and sandbox model.
74
64
 
75
- ## 5. Delegate to a specialist with a subagent
65
+ ## Delegate to a specialist with a subagent
76
66
 
77
- If a task deserves its own prompt and tool surface, use a local subagent instead of overloading the root agent. Subagents are a context-control tool too: they get their own `instructions.md`, their own tools, and their own sandbox, and they run inside their own delegated context instead of extending the root agent inline.
67
+ If a task deserves its own prompt and tool surface, use a local subagent instead of overloading the root agent. Subagents are a context-control lever too. They get their own `instructions.md`, tools, and sandbox, and they run inside their own delegated context instead of extending the root agent inline.
78
68
 
79
69
  See [Subagents](../subagents).
80
70
 
81
71
  ## Dynamic context with `defineDynamic`
82
72
 
83
- The levers above are static: authored once, the same on every session. When the right context depends on who is calling (their team, tenant, plan, or feature flags), resolve it at runtime instead. `defineDynamic` in `agent/instructions/` returns the per-session system prompt, and `defineDynamic` in `agent/skills/` returns the set of skills a caller can load. Both read `ctx.session.auth` or channel metadata, so a caller on the billing team gets the billing instructions and playbook while nobody else sees them. See [Dynamic capabilities](../guides/dynamic-capabilities) for the resolver API and when each event fires.
73
+ The levers above are static, authored once and the same on every session. When the right context depends on who is calling (their team, tenant, plan, or feature flags), resolve it at runtime instead. `defineDynamic` in `agent/instructions/` returns the per-session system prompt, and `defineDynamic` in `agent/skills/` returns the set of skills a caller can load. Both read `ctx.session.auth` or channel metadata, so a caller on the billing team gets the billing instructions and playbook while no one else sees them. See [Dynamic capabilities](../guides/dynamic-capabilities) for the resolver API and when each event fires.
84
74
 
85
- ## Choosing the right lever
75
+ ## Recommended context layout
86
76
 
87
- Use:
77
+ Pick the lever by what the context is for:
88
78
 
89
- - `instructions.md` for the agent's permanent identity.
79
+ - `instructions.md` for the agent's permanent identity. Keep it short and stable.
90
80
  - `instructions.ts` when you need to compose the prompt from typed helpers at build time.
91
- - `skills/` for optional procedures that should load only when needed.
92
- - a subagent when the task needs a different specialist surface.
81
+ - `skills/` for optional procedures that should load only when needed. Move long procedures here instead of into the always-on prompt.
82
+ - `tools/` to expose typed integrations.
83
+ - a subagent when the task needs a different specialist surface; use one only for real specialization boundaries.
93
84
  - the workspace or sandbox when the model should inspect files or run commands instead of relying on pasted instructions.
94
85
 
95
- ## A good pattern
96
-
97
- For most agents:
98
-
99
- 1. Keep `instructions.md` short and stable.
100
- 2. Move long procedures into `skills/`.
101
- 3. Expose typed integrations through `tools/`.
102
- 4. Use subagents only for real specialization boundaries.
103
-
104
86
  ## What to read next
105
87
 
106
- - [Tools](../tools)
107
- - [Skills](../skills)
108
- - [Subagents](../subagents)
109
- - [Hooks](../guides/hooks)
88
+ - [Tools](../tools): expose typed integrations the model can call.
89
+ - [Skills](../skills): the full authoring model for on-demand procedures.
90
+ - [Subagents](../subagents): delegate to a specialist with its own prompt and tools.
91
+ - [Dynamic capabilities](../guides/dynamic-capabilities): resolve per-session instructions and skills with `defineDynamic`.
92
+ - [Hooks](../guides/hooks): run code on session events to update the channel state that dynamic resolvers read.
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  title: "The Harness"
3
- description: "The out-of-the-box agent loop and the built-in tools every Eve agent ships with, plus how to override or disable them."
3
+ description: "The out-of-the-box Eve agent loop and the built-in tools every agent ships with, plus how to override or disable them."
4
4
  ---
5
5
 
6
- The default harness is what every Eve agent ships with: the framework-owned agent loop, plus a set of built-in tools the model can call without you writing a line. You extend the base harness with capabilities specific to your agent. The loop itself, how a turn runs and checkpoints and resumes, lives in [Execution model & durability](./execution-model-and-durability).
6
+ The default harness is what every Eve agent ships with. It includes the framework-owned agent loop plus a set of built-in tools the model can call without you writing a line. You extend it with capabilities specific to your agent. The loop itself, how a turn runs and checkpoints and resumes, lives in [Execution model and durability](./execution-model-and-durability).
7
7
 
8
8
  ## Compaction
9
9
 
10
- A long session eventually fills the model's context window. The harness handles that for you: once the conversation crosses a fraction of the window (`thresholdPercent`, `0.9` by default), it summarizes the older turns into a compact form and keeps going, so the session continues instead of overflowing. The summary uses the active turn model unless you override it. Tune when and how it kicks in under [`compaction`](../agent-config#compaction) in `agent.ts`:
10
+ The harness keeps a long session from overflowing the model's context window. Once the conversation crosses a fraction of the window (`thresholdPercent`, `0.9` by default), it summarizes the older turns into a compact form and keeps going. The summary uses the active turn model unless you override it. Tune when and how it kicks in under [`compaction`](../agent-config#compaction) in `agent.ts`:
11
11
 
12
12
  ```ts title="agent/agent.ts"
13
13
  export default defineAgent({
@@ -18,11 +18,11 @@ export default defineAgent({
18
18
  });
19
19
  ```
20
20
 
21
- Compaction also preserves the framework's own tool state automatically. When the harness compacts history, it resets read-before-write tracking (so a write afterward re-reads the file whose read evidence was summarized away) and re-injects the active todo list, so the model keeps its task list across the summary. There is no per-tool hook to configure.
21
+ Compaction also preserves the framework's own tool state automatically. It resets read-before-write tracking (so a write afterward re-reads the file whose read evidence was summarized away) and re-injects the active todo list, so the model keeps its task list across the summary. There is no per-tool hook to configure.
22
22
 
23
23
  ## Built-in tools
24
24
 
25
- These ship with every agent, no imports. Discovery never runs them: the harness shows the model the tool descriptors first, then executes only what the model actually calls. The shell and file tools run inside the agent's single [sandbox](../sandbox); the rest run in the app runtime.
25
+ These ship with every agent, no imports. The harness shows the model the tool descriptors first, then executes only what the model actually calls; discovery never runs them. The shell and file tools (`bash`, `read_file`, `write_file`, `glob`, `grep`) live in the app runtime and proxy their work into the agent's single [sandbox](../sandbox); the rest run in the app runtime. The "Where it runs" column below names where each tool's effect lands.
26
26
 
27
27
  | Tool | Does | Where it runs |
28
28
  | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
@@ -46,9 +46,11 @@ Notes:
46
46
  - **`connection_search`** is the model-facing `connection__search` tool. A search surfaces a connection's tools by their qualified name (e.g. `connection__linear__list_issues`), and the model can then call them directly. It's registered only when the agent has connections.
47
47
  - **`web_search`** has no local executor; the provider runs it. To supply your own implementation, override it with `defineTool()`.
48
48
 
49
+ Review these built-in tools before production use. Disable, wrap, restrict, or require approval for any tool that can access the filesystem, network, shell, or sensitive data.
50
+
49
51
  ## Override a default
50
52
 
51
- Author a tool at the same slug and it takes over the built-in of that name. The file `agent/tools/write_file.ts` replaces the built-in `write_file` just by existing:
53
+ Author a tool at the same slug and it takes over the built-in of that name. The file `agent/tools/write_file.ts` replaces the built-in `write_file` by existing:
52
54
 
53
55
  ```ts title="agent/tools/write_file.ts"
54
56
  import { defineTool } from "eve/tools";
@@ -63,7 +65,7 @@ export default defineTool({
63
65
  });
64
66
  ```
65
67
 
66
- The framework defaults are importable from `eve/tools/defaults` (`bash`, `readFile`, `writeFile`, `glob`, `grep`, `webFetch`, `webSearch`, `todo`, `loadSkill`), so you can spread, wrap, or patch them. Skip the spread and your replacement owns its own context: a fresh `defineTool` for `todo` won't inherit the framework's durable state key.
68
+ The framework defaults are importable from `eve/tools/defaults` (`bash`, `readFile`, `writeFile`, `glob`, `grep`, `webFetch`, `webSearch`, `todo`, `loadSkill`), so you can spread, wrap, or patch them. Skip the spread and your replacement owns its own context. A fresh `defineTool` for `todo` won't inherit the framework's durable state key.
67
69
 
68
70
  ## Disable a default
69
71
 
@@ -75,11 +77,19 @@ import { disableTool } from "eve/tools";
75
77
  export default disableTool();
76
78
  ```
77
79
 
78
- Misspell the filename so it matches no known framework tool and it fails at resolve time, instead of silently doing nothing.
80
+ If the filename matches no known framework tool, resolution fails instead of silently doing nothing, so a typo surfaces at build time rather than removing the wrong tool.
81
+
82
+ ## When to override, disable, or author a new tool
83
+
84
+ Three moves shape the harness. The right one depends on whether the model should keep the built-in capability.
85
+
86
+ - **Override** when you want the same capability with different behavior. Spread the default from `eve/tools/defaults` and wrap it (logging, an extra guard, a different backend), and the model still sees a tool by that name. Spreading keeps the default's description, schema, and any framework state, such as the `todo` tool's durable state key. Drop the spread and your replacement owns its own context, losing that wiring.
87
+ - **Disable** when the model should not have the capability at all. A `disableTool()` sentinel removes the built-in, and the model never sees it. Reach for this to lock down `bash` or `web_fetch` in an agent that should not run shell commands or fetch arbitrary URLs.
88
+ - **Author a new tool** when you want a capability the harness does not ship. Give it a fresh slug under `agent/tools/` and it joins the built-ins instead of replacing one. See [Tools](../tools) for the authoring model.
79
89
 
80
90
  ## The opt-in `Workflow` tool
81
91
 
82
- There's also an experimental `Workflow` tool, shipped but off by default. To turn it on, re-export the opt-in marker from `agent/tools/workflow.ts`:
92
+ An experimental `Workflow` tool ships but stays off by default. To turn it on, re-export the opt-in marker from `agent/tools/workflow.ts`:
83
93
 
84
94
  ```ts
85
95
  export { ExperimentalWorkflow as default } from "eve/tools";
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: "Execution Model & Durability"
3
- description: "How a session runs: durable conversations, turns that checkpoint at steps, and parked work that resumes later."
2
+ title: "Execution Model and Durability"
3
+ description: "How an Eve session runs. Durable conversations, turns that checkpoint at steps, and parked work that resumes later."
4
4
  ---
5
5
 
6
- A session is a durable conversation. It can run for days, and it survives process restarts and redeploys without any work on your part. You write the capabilities (tools, instructions, channels) and Eve runs the loop.
6
+ An Eve session is a durable conversation. It can run for days and survives process restarts and redeploys without any work on your part. You write the capabilities (tools, instructions, channels) and Eve runs the loop.
7
7
 
8
8
  ## Sessions, turns, and steps
9
9
 
@@ -13,38 +13,38 @@ Work nests in three levels:
13
13
  - **turn**: one user message and all the work it triggers (model calls, tool calls, reasoning) until the agent produces its response.
14
14
  - **step**: a durable checkpoint inside a turn (one model call and the tool calls it makes).
15
15
 
16
- Every turn runs as a durable workflow, built on the open-source [Workflow SDK](https://workflow-sdk.dev/) (Vercel Workflow when you deploy on Vercel). Eve checkpoints progress at each step and serializes durable state at that boundary. Your code runs inside a managed step, so tools, the sandbox, and subagents feel synchronous even though the session underneath them is durable.
16
+ Every turn runs as a durable workflow, built on the open-source [Workflow SDK](https://workflow-sdk.dev/) (Vercel Workflow when you deploy on Vercel). Eve checkpoints progress and serializes durable state at each step boundary. Your code runs inside a managed step, so tools, the sandbox, and subagents feel synchronous even though the session underneath them is durable.
17
17
 
18
18
  ## Resuming after a crash
19
19
 
20
- Crash the process, hit a timeout, or redeploy mid-turn, and the run picks up from the last completed step rather than replaying the whole turn. Re-running a step from the same input is idempotent. Your tool calls don't fire twice, so a resume never doubles up a side effect (a charge, an email, a write).
20
+ Crash the process, hit a timeout, or redeploy mid-turn, and the run picks up from the last completed step rather than replaying the whole turn. Completed steps never re-run; Eve replays the recorded result. A step interrupted mid-execution re-runs, so make non-idempotent side effects like charges or emails idempotent, or gate them with approval.
21
21
 
22
- There's nothing to configure here. Eve owns the workflow lifecycle, and sessions are durable by default.
22
+ There's nothing to configure. Eve owns the workflow lifecycle, and sessions are durable by default.
23
23
 
24
- You don't write workflow code directly. Workflow primitives (`start()`, `resumeHook()`, etc.) are an implementation detail of Eve's runtime layer; channels, tools, and hooks never touch them. When you do need session data from your own code, there are two supported surfaces: tools read the current session's metadata (id, turn, auth, parent lineage) via `ctx.session`, and [`defineState`](../guides/session-context) reads or writes session-scoped durable state. See [State](../guides/state) for the read/write model.
24
+ You don't write workflow code directly. Workflow primitives (`start()`, `resumeHook()`, etc.) are an implementation detail of Eve's runtime layer; channels, tools, and hooks never touch them. Two surfaces give your own code session data: tools read the current session's metadata (id, turn, auth, parent lineage) via `ctx.session`, and [`defineState`](../guides/state) reads or writes session-scoped durable state. See [State](../guides/state) for the read/write model.
25
25
 
26
26
  ## Parked work
27
27
 
28
- Some work has to wait: a human approving a [tool](../tools), an interactive OAuth sign-in for a [connection](../connections), or a long-running [subagent](../subagents). At those points the turn parks durably. The workflow suspends and holds no compute until the input it's waiting on shows up (a click, a callback, a child completing), even if that's much later. When it does, the conversation picks up exactly where it left off.
28
+ Some work has to wait, including a human approving a [tool](../tools), an interactive OAuth sign-in for a [connection](../connections), or a long-running [subagent](../subagents). At those points the turn parks durably. The workflow suspends and holds no compute until the input it's waiting on arrives (a click, a callback, a child completing), even if that's much later. When it does, the conversation picks up exactly where it left off.
29
29
 
30
30
  ## Message delivery and queueing
31
31
 
32
- Eve does not maintain a durable FIFO queue of user messages for a session today. The `continuationToken` is a resume handle for the session's current workflow hook, not a general message-queue address.
32
+ Eve does not maintain a durable FIFO queue of user messages for a session. The `continuationToken` is a resume handle for the session's current workflow hook, not a general message-queue address.
33
33
 
34
- When a session is waiting, a delivery to the current continuation token wakes the session and starts the next turn. When a turn is already active, additional deliveries may be accepted by the hook, but the runtime only drains them at specific workflow boundaries. If more than one delivery is already ready when the driver checks, Eve may fold them into the next turn; that drain is best-effort and depends on workflow and transport timing.
34
+ When a session is waiting, a delivery to the current continuation token wakes the session and starts the next turn. When a turn is already active, the hook may accept additional deliveries, but the runtime only drains them at specific workflow boundaries. If more than one delivery is ready when the driver checks, Eve may fold them into the next turn; that drain is best-effort and depends on workflow and transport timing.
35
35
 
36
- That means applications should not rely on concurrent sends to the same session behaving like a typical ordered chat queue. For deterministic behavior, send one user turn at a time: wait for `session.waiting` before sending the next message to the same session. If your channel can receive bursts while the agent is working, keep your own per-session queue in the channel or app layer, then deliver the next message after the session parks again. Separate sessions can still run independently.
36
+ So don't rely on concurrent sends to the same session behaving like a typical ordered chat queue. For deterministic behavior, send one user turn at a time and wait for `session.waiting` before sending the next message to the same session. If your channel can receive bursts while the agent is working, keep your own per-session queue in the channel or app layer, then deliver the next message after the session parks again. Separate sessions still run independently.
37
37
 
38
38
  ## Subagents
39
39
 
40
40
  A turn can hand work off to a [subagent](../subagents). Each subagent gets its own context and its own durable session; a declared subagent also gets its own sandbox, skills, and state. Nothing crosses the boundary implicitly.
41
41
 
42
- ## Ordering
42
+ ## How Eve orders session history
43
43
 
44
- Conversation history within a session is append-only. Turns land in order, and the tool calls inside a turn (plus their results) keep their order too. Read a session back and you see things in the order they happened.
44
+ Conversation history within a session is append-only. Turns land in order, and the tool calls inside a turn (plus their results) keep their order too. Read a session back and you see events in the order they happened.
45
45
 
46
46
  ## What to read next
47
47
 
48
- - [Sessions, runs & streaming](./sessions-runs-and-streaming): the handles you hold and the event stream you watch.
48
+ - [Sessions and streaming](./sessions-runs-and-streaming): the handles you hold and the event stream you watch.
49
49
  - [Security model](./security-model): the trust boundaries the runtime enforces.
50
50
  - [State](../guides/state): durable per-session memory that persists across step boundaries.
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  title: "Security Model"
3
- description: "Trust boundaries, where secrets live, how credentials reach hosts, and what fails closed by default."
3
+ description: "Eve's trust boundaries, where secrets live, how credentials reach hosts, and what fails closed by default."
4
4
  ---
5
5
 
6
- Your agent runs across two contexts, with a trust boundary drawn between them and every secret kept on the trusted side. This page is the mental model to use when you're deciding what an agent (and the model driving it) is allowed to reach.
6
+ Your Eve agent runs across two contexts, with a trust boundary between them and every secret kept on the trusted side. Use this mental model when deciding what an agent (and the model driving it) is allowed to reach.
7
7
 
8
8
  ## Trust boundaries
9
9
 
@@ -16,13 +16,37 @@ Your agent runs across two contexts, with a trust boundary drawn between them an
16
16
 
17
17
  The app runtime is the trusted side. Your tool implementations, model calls, connections, state, and durable execution all run here, with `process.env` and full Node.js available. (On Vercel, this is a Vercel Function.)
18
18
 
19
- The sandbox is the isolated side. The model runs shell commands there through the built-in `bash`, `read_file`, `write_file`, `glob`, and `grep` tools. It gets its own `/workspace` filesystem, but no `process.env`, no secrets, and no path back into the app runtime. (On Vercel, each sandbox is a [Vercel Sandbox](https://vercel.com/docs/sandbox) microVM with hardware-level isolation.) The only thing that actually executes in the sandbox is shell commands. Even the built-in `bash`/`read_file`/`write_file` tools live in the app runtime and _proxy_ into the sandbox. The model sees tool definitions and results, never your secrets.
19
+ The sandbox is the isolated side. The model runs shell commands there through the built-in `bash`, `read_file`, `write_file`, `glob`, and `grep` tools. It gets its own `/workspace` filesystem, but no `process.env`, no secrets, and no path back into the app runtime. (On Vercel, each sandbox is a [Vercel Sandbox](https://vercel.com/docs/sandbox) microVM with hardware-level isolation.) Only shell commands execute in the sandbox. Even the built-in `bash`/`read_file`/`write_file` tools live in the app runtime and _proxy_ into the sandbox. The model sees tool definitions and results, never your secrets.
20
20
 
21
21
  A concrete trace makes the boundary clear. When the model calls a custom `charge_card` tool, its `execute` runs in the app runtime, reads `process.env.STRIPE_KEY`, calls Stripe, and returns `{ ok: true }`. The model sees only `{ ok: true }`: the key never leaves the app runtime, and nothing about the call touches the sandbox. The built-in `write_file` is the mirror image, running in the app runtime and proxying the write into the sandbox `/workspace`. Either way the model drives the work through tool calls and their results, never by holding a credential or reaching the runtime directly.
22
22
 
23
+ ## Data flow at a glance
24
+
25
+ ```mermaid
26
+ flowchart LR
27
+ User["User or channel provider"] --> Channel["Channel route and route auth"]
28
+ Channel --> Runtime["Eve app runtime and durable session"]
29
+ Runtime --> Model["Configured model provider or Vercel AI Gateway"]
30
+ Runtime --> Tools["Authored tools and connections"]
31
+ Tools --> Services["Customer-selected external services"]
32
+ Runtime --> Sandbox["Per-session sandbox"]
33
+ Sandbox --> Egress["Allowed sandbox network egress"]
34
+ Runtime --> Telemetry["Configured telemetry or eval provider"]
35
+ ```
36
+
37
+ Eve sends data where your agent configuration and runtime choices send it:
38
+
39
+ - Inbound channel data flows through the channel provider you configure, then into the Eve app runtime.
40
+ - Model inputs and outputs flow to the model or routing path selected in `agent.ts`, such as a Vercel AI Gateway model id or a provider-authored `LanguageModel`.
41
+ - Tool and connection calls flow to the external services, MCP servers, OpenAPI endpoints, and channels you configure.
42
+ - Sandbox commands can reach network destinations allowed by the sandbox network policy.
43
+ - Telemetry and eval data flows to the exporters and providers you configure in `instrumentation.ts` or eval settings.
44
+
45
+ Eve stores durable session and workflow state needed to resume conversations, stream events, replay completed steps, and show run observability. You are responsible for deciding whether the selected channels, model providers, connected services, sandbox egress destinations, telemetry exporters, retention settings, and deletion controls are appropriate for your data and use case.
46
+
23
47
  ## Credential brokering
24
48
 
25
- Sometimes the model needs _authenticated_ network access from inside the sandbox, like a `git clone` of a private repo or an authenticated `curl`, and there's no [tool](../tools) or [connection](../connections) to route it through. That's what credential brokering is for. On the Vercel Sandbox backend, auth headers get injected at the sandbox's network firewall for matching domains. The secret stays in the app runtime; the sandbox process only ever sees the response. See [Vercel Sandbox Credential Brokering](https://vercel.com/docs/sandbox/concepts/firewall#credentials-brokering) for the platform mechanism, and [Sandbox](../sandbox) for the Eve policy API.
49
+ Credential brokering gives the model _authenticated_ network access from inside the sandbox, like a `git clone` of a private repo or an authenticated `curl`, when there's no [tool](../tools) or [connection](../connections) to route it through. On the Vercel Sandbox backend, auth headers get injected at the sandbox's network firewall for matching domains. The secret stays in the app runtime; the sandbox process only ever sees the response. See [Vercel Sandbox Credential Brokering](https://vercel.com/docs/sandbox/concepts/firewall#credentials-brokering) for the platform mechanism, and [Sandbox](../sandbox) for the Eve policy API.
26
50
 
27
51
  ## Connection credentials
28
52
 
@@ -30,7 +54,7 @@ Sometimes the model needs _authenticated_ network access from inside the sandbox
30
54
 
31
55
  ## Channel verification
32
56
 
33
- A [channel](../channels/overview) is your agent's front door, which makes authenticating inbound traffic its job. The built-in platform channels follow two rules here, and so must any channel you write yourself:
57
+ A [channel](../channels/overview) is your agent's front door, so authenticating inbound traffic is its job. The built-in platform channels follow two rules, and so must any channel you write yourself:
34
58
 
35
59
  - **Verify signatures in constant time.** Platform channels (Slack, GitHub,
36
60
  Telegram, Twilio) verify the platform's HMAC signature over the raw request body
@@ -46,11 +70,11 @@ A custom channel that accepts dashboard-style webhooks should follow the same sh
46
70
 
47
71
  ## Authored markdown is data
48
72
 
49
- [Skill](../skills) and [schedule](../schedules) files are markdown with YAML frontmatter, and Eve treats that frontmatter strictly as data. The code-capable engines (`---js` / `---javascript`, which would `eval()` the frontmatter body the moment the file is parsed) are disabled. A fence like that throws rather than running. Frontmatter has to parse to a plain YAML object.
73
+ [Skill](../skills) and [schedule](../schedules) files are markdown with YAML frontmatter, and Eve treats that frontmatter strictly as data. The code-capable engines (`---js` / `---javascript`, which would `eval()` the frontmatter body the moment the file is parsed) are disabled, so such a fence throws rather than running. Frontmatter has to parse to a plain YAML object.
50
74
 
51
75
  ## Auth fails closed
52
76
 
53
- Routes reject unauthenticated traffic by default: if no `AuthFn` in the walk accepts the request, it gets a `401`, and admitting anonymous callers takes an explicit `none()`. The scaffold's `placeholderAuth()` keeps a half-configured app closed in production until you replace it. See [Auth & route protection](../guides/auth-and-route-protection) for the full walk and verifiers.
77
+ Routes reject unauthenticated traffic by default. If no `AuthFn` in the walk accepts the request, it gets a `401`, and admitting anonymous callers takes an explicit `none()`. The scaffold's `placeholderAuth()` keeps a half-configured app closed in production until you replace it. See [Auth & route protection](../guides/auth-and-route-protection) for the full walk and verifiers.
54
78
 
55
79
  ## Pre-production checklist
56
80
 
@@ -75,5 +99,5 @@ Before exposing an agent to real traffic:
75
99
 
76
100
  - [Auth & route protection](../guides/auth-and-route-protection): the full auth walk and verifier helpers
77
101
  - [Sandbox](../sandbox): backends, network policy, and brokering config
78
- - [Execution model & durability](./execution-model-and-durability): how durable sessions run
102
+ - [Execution model and durability](./execution-model-and-durability): how durable sessions run
79
103
  - [Connections](../connections): static-token and OAuth connections
@@ -7,7 +7,7 @@ Every Eve app speaks the same stable HTTP API to a [durable session](./execution
7
7
 
8
8
  ## The two handles
9
9
 
10
- Two handles do two jobs here, and mixing them up is the most common mistake. One handle creates and resumes a session; a different one streams and inspects it.
10
+ Two handles do two jobs, and mixing them up is the most common mistake. One handle creates and resumes a session; a different one streams and inspects it.
11
11
 
12
12
  - **`continuationToken`**: the resume handle. Use it to send a follow-up message to the same conversation. Owned by the channel.
13
13
  - **`sessionId` / `runId`**: the stream-and-inspect handle. Use it to attach to the event stream and watch a run. Owned by the runtime.
@@ -19,17 +19,17 @@ React, Vue, and Svelte apps reach for [`useEveAgent()`](../guides/frontend/overv
19
19
  ## Start a session
20
20
 
21
21
  ```bash
22
- curl -X POST http://127.0.0.1:2000/eve/v1/session \
22
+ curl -X POST http://127.0.0.1:3000/eve/v1/session \
23
23
  -H 'content-type: application/json' \
24
24
  -d '{"message":"Summarize the latest forecast."}'
25
25
  ```
26
26
 
27
- Eve responds right away. The JSON body carries a `sessionId` and a `continuationToken`, and the `x-eve-session-id` header tells you which durable session to stream.
27
+ Eve responds right away. The JSON body carries a `sessionId` and a `continuationToken`, and the `x-eve-session-id` header names the durable session to stream.
28
28
 
29
29
  ## Stream a session
30
30
 
31
31
  ```bash
32
- curl http://127.0.0.1:2000/eve/v1/session/<sessionId>/stream
32
+ curl http://127.0.0.1:3000/eve/v1/session/<sessionId>/stream
33
33
  ```
34
34
 
35
35
  The stream is newline-delimited JSON (NDJSON), one event per line:
@@ -64,6 +64,8 @@ The stream is newline-delimited JSON (NDJSON), one event per line:
64
64
 
65
65
  `reasoning.appended` and `message.appended` stream deltas as they arrive, and each one carries both the new delta and the cumulative text for the current block. The finalized block shows up on `message.completed` and `reasoning.completed`, which is the compatibility path for clients that don't render incremental streaming.
66
66
 
67
+ Note: consider the privacy, confidentiality, and user-experience implications for displaying, storing, or transmitting reasoning events in your application.
68
+
67
69
  `message.completed` can fire more than once in a turn: the agent often emits interim assistant text before a tool call. To tell tool-call narration from a terminal reply, check `message.completed.data.finishReason`. `step.completed.data.finishReason` mirrors the step outcome, and usage lives on `step.completed`.
68
70
 
69
71
  A delegated subagent publishes progress on its own child-session stream. The parent only emits `subagent.called` with a `childSessionId`, which a client uses to attach.
@@ -75,7 +77,7 @@ A delegated subagent publishes progress on its own child-session stream. The par
75
77
  Once the session is waiting (you'll see `session.waiting`), POST your follow-up to the session endpoint with the stored continuation token:
76
78
 
77
79
  ```bash
78
- curl -X POST http://127.0.0.1:2000/eve/v1/session/<sessionId> \
80
+ curl -X POST http://127.0.0.1:3000/eve/v1/session/<sessionId> \
79
81
  -H 'content-type: application/json' \
80
82
  -d '{"continuationToken":"<token>","message":"Now send the short version."}'
81
83
  ```
@@ -86,10 +88,10 @@ For deterministic ordering, send one follow-up at a time and wait for the next `
86
88
 
87
89
  ## Reconnect and rewind
88
90
 
89
- The stream is durable. Every event is recorded before a step completes, so it's all replayable. Pass `startIndex` to reconnect by event count and pick up where you dropped off, or rewind to the start:
91
+ The stream is durable. Every event is recorded before a step completes, so the whole stream is replayable. Pass `startIndex` to reconnect by event count and pick up where you dropped off, or rewind to the start:
90
92
 
91
93
  ```bash
92
- curl "http://127.0.0.1:2000/eve/v1/session/<sessionId>/stream?startIndex=<count>"
94
+ curl "http://127.0.0.1:3000/eve/v1/session/<sessionId>/stream?startIndex=<count>"
93
95
  ```
94
96
 
95
97
  ## Use the client from TypeScript
@@ -103,7 +105,7 @@ Start with the [TypeScript SDK](../guides/client/overview) guide. It covers basi
103
105
  `GET /eve/v1/info` returns a JSON inspection snapshot for the running agent: model, instructions, authored and framework tools, skills, channels, schedules, subagents, sandbox, connections, hooks, workflow, and workspace metadata. Local development accepts loopback requests; deployed Vercel targets require the route's OIDC auth.
104
106
 
105
107
  ```bash
106
- curl http://127.0.0.1:2000/eve/v1/info
108
+ curl http://127.0.0.1:3000/eve/v1/info
107
109
  ```
108
110
 
109
111
  The route uses the same default auth chain as the eve channel (`[localDev(), vercelOidc()]`). Locally it answers anonymously; a deployed Vercel target requires a valid OIDC bearer, with a same-project bypass for in-deployment callers. See [auth & route protection](../guides/auth-and-route-protection).
@@ -117,7 +119,7 @@ Every stream event runs four steps, in this order:
117
119
  3. **Hooks**: authored [hooks](../guides/hooks) subscribed to the event fire.
118
120
  4. **Dynamic resolvers**: [dynamic](../guides/dynamic-capabilities) tool, skill, and instruction resolvers fire, and `ctx.channel.metadata` already holds the freshly projected metadata from step 2.
119
121
 
120
- The order isn't incidental, it's structural. By the time a resolver or hook reads channel metadata, the channel has already updated its state and the projection is current.
122
+ The order is structural, not incidental. By the time a resolver or hook reads channel metadata, the channel has already updated its state and the projection is current.
121
123
 
122
124
  ## What to read next
123
125