eve 0.29.4 → 0.29.5

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 (128) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/src/channel/clear-session.d.ts +4 -0
  3. package/dist/src/channel/clear-session.js +1 -0
  4. package/dist/src/channel/compact-session.d.ts +4 -0
  5. package/dist/src/channel/compact-session.js +1 -0
  6. package/dist/src/channel/routes.d.ts +34 -6
  7. package/dist/src/channel/types.d.ts +61 -9
  8. package/dist/src/chunks/{use-eve-agent-8mofdZcO.js → use-eve-agent-BXMIf5fR.js} +85 -1
  9. package/dist/src/chunks/{use-eve-agent-bKJbH0k4.js → use-eve-agent-k-XHfrJT.js} +85 -1
  10. package/dist/src/cli/dev/tui/message-queue.d.ts +9 -13
  11. package/dist/src/cli/dev/tui/message-queue.js +1 -1
  12. package/dist/src/cli/dev/tui/prompt-commands.d.ts +13 -5
  13. package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
  14. package/dist/src/cli/dev/tui/runner.d.ts +7 -7
  15. package/dist/src/cli/dev/tui/runner.js +1 -1
  16. package/dist/src/cli/dev/tui/subagent-pump.d.ts +5 -5
  17. package/dist/src/cli/dev/tui/terminal-renderer.js +1 -1
  18. package/dist/src/client/agent-info-schema.d.ts +2 -2
  19. package/dist/src/client/agent-info-schema.js +1 -1
  20. package/dist/src/client/index.d.ts +1 -1
  21. package/dist/src/client/session.d.ts +15 -1
  22. package/dist/src/client/session.js +1 -1
  23. package/dist/src/client/types.d.ts +20 -0
  24. package/dist/src/compiler/extension-compatibility.d.ts +8 -8
  25. package/dist/src/compiler/extension-compatibility.js +1 -1
  26. package/dist/src/compiler/manifest.d.ts +11 -22
  27. package/dist/src/compiler/manifest.js +1 -1
  28. package/dist/src/compiler/normalize-agent-config.d.ts +3 -1
  29. package/dist/src/compiler/normalize-agent-config.js +1 -1
  30. package/dist/src/compiler/normalize-manifest.js +1 -1
  31. package/dist/src/compiler/normalize-subagent.d.ts +1 -0
  32. package/dist/src/compiler/normalize-subagent.js +1 -1
  33. package/dist/src/compiler/remote-agent-node.d.ts +3 -0
  34. package/dist/src/context/dynamic-subagent-lifecycle.d.ts +22 -0
  35. package/dist/src/context/dynamic-subagent-lifecycle.js +1 -0
  36. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  37. package/dist/src/context/keys.d.ts +13 -2
  38. package/dist/src/context/keys.js +1 -1
  39. package/dist/src/context/run-step.js +1 -1
  40. package/dist/src/execution/create-session-step.d.ts +2 -0
  41. package/dist/src/execution/create-session-step.js +1 -1
  42. package/dist/src/execution/delegation-tool.d.ts +3 -0
  43. package/dist/src/execution/delegation-tool.js +1 -0
  44. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  45. package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
  46. package/dist/src/execution/effective-agent-config.d.ts +12 -0
  47. package/dist/src/execution/effective-agent-config.js +1 -0
  48. package/dist/src/execution/node-step.d.ts +4 -0
  49. package/dist/src/execution/node-step.js +1 -1
  50. package/dist/src/execution/runtime-context.d.ts +2 -0
  51. package/dist/src/execution/runtime-context.js +1 -1
  52. package/dist/src/execution/session-callback-request.d.ts +5 -0
  53. package/dist/src/execution/session-callback-request.js +1 -0
  54. package/dist/src/execution/session-delivery-hook.d.ts +1 -0
  55. package/dist/src/execution/session-delivery-hook.js +1 -1
  56. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  57. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  58. package/dist/src/execution/workflow-entry.js +1 -1
  59. package/dist/src/execution/workflow-runtime.d.ts +2 -0
  60. package/dist/src/execution/workflow-runtime.js +1 -1
  61. package/dist/src/execution/workflow-steps.js +1 -1
  62. package/dist/src/harness/agent-handles.d.ts +238 -0
  63. package/dist/src/harness/agent-handles.js +2 -0
  64. package/dist/src/harness/compaction.d.ts +1 -1
  65. package/dist/src/harness/compaction.js +1 -1
  66. package/dist/src/harness/tool-loop.js +2 -2
  67. package/dist/src/harness/types.d.ts +16 -0
  68. package/dist/src/internal/application/package.js +1 -1
  69. package/dist/src/internal/authored-definition/core.js +1 -1
  70. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  71. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +1 -1
  72. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  73. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  74. package/dist/src/internal/vercel-agent-summary.d.ts +1 -1
  75. package/dist/src/protocol/clear-session.d.ts +14 -0
  76. package/dist/src/protocol/clear-session.js +1 -0
  77. package/dist/src/protocol/compact-session.d.ts +14 -0
  78. package/dist/src/protocol/compact-session.js +1 -0
  79. package/dist/src/protocol/message.d.ts +19 -1
  80. package/dist/src/protocol/message.js +1 -1
  81. package/dist/src/protocol/routes.d.ts +10 -0
  82. package/dist/src/protocol/routes.js +1 -1
  83. package/dist/src/public/channels/eve.js +1 -1
  84. package/dist/src/public/channels/index.d.ts +1 -1
  85. package/dist/src/public/definitions/agent.d.ts +32 -1
  86. package/dist/src/public/definitions/agent.js +1 -1
  87. package/dist/src/public/definitions/channel.d.ts +5 -2
  88. package/dist/src/public/definitions/channel.js +1 -1
  89. package/dist/src/public/definitions/hook.d.ts +1 -0
  90. package/dist/src/public/definitions/tool.d.ts +4 -1
  91. package/dist/src/public/index.d.ts +1 -2
  92. package/dist/src/public/index.js +1 -1
  93. package/dist/src/runtime/framework-tools/connection-search-dynamic.d.ts +2 -18
  94. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +2 -2
  95. package/dist/src/runtime/framework-tools/index.d.ts +7 -2
  96. package/dist/src/runtime/framework-tools/index.js +1 -1
  97. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  98. package/dist/src/runtime/resolve-agent.js +1 -1
  99. package/dist/src/runtime/resolve-dynamic-subagent.d.ts +12 -0
  100. package/dist/src/runtime/resolve-dynamic-subagent.js +1 -0
  101. package/dist/src/runtime/resolve-dynamic-tool.d.ts +15 -0
  102. package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
  103. package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +22 -0
  104. package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -0
  105. package/dist/src/runtime/subagents/registry.d.ts +10 -2
  106. package/dist/src/runtime/subagents/registry.js +1 -1
  107. package/dist/src/runtime/types.d.ts +11 -2
  108. package/dist/src/setup/flows/registry.js +1 -1
  109. package/dist/src/setup/scaffold/create/project.js +1 -1
  110. package/dist/src/shared/agent-definition.d.ts +7 -0
  111. package/dist/src/shared/agent-turn-outcome.d.ts +47 -0
  112. package/dist/src/shared/agent-turn-outcome.js +1 -0
  113. package/dist/src/shared/dynamic-tool-definition.d.ts +1 -5
  114. package/dist/src/shared/dynamic-tool-definition.js +1 -1
  115. package/dist/src/svelte/index.js +1 -1
  116. package/dist/src/svelte/use-eve-agent.js +1 -1
  117. package/dist/src/vue/index.js +1 -1
  118. package/dist/src/vue/use-eve-agent.js +1 -1
  119. package/docs/channels/custom.mdx +41 -1
  120. package/docs/channels/eve.mdx +26 -1
  121. package/docs/concepts/default-harness.md +4 -0
  122. package/docs/guides/client/streaming.mdx +14 -0
  123. package/docs/guides/dev-tui.md +10 -7
  124. package/docs/guides/dynamic-capabilities.md +49 -6
  125. package/docs/reference/project-layout.md +1 -1
  126. package/docs/reference/typescript-api.md +48 -48
  127. package/docs/subagents.mdx +32 -2
  128. package/package.json +2 -2
@@ -18,13 +18,16 @@ export default eveChannel({
18
18
 
19
19
  ## Routes
20
20
 
21
- The application exposes a health route plus eve channel routes that inspect the agent, create sessions, send follow-ups, cancel turns, and stream events:
21
+ The application exposes a health route plus eve channel routes that inspect the agent, create sessions, send follow-ups, cancel turns, compact or reset sessions, and stream events:
22
22
 
23
23
  - `GET /eve/v1/health`
24
24
  - `GET /eve/v1/info`
25
25
  - `POST /eve/v1/session` (start a session)
26
26
  - `POST /eve/v1/session/:sessionId` (send a follow-up)
27
27
  - `POST /eve/v1/session/:sessionId/cancel` (cancel the in-flight turn)
28
+ - `POST /eve/v1/session/clear` (clear the continuation owner's model history)
29
+ - `POST /eve/v1/session/compact` (compact the continuation owner's context)
30
+ - `POST /eve/v1/session/reset` (retire the continuation owner)
28
31
  - `GET /eve/v1/session/:sessionId/stream` (stream events, NDJSON)
29
32
 
30
33
  Start a session with a minimal body. The response returns `sessionId` and the `continuationToken` you reuse for follow-ups:
@@ -54,6 +57,28 @@ curl -X POST https://<deployment>/eve/v1/session/ses_01h.../cancel
54
57
 
55
58
  Cancellation is asynchronous: `"accepted"` means a cancellation hook accepted the request. Confirm the effective outcome on the stream as `turn.cancelled` followed by `session.waiting` — never as a failure. Active local and remote subagents are cancelled recursively before the parent settles; their own streams carry their cancellation boundaries, and cancelled work does not emit `subagent.completed` on the parent. Content emitted before the cancel stays on the event stream, while durable model history keeps only content that had already settled. The session accepts the next message normally. When there is no resumable cancellation target (including an unknown session, a settled turn, or a duplicate cancel), the route responds with `"no_active_turn"` — also a success, so a stop button can fire and forget. A `turnId` naming any other turn is accepted and consumed as a no-op, so a guarded cancel racing a turn boundary cannot stop a turn the caller never saw.
56
59
 
60
+ Clear the model-message history of the session that owns a continuation token:
61
+
62
+ ```bash
63
+ curl -X POST https://<deployment>/eve/v1/session/clear \
64
+ -H "Content-Type: application/json" \
65
+ -d '{"continuationToken":"eve:7f3c..."}'
66
+ # {"ok":true,"sessionId":"ses_01h...","status":"accepted"}
67
+ ```
68
+
69
+ An accepted clear emits `context.cleared` followed by `session.waiting`. The next message resumes the same session without prior model messages; the system prompt, tools and skills, durable state, limits, and session-scoped sandbox remain.
70
+
71
+ Compact the session that owns a continuation token without sending a message:
72
+
73
+ ```bash
74
+ curl -X POST https://<deployment>/eve/v1/session/compact \
75
+ -H "Content-Type: application/json" \
76
+ -d '{"continuationToken":"eve:7f3c..."}'
77
+ # {"ok":true,"sessionId":"ses_01h...","status":"accepted"}
78
+ ```
79
+
80
+ Compaction is asynchronous. A successful operation emits `compaction.requested` and `compaction.completed`, then returns through `session.waiting`; when a turn is active, the operation waits for it to settle. If summarization fails, the session still returns to `session.waiting` with its previous history. `"no_active_session"` is the successful no-op response when the token has no owner.
81
+
57
82
  See [Sessions, runs & streaming](../concepts/sessions-runs-and-streaming) for the full request and stream flow, including the complete event set.
58
83
 
59
84
  ## CORS
@@ -20,6 +20,10 @@ export default defineAgent({
20
20
 
21
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
+ Clients and channels can also request compaction between turns. Call `ClientSession.compact()` or a custom route's `compact({ continuationToken })` helper. The request does not append a user message; if a turn is running, eve queues it until that turn settles. A successful manual compaction emits the same `compaction.requested` and `compaction.completed` events as automatic compaction, followed by `session.waiting`.
24
+
25
+ To discard model-message history instead of summarizing it, call `ClientSession.clear()` or a custom route's `clear({ continuationToken })` helper. Clearing preserves the session identity, system prompt, configured tools and skills, durable state, limits, and sandbox. Its stream boundary is `context.cleared` followed by `session.waiting`.
26
+
23
27
  ## Built-in tools
24
28
 
25
29
  Built-in tools require no imports. The exact set depends on the agent and session. `agent` is available only in the root session; `load_skill` and `connection_search` appear only when the agent declares the corresponding resources; `ask_question` requires a session that can request user input; and `web_search` requires a supported model provider. The harness advertises only the tools available to the current session.
@@ -19,6 +19,20 @@ const result = await response.result();
19
19
 
20
20
  Cancellation does not replace stream consumption. Continue reading the response to observe its terminal `turn.cancelled` and `session.waiting` boundary and to advance the client session cursor normally.
21
21
 
22
+ Between turns, `session.compact()` queues context compaction without sending model input. An accepted request reports the session id; consume the durable stream through the following `session.waiting` boundary before sending the next turn. `compaction.completed` confirms that summarization succeeded; without it, eve preserves the previous history. A never-started session returns `no_active_session` as a successful no-op.
23
+
24
+ ```ts
25
+ const compaction = await session.compact();
26
+ console.log(compaction.status);
27
+ ```
28
+
29
+ Use `session.clear()` to remove model-message history while retaining the session and its durable resources. Consume `context.cleared` and the following `session.waiting` before sending the next turn.
30
+
31
+ ```ts
32
+ const cleared = await session.clear();
33
+ console.log(cleared.status);
34
+ ```
35
+
22
36
  ## Aggregate a turn
23
37
 
24
38
  Use `result()` when you only need the final turn summary:
@@ -35,13 +35,16 @@ Each command echoes as an invocation line, asks through a bordered panel that ta
35
35
  | Command | Does |
36
36
  | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
37
37
  | `/model` | Opens a configure menu that loops until Done (or Esc). See [Configure the model and provider](#configure-the-model-and-provider). |
38
- | `/add` | Searches registry integrations or adds an item address entered directly. |
38
+ | `/add` | Adds an integration from the registry or an item address entered directly. |
39
39
  | `/deploy` | Ships the agent to Vercel production, linking the directory first when it is unlinked. |
40
40
  | `/vc:install` | Installs the Vercel CLI. Available locally and on a remote session. |
41
41
  | `/vc:login` | Logs in to Vercel locally. On a remote session, resolves the deployment's project, refreshes its OIDC token, and confirms any required Trusted Sources rule. |
42
42
  | `/loglevel` | Switches which logs the transcript shows. See [Control what logs show](#control-what-logs-show). |
43
43
  | `/traces` | Opens the full-screen local trace viewer. See [Inspect traces](#inspect-traces). |
44
- | `/new` | Starts a fresh session. |
44
+ | `/reset` | Starts a fresh session. |
45
+ | `/cancel` | Cooperatively cancels the running turn while preserving the session and settled context. |
46
+ | `/clear` | Clears model-message history while preserving the current session and its durable resources. |
47
+ | `/compact` | Queues context compaction for the current session without sending a message. |
45
48
  | `/exit` | Quits the TUI. |
46
49
  | `/help` | Lists the commands available for the current local or remote session. |
47
50
 
@@ -55,11 +58,11 @@ The provider row opens one menu: AI Gateway via a project, AI Gateway via `AI_GA
55
58
 
56
59
  The provider row demands attention (a bold yellow "Configure model access" with a yellow "Not configured" hint that dims when unselected and uses the terminal foreground when selected) until a link or gateway credential is detected, then names the connection afterward (for example "AI Gateway (Linked to my-project in my-team)"). Setup menus mark the cursor row with a padded, filled-arrow inverse label that inherits the row's accent: blue normally and yellow for warning rows. In stacked menus, the selected row's description appears directly beneath that option. The completed command's outcome stays in the transcript after the panel closes. When a turn fails because AI Gateway authentication is missing or stale, the error points you at `/model` directly.
57
60
 
58
- ### Browse registry integrations
61
+ ### Add registry integrations
59
62
 
60
- `/add` first organizes integrations by what they add: a way to chat, tools and data, capabilities, or observability. Pick a category to open its searchable catalog from the official eve registry and the registry namespaces configured in `package.json`, or browse everything. Each integration shows its source beside its name, such as `Vercel` or a configured registry namespace. Select a result to review its source, packages, environment variables, and target files before adding it, or type an official item path, configured namespace address, or HTTP(S) URL directly into the search bar. After an add attempt finishes, the panel closes instead of returning to the catalog.
63
+ `/add` groups integrations by their role: **Channels** for where people talk to your agent, **MCP connections** for external services and data, **Extensions** for reusable capabilities, and **Observability** for tracing and evaluation. Pick a category to open its searchable catalog from the official eve registry and the registry namespaces configured in `package.json`, or browse every integration. Each result shows its source beside its name, such as `Vercel` or a configured registry namespace. Select a result to review its source, packages, environment variables, and target files before adding it, or enter an official item path, configured namespace address, or HTTP(S) URL directly in the search bar. After an add attempt finishes, the panel closes instead of returning to the catalog.
61
64
 
62
- Connection registry items install their definition and then configure Vercel Connect through the same `/add` flow. If the directory is unlinked, setup first offers to create or link a project. Run `eve add connection/<name>` for the equivalent CLI flow.
65
+ MCP connection registry items install their definition and then configure Vercel Connect through the same `/add` flow. If the directory is unlinked, setup first offers to create or link a project. Run `eve add connection/<name>` for the equivalent CLI flow.
63
66
 
64
67
  ## Keyboard shortcuts
65
68
 
@@ -81,9 +84,9 @@ In terminals that support bracketed paste, pasting multi-line text into chat or
81
84
 
82
85
  ### Queue and steer while the agent works
83
86
 
84
- Sending a message while a turn is still running does not interrupt it — the message joins a queue of up to five, pinned in a panel directly above the input with one line per message. When the turn ends, the queued messages coalesce into the next turn's message.
87
+ Sending a message while a turn is still running does not interrupt it — the message joins a queue of up to five, pinned in a panel directly above the input with one line per message. When the turn ends, the queued messages coalesce into the next turn's message. Submit `/cancel` during a turn to cancel it immediately without queueing the command as model input; `/cancel` also works from the idle prompt when a prior stream disconnected while its server turn may still be running.
85
88
 
86
- `Esc` steers instead of waiting: it pops the oldest queued message, cancels the running turn cooperatively, and submits the popped message as the replacement turn. In the transcript, a steered message carries an accent `↑` on its own line above its gutter bar; a queued message that waited for the boundary carries it below. Any remaining messages stay queued behind it. With nothing queued, the first `Esc` arms cancellation and a second `Esc` cancels the turn. Unlike `Ctrl+C` — which drops the stream client-side — a cancelled turn ends cleanly on the server and the session keeps its context; the conversation picks up at the next prompt.
89
+ `Esc` steers instead of waiting: it pops the oldest queued message, cancels the running turn cooperatively, and submits the popped message as the replacement turn. In the transcript, a steered message carries an accent `↑` on its own line above its gutter bar; a queued message that waited for the boundary carries it below. Any remaining messages stay queued behind it. With nothing queued, one `Esc` cancels the turn immediately. Unlike `Ctrl+C` — which drops the stream client-side — a cancelled turn ends cleanly on the server and the session keeps its context; the conversation picks up at the next prompt.
87
90
 
88
91
  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. Messages still queued when a turn is interrupted or fails are restored into the next prompt's input instead of being sent blind.
89
92
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  title: "Dynamic Capabilities"
3
- description: "Resolve models, tools, skills, and instructions at runtime: dynamic model selection, defineDynamic resolver events, execution order, and durable dynamic tools."
3
+ description: "Resolve models, subagents, tools, skills, and instructions at runtime with defineDynamic resolver events."
4
4
  ---
5
5
 
6
- `defineDynamic` resolves the model, tools, skills, and instructions at runtime from a session event instead of declaring them up front. Reach for it when the right capability isn't known until the session starts, because it hinges 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.
6
+ `defineDynamic` resolves the model, subagents, tools, skills, and instructions at runtime from a session event instead of declaring them up front. Reach for it when the right capability isn't known until the session starts, because it hinges on who the caller is, what tenant they belong to, feature flags, or external data. The [subagents](../subagents), [tools](../tools), [skills](../skills), and [instructions](../instructions) guides each point here for their dynamic form.
7
7
 
8
8
  ## Dynamic models
9
9
 
@@ -16,10 +16,52 @@ uncached prices. See
16
16
  [agent configuration](../agent-config#choose-the-model-dynamically) for the
17
17
  full contract.
18
18
 
19
- `fallback` is model-only: the agent always needs exactly one model, and the
20
- compiled fallback anchors build-time metadata. Tools, skills, and instructions
21
- default by authoring a static entry (or returning `null`), so `fallback` on
22
- their `defineDynamic` export is a build error.
19
+ The agent always needs exactly one model, so the compiled fallback anchors
20
+ build-time metadata. Tools, skills, instructions, and subagents default by
21
+ authoring a static entry (or returning `null`), so `fallback` on their
22
+ `defineDynamic` export is a build error.
23
+
24
+ ## Dynamic subagents
25
+
26
+ Wrap a declared subagent's own `agent.ts` in `defineDynamic` when its
27
+ availability depends on the caller, tenant, environment, or a feature flag.
28
+ Return the child definition to configure and expose it. Return `null` or
29
+ `undefined` to omit it from the parent's model-visible tools.
30
+
31
+ ```ts title="agent/subagents/finance/agent.ts"
32
+ import { defineAgent, defineDynamic } from "eve";
33
+
34
+ export default defineDynamic({
35
+ events: {
36
+ "session.started": (_event, ctx) =>
37
+ ctx.session.auth.current?.attributes.plan === "enterprise"
38
+ ? defineAgent({
39
+ description: "Analyze financial and accounting data.",
40
+ model: "openai/gpt-5.5",
41
+ })
42
+ : null,
43
+ },
44
+ });
45
+ ```
46
+
47
+ eve always compiles the subagent's filesystem manifest, including its
48
+ instructions, tools, skills, connections, sandbox, and nested subagents. When
49
+ the resolver selects it, eve injects the returned agent configuration into that
50
+ compiled manifest. Each resolution can return a different model or other
51
+ runtime agent settings. Runtime-selected models must use string model IDs;
52
+ build and Workflow-world configuration cannot be selected at runtime.
53
+
54
+ Dynamic subagents support `session.started` and `turn.started`. A turn selection
55
+ shadows the session selection for that turn, including when the turn handler
56
+ returns nil. If a resolver throws or returns an invalid definition, eve logs the
57
+ failure and omits the subagent.
58
+
59
+ The resolved set applies to direct delegation and the `Workflow` tool. eve
60
+ also checks availability again before starting the child, so a stale or
61
+ manually constructed call fails with `SUBAGENT_UNAVAILABLE`. Treat conditional
62
+ availability as capability composition, not as the only authorization
63
+ boundary: sensitive child tools still need their own authorization and
64
+ approval checks.
23
65
 
24
66
  ## Dynamic tools
25
67
 
@@ -162,6 +204,7 @@ Both resolve before the prompt is assembled, so the model sees the right instruc
162
204
 
163
205
  ## What to read next
164
206
 
207
+ - Conditionally expose a specialist → [Subagents](../subagents)
165
208
  - The static tool basics this builds on → [Tools](../tools)
166
209
  - The built-in tools and how to override them → [Default harness](../concepts/default-harness)
167
210
  - Authenticate a tool or connection to an external service → [Auth & route protection](./auth-and-route-protection)
@@ -91,7 +91,7 @@ agent/subagents/researcher/
91
91
 
92
92
  Rules:
93
93
 
94
- - `agent.ts` is required, and must declare a `description`. The parent reads it on the lowered subagent tool to decide when to delegate.
94
+ - `agent.ts` is required. A static subagent's definition must declare a `description`; a dynamic subagent's resolver must return a definition with one. The parent reads it on the lowered subagent tool to decide when to delegate.
95
95
  - `instructions.md` / `instructions.ts` is optional (unlike the root agent, where it is required).
96
96
  - `connections/`, `hooks/`, `skills/`, `lib/`, `sandbox/`, and `tools/` are all supported, discovered from the subagent's own directory.
97
97
  - `channels/` and `schedules/` are not supported inside local subagents.
@@ -30,27 +30,27 @@ export default defineTool({
30
30
 
31
31
  ## The define\* helpers
32
32
 
33
- | Helper | Import from | Authored at | Guide |
34
- | ----------------------------------------------------- | --------------------------------------------- | ------------------------------------ | ------------------------------------------------------ |
35
- | `defineAgent` | `eve` | `agent/agent.ts` | [agent.ts](../agent-config) |
36
- | `defineTool` | `eve/tools` | `agent/tools/<name>.ts` | [Tools](../tools) |
37
- | `defineDynamic` | `eve/tools`, `eve/skills`, `eve/instructions` | `agent/{tools,skills,instructions}/` | [Dynamic capabilities](../guides/dynamic-capabilities) |
38
- | `defineMcpClientConnection` | `eve/connections` | `agent/connections/<name>.ts` | [MCP connections](../connections/mcp) |
39
- | `defineOpenAPIConnection` | `eve/connections` | `agent/connections/<name>.ts` | [OpenAPI connections](../connections/openapi) |
40
- | `defineChannel` | `eve/channels` | `agent/channels/<name>.ts` | [Custom channels](../channels/custom) |
41
- | `eveChannel`, `slackChannel`, and the other platforms | `eve/channels/<platform>` | `agent/channels/<platform>.ts` | [Channels](../channels/overview) |
42
- | `defineSkill` | `eve/skills` | `agent/skills/<name>.ts` | [Skills](../skills) |
43
- | `defineInstructions` | `eve/instructions` | `agent/instructions.ts` | [Instructions](../instructions) |
44
- | `defineHook` | `eve/hooks` | `agent/hooks/<slug>.ts` | [Hooks](../guides/hooks) |
45
- | `defineSchedule` | `eve/schedules` | `agent/schedules/<name>.ts` | [Schedules](../schedules) |
46
- | `defineState` | `eve/context` | tools, hooks, lifecycle | [Session context](../guides/session-context) |
47
- | `defineSandbox` | `eve/sandbox` | `agent/sandbox.ts` | [Sandbox](../sandbox) |
48
- | `defineInstrumentation` | `eve/instrumentation` | `agent/instrumentation.ts` | [instrumentation.ts](../guides/instrumentation) |
49
- | `defineRemoteAgent` | `eve` | `agent/subagents/<id>/agent.ts` | [Remote agents](../guides/remote-agents) |
50
- | `defineEval` | `eve/evals` | `evals/*.eval.ts` | [Evals](../evals/overview) |
51
- | `defineEvalConfig` | `eve/evals` | `evals/evals.config.ts` | [Evals](../evals/overview) |
52
- | `mockModel` | `eve/evals` | Deterministic fixture agent models | [Evals](../evals/overview) |
53
- | `useEveAgent` | `eve/react`, `eve/vue`, `eve/svelte` | frontend | [Frontend](../guides/frontend/overview) |
33
+ | Helper | Import from | Authored at | Guide |
34
+ | ----------------------------------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------ |
35
+ | `defineAgent` | `eve` | `agent/agent.ts` | [agent.ts](../agent-config) |
36
+ | `defineTool` | `eve/tools` | `agent/tools/<name>.ts` | [Tools](../tools) |
37
+ | `defineDynamic` | `eve`, `eve/tools`, `eve/skills`, `eve/instructions` | dynamic model or subagent `agent.ts`; `agent/{tools,skills,instructions}/` | [Dynamic capabilities](../guides/dynamic-capabilities) |
38
+ | `defineMcpClientConnection` | `eve/connections` | `agent/connections/<name>.ts` | [MCP connections](../connections/mcp) |
39
+ | `defineOpenAPIConnection` | `eve/connections` | `agent/connections/<name>.ts` | [OpenAPI connections](../connections/openapi) |
40
+ | `defineChannel` | `eve/channels` | `agent/channels/<name>.ts` | [Custom channels](../channels/custom) |
41
+ | `eveChannel`, `slackChannel`, and the other platforms | `eve/channels/<platform>` | `agent/channels/<platform>.ts` | [Channels](../channels/overview) |
42
+ | `defineSkill` | `eve/skills` | `agent/skills/<name>.ts` | [Skills](../skills) |
43
+ | `defineInstructions` | `eve/instructions` | `agent/instructions.ts` | [Instructions](../instructions) |
44
+ | `defineHook` | `eve/hooks` | `agent/hooks/<slug>.ts` | [Hooks](../guides/hooks) |
45
+ | `defineSchedule` | `eve/schedules` | `agent/schedules/<name>.ts` | [Schedules](../schedules) |
46
+ | `defineState` | `eve/context` | tools, hooks, lifecycle | [Session context](../guides/session-context) |
47
+ | `defineSandbox` | `eve/sandbox` | `agent/sandbox.ts` | [Sandbox](../sandbox) |
48
+ | `defineInstrumentation` | `eve/instrumentation` | `agent/instrumentation.ts` | [instrumentation.ts](../guides/instrumentation) |
49
+ | `defineRemoteAgent` | `eve` | `agent/subagents/<id>/agent.ts` | [Remote agents](../guides/remote-agents) |
50
+ | `defineEval` | `eve/evals` | `evals/*.eval.ts` | [Evals](../evals/overview) |
51
+ | `defineEvalConfig` | `eve/evals` | `evals/evals.config.ts` | [Evals](../evals/overview) |
52
+ | `mockModel` | `eve/evals` | Deterministic fixture agent models | [Evals](../evals/overview) |
53
+ | `useEveAgent` | `eve/react`, `eve/vue`, `eve/svelte` | frontend | [Frontend](../guides/frontend/overview) |
54
54
 
55
55
  A few non-`define*` helpers round out the set: `disableTool` and `experimental_workflow` from `eve/tools` (see [Default harness](../concepts/default-harness)), `sleep` from `eve/tools/sleep`, the route verbs `GET`/`POST`/`PUT`/`PATCH`/`DELETE`/`WS` from `eve/channels`, the approval policies `always`/`once`/`never` from `eve/tools/approval`, and the channel auth helpers `localDev`/`vercelOidc`/`placeholderAuth` from `eve/channels/auth`. To wrap a built-in tool, import its default value from `eve/tools/defaults` (`bash`, `readFile`, `writeFile`, `glob`, `grep`, `webFetch`, `webSearch`, `todo`, `loadSkill`). `AgentReasoningDefinition` is exported from `eve` for the top-level `defineAgent({ reasoning })` setting. `AgentLimitsDefinition` is exported for `defineAgent({ limits })`. `AgentWorkflowDefinition` and `AgentWorkflowWorldDefinition` are exported from `eve` for the `defineAgent({ experimental: { workflow } })` config shape. `ExperimentalWorkflowToolInput` is exported from `eve/tools` for the `experimental_workflow(...)` config shape.
56
56
 
@@ -68,33 +68,33 @@ A few non-`define*` helpers round out the set: `disableTool` and `experimental_w
68
68
 
69
69
  ## Imports at a glance
70
70
 
71
- | Import | Holds |
72
- | ----------------------------------------------------------- | --------------------------------------------------------------------- |
73
- | `eve` | `defineAgent`, `defineRemoteAgent`, agent config types |
74
- | `eve/tools` | `defineTool`, `defineDynamic`, `disableTool`, `experimental_workflow` |
75
- | `eve/tools/defaults` | the built-in tools as plain values |
76
- | `eve/tools/approval` | `always`, `once`, `never` |
77
- | `eve/tools/sleep` | opt-in durable `sleep` tool |
78
- | `eve/connections` | `defineMcpClientConnection`, `defineOpenAPIConnection` |
79
- | `eve/channels` | `defineChannel`, route verbs |
80
- | `eve/channels/eve` | `eveChannel` |
81
- | `eve/channels/auth` | `localDev`, `vercelOidc`, `placeholderAuth` |
82
- | `eve/channels/{slack,discord,teams,telegram,twilio,github}` | platform channel factories |
83
- | `eve/hooks` | `defineHook` |
84
- | `eve/schedules` | `defineSchedule` |
85
- | `eve/skills` | `defineSkill`, `defineDynamic` |
86
- | `eve/instructions` | `defineInstructions`, `defineDynamic` |
87
- | `eve/context` | `defineState`, session and state types |
88
- | `eve/sandbox` | `defineSandbox`, backends |
89
- | `eve/instrumentation` | `defineInstrumentation`, `isChannel` |
90
- | `eve/models/openai` | `experimental_chatgpt` |
91
- | `eve/evals` | `defineEval`, `defineEvalConfig`, `mockModel`, eval types |
92
- | `eve/evals/expect` | `includes`, `equals`, `matches`, `similarity` |
93
- | `eve/evals/reporters` | `Braintrust`, `JUnit`, `EvalReporter` |
94
- | `eve/evals/loaders` | `loadJson`, `loadYaml` |
95
- | `eve/react`, `eve/vue`, `eve/svelte` | `useEveAgent` |
96
- | `eve/next`, `eve/nuxt`, `eve/sveltekit` | framework bundler plugins |
97
- | [`eve/client`](../guides/client/overview) | `Client`, `ClientSession` |
71
+ | Import | Holds |
72
+ | ----------------------------------------------------------- | ----------------------------------------------------------------------- |
73
+ | `eve` | `defineAgent`, `defineRemoteAgent`, `defineDynamic`, agent config types |
74
+ | `eve/tools` | `defineTool`, `defineDynamic`, `disableTool`, `experimental_workflow` |
75
+ | `eve/tools/defaults` | the built-in tools as plain values |
76
+ | `eve/tools/approval` | `always`, `once`, `never` |
77
+ | `eve/tools/sleep` | opt-in durable `sleep` tool |
78
+ | `eve/connections` | `defineMcpClientConnection`, `defineOpenAPIConnection` |
79
+ | `eve/channels` | `defineChannel`, route verbs |
80
+ | `eve/channels/eve` | `eveChannel` |
81
+ | `eve/channels/auth` | `localDev`, `vercelOidc`, `placeholderAuth` |
82
+ | `eve/channels/{slack,discord,teams,telegram,twilio,github}` | platform channel factories |
83
+ | `eve/hooks` | `defineHook` |
84
+ | `eve/schedules` | `defineSchedule` |
85
+ | `eve/skills` | `defineSkill`, `defineDynamic` |
86
+ | `eve/instructions` | `defineInstructions`, `defineDynamic` |
87
+ | `eve/context` | `defineState`, session and state types |
88
+ | `eve/sandbox` | `defineSandbox`, backends |
89
+ | `eve/instrumentation` | `defineInstrumentation`, `isChannel` |
90
+ | `eve/models/openai` | `experimental_chatgpt` |
91
+ | `eve/evals` | `defineEval`, `defineEvalConfig`, `mockModel`, eval types |
92
+ | `eve/evals/expect` | `includes`, `equals`, `matches`, `similarity` |
93
+ | `eve/evals/reporters` | `Braintrust`, `JUnit`, `EvalReporter` |
94
+ | `eve/evals/loaders` | `loadJson`, `loadYaml` |
95
+ | `eve/react`, `eve/vue`, `eve/svelte` | `useEveAgent` |
96
+ | `eve/next`, `eve/nuxt`, `eve/sveltekit` | framework bundler plugins |
97
+ | [`eve/client`](../guides/client/overview) | `Client`, `ClientSession` |
98
98
 
99
99
  Exported types ship from the same entrypoint as the helper they describe (for example `ToolDefinition` and `ToolContext` from `eve/tools`). For the exhaustive list, read `packages/eve/src/public/index.ts`.
100
100
 
@@ -47,11 +47,41 @@ export default defineAgent({
47
47
 
48
48
  `description` is required. The parent reads it to decide whether to delegate, so the compiler rejects any subagent whose `agent.ts` leaves it out.
49
49
 
50
+ ### Conditional availability
51
+
52
+ To expose a declared subagent only for certain sessions or turns, export
53
+ `defineDynamic` from that subagent's `agent.ts`. Return a `defineAgent`
54
+ configuration to expose the subagent, or nil to omit it from the parent's tools.
55
+
56
+ ```ts title="agent/subagents/researcher/agent.ts"
57
+ import { defineAgent, defineDynamic } from "eve";
58
+
59
+ export default defineDynamic({
60
+ events: {
61
+ "session.started": (_event, ctx) =>
62
+ ctx.session.auth.current?.attributes.research === true
63
+ ? defineAgent({
64
+ description: "Investigate ambiguous questions before the parent responds.",
65
+ model: "anthropic/claude-opus-4.8",
66
+ })
67
+ : null,
68
+ },
69
+ });
70
+ ```
71
+
72
+ Resolvers run at `session.started` or `turn.started`; `step.started` is not
73
+ supported for subagents. A nil result (`null` or `undefined`) removes the
74
+ subagent's description and tool definition from the model-visible surface.
75
+ The subagent's filesystem manifest is always compiled; a non-nil result injects
76
+ the returned agent configuration when the child runs.
77
+ See [Dynamic capabilities](./guides/dynamic-capabilities#dynamic-subagents) for
78
+ scope precedence, failure behavior, and the dispatch-time guard.
79
+
50
80
  Minimum files:
51
81
 
52
82
  ```text
53
83
  agent/subagents/researcher/
54
- ├── agent.ts # required (must export a description)
84
+ ├── agent.ts # required
55
85
  ├── instructions.md # or instructions.ts, optional
56
86
  ├── tools/ # optional, its own tools
57
87
  ├── skills/ # optional, its own skills
@@ -100,7 +130,7 @@ A declared subagent's tool name is the bare path-derived name, with no prefix. `
100
130
  }
101
131
  ```
102
132
 
103
- Because the name lives in the same runtime tool namespace as authored tools, a subagent named `researcher` collides with a tool named `researcher`. eve rejects the build rather than picking a winner, so keep subagent directory names distinct from tool names.
133
+ Because the name lives in the same runtime tool namespace as authored tools, a subagent named `researcher` collides with a tool named `researcher`. eve rejects static collisions at build time and active dynamic collisions at runtime rather than picking a winner, so keep subagent directory names distinct from tool names.
104
134
 
105
135
  Do not rely on subagent delegation by itself as an approval boundary. Put sensitive tools behind `approval`, connection approval, route/session authorization, or other controls wherever those tools can be called.
106
136
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.29.4",
3
+ "version": "0.29.5",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [
@@ -385,7 +385,7 @@
385
385
  "clean": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"",
386
386
  "build": "pnpm run check:bin-runtime-dependencies && pnpm run build:js && node ./scripts/copy-docs.mjs && node ./scripts/stamp-version-tokens.mjs",
387
387
  "build:compiled": "node ./scripts/vendor-compiled.mjs",
388
- "build:js": "pnpm run build:compiled && pnpm run clean && pnpm run build:types && node ./scripts/copy-compiled-assets.mjs && node ./scripts/build-rolldown.mjs && node ./scripts/copy-runtime-assets.mjs",
388
+ "build:js": "pnpm run build:compiled && pnpm run clean && pnpm run build:types && node ./scripts/copy-compiled-assets.mjs && node --conditions=eve-source ./scripts/build-rolldown.mjs && node ./scripts/copy-runtime-assets.mjs",
389
389
  "build:types": "pnpm run build:compiled && tsc -p tsconfig.build.json",
390
390
  "check:bin-runtime-dependencies": "node ./scripts/check-bin-runtime-dependencies.mjs",
391
391
  "dev": "pnpm run build:compiled && node ./scripts/copy-runtime-assets.mjs && tsc -p tsconfig.dev.json --watch --preserveWatchOutput",