eve 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/src/channel/audience.d.ts +3 -3
  3. package/dist/src/channel/conversation-context.d.ts +4 -2
  4. package/dist/src/channel/conversation-context.js +1 -1
  5. package/dist/src/chunks/{use-eve-agent-CxPlg0KL.js → use-eve-agent-CMdMlS7Y.js} +0 -10
  6. package/dist/src/chunks/{use-eve-agent-D-KQzzyW.js → use-eve-agent-RUGSwq8b.js} +0 -10
  7. package/dist/src/cli/commands/registry-metadata.d.ts +0 -18
  8. package/dist/src/cli/commands/registry-metadata.js +1 -1
  9. package/dist/src/cli/commands/registry-pnpm-build-policy-flow.js +1 -1
  10. package/dist/src/cli/commands/registry.js +1 -1
  11. package/dist/src/cli/dev/tui/blocks.d.ts +2 -0
  12. package/dist/src/cli/dev/tui/blocks.js +3 -3
  13. package/dist/src/cli/dev/tui/markdown.d.ts +8 -1
  14. package/dist/src/cli/dev/tui/markdown.js +7 -7
  15. package/dist/src/cli/dev/tui/runner.d.ts +4 -1
  16. package/dist/src/cli/dev/tui/runner.js +1 -1
  17. package/dist/src/cli/dev/tui/terminal-renderer.d.ts +5 -1
  18. package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
  19. package/dist/src/cli/dev/tui/tui.d.ts +4 -1
  20. package/dist/src/cli/ui/terminal-text.js +1 -1
  21. package/dist/src/client/agent-info-schema.d.ts +0 -57
  22. package/dist/src/client/agent-info-schema.js +1 -1
  23. package/dist/src/compiled/.vendor-stamp.json +1 -1
  24. package/dist/src/compiler/extension-compatibility.d.ts +18 -8
  25. package/dist/src/compiler/extension-compatibility.js +1 -1
  26. package/dist/src/compiler/manifest.d.ts +12 -11
  27. package/dist/src/compiler/manifest.js +1 -1
  28. package/dist/src/compiler/normalize-manifest.js +1 -1
  29. package/dist/src/compiler/normalize-tool.d.ts +0 -3
  30. package/dist/src/compiler/normalize-tool.js +1 -1
  31. package/dist/src/compiler/validate-artifact.js +1 -1
  32. package/dist/src/context/keys.d.ts +2 -0
  33. package/dist/src/context/keys.js +1 -1
  34. package/dist/src/eve-channel/audience.d.ts +2 -2
  35. package/dist/src/eve-channel/audience.js +1 -1
  36. package/dist/src/eve-channel/types.d.ts +5 -5
  37. package/dist/src/execution/coordination-dispatch-step.d.ts +2 -2
  38. package/dist/src/execution/coordination-dispatch-step.js +1 -1
  39. package/dist/src/execution/create-session-step.js +1 -1
  40. package/dist/src/execution/durable-session-store.d.ts +0 -1
  41. package/dist/src/execution/dynamic-workflow/program-step.d.ts +21 -0
  42. package/dist/src/execution/dynamic-workflow/program-step.js +1 -0
  43. package/dist/src/execution/dynamic-workflow/schema.d.ts +36 -0
  44. package/dist/src/execution/dynamic-workflow/schema.js +1 -0
  45. package/dist/src/execution/dynamic-workflow/security-step.d.ts +3 -0
  46. package/dist/src/execution/dynamic-workflow/security-step.js +1 -0
  47. package/dist/src/execution/dynamic-workflow/tool.d.ts +8 -0
  48. package/dist/src/execution/dynamic-workflow/tool.js +1 -0
  49. package/dist/src/execution/dynamic-workflow/workflow.d.ts +10 -0
  50. package/dist/src/execution/dynamic-workflow/workflow.js +1 -0
  51. package/dist/src/execution/eve-workflow-attributes.d.ts +2 -1
  52. package/dist/src/execution/eve-workflow-attributes.js +1 -1
  53. package/dist/src/execution/inline-turn.js +1 -1
  54. package/dist/src/execution/model-call-batching.js +1 -1
  55. package/dist/src/execution/next-driver-action.d.ts +0 -8
  56. package/dist/src/execution/node-step.d.ts +0 -5
  57. package/dist/src/execution/node-step.js +1 -1
  58. package/dist/src/execution/runtime-context.js +1 -1
  59. package/dist/src/execution/session.d.ts +0 -1
  60. package/dist/src/execution/session.js +2 -2
  61. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  62. package/dist/src/execution/tasks/parent/delegate.d.ts +7 -0
  63. package/dist/src/execution/tasks/parent/delegate.js +1 -1
  64. package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
  65. package/dist/src/execution/tools/sleep-workflow.js +1 -1
  66. package/dist/src/execution/tools/subagent/invoke-step.d.ts +2 -0
  67. package/dist/src/execution/tools/subagent/invoke-step.js +1 -1
  68. package/dist/src/execution/turn-workflow.js +1 -1
  69. package/dist/src/execution/workflow-runtime.js +1 -1
  70. package/dist/src/execution/workflow-steps.js +1 -1
  71. package/dist/src/harness/advertised-tools.d.ts +0 -3
  72. package/dist/src/harness/advertised-tools.js +1 -1
  73. package/dist/src/harness/tool-loop.js +2 -2
  74. package/dist/src/harness/types.d.ts +0 -21
  75. package/dist/src/instrumentation/content.js +1 -1
  76. package/dist/src/instrumentation/lifecycle.d.ts +5 -7
  77. package/dist/src/instrumentation/native-events.d.ts +2 -0
  78. package/dist/src/instrumentation/native-events.js +1 -1
  79. package/dist/src/instrumentation/runtime.js +1 -1
  80. package/dist/src/instrumentation/session-context.d.ts +2 -0
  81. package/dist/src/instrumentation/session-context.js +1 -1
  82. package/dist/src/internal/application/package.js +1 -1
  83. package/dist/src/internal/authored-definition/connection.js +1 -1
  84. package/dist/src/internal/authored-definition/schema-backed.d.ts +3 -4
  85. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  86. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  87. package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
  88. package/dist/src/internal/nitro/host/workflow-sandbox-runtime-plugin.js +1 -1
  89. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  90. package/dist/src/public/channels/chat-sdk/audience.d.ts +2 -2
  91. package/dist/src/public/channels/index.d.ts +1 -1
  92. package/dist/src/public/channels/telegram/audience.d.ts +2 -2
  93. package/dist/src/public/connections/index.d.ts +1 -1
  94. package/dist/src/public/definitions/channel.d.ts +1 -1
  95. package/dist/src/public/definitions/connections/mcp.d.ts +1 -1
  96. package/dist/src/public/definitions/connections/openapi.d.ts +1 -1
  97. package/dist/src/public/tools/workflow.d.ts +1 -4
  98. package/dist/src/public/tools/workflow.js +1 -1
  99. package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
  100. package/dist/src/runtime/connections/authorization-tokens.d.ts +2 -4
  101. package/dist/src/runtime/connections/principal.d.ts +6 -6
  102. package/dist/src/runtime/connections/principal.js +1 -1
  103. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  104. package/dist/src/runtime/resolve-agent.js +1 -1
  105. package/dist/src/runtime/resolve-tool.js +1 -1
  106. package/dist/src/runtime/types.d.ts +3 -9
  107. package/dist/src/self-modification/extension/classify-registry-item.d.ts +3 -3
  108. package/dist/src/self-modification/extension/classify-registry-item.js +1 -1
  109. package/dist/src/self-modification/extension/tools/search_registry.d.ts +1 -7
  110. package/dist/src/self-modification/extension/tools/search_registry.js +1 -1
  111. package/dist/src/setup/flows/registry.js +1 -1
  112. package/dist/src/setup/integrations/self-modification/setup.js +1 -1
  113. package/dist/src/setup/scaffold/create/project.js +6 -2
  114. package/dist/src/shared/channel-definition.d.ts +2 -2
  115. package/dist/src/shared/connection-types.d.ts +20 -7
  116. package/dist/src/shared/conversation-context.d.ts +15 -0
  117. package/dist/src/shared/validate-authorization.js +1 -1
  118. package/dist/src/shared/workflow-sandbox.d.ts +18 -12
  119. package/dist/src/shared/workflow-sandbox.js +1 -1
  120. package/dist/src/svelte/index.js +1 -1
  121. package/dist/src/svelte/use-eve-agent.js +1 -1
  122. package/dist/src/tasks/session-index.d.ts +11 -0
  123. package/dist/src/tasks/session-index.js +1 -1
  124. package/dist/src/tools/auth.d.ts +5 -6
  125. package/dist/src/tools/provided/workflow.d.ts +12 -0
  126. package/dist/src/tools/provided/workflow.js +1 -0
  127. package/dist/src/tools/workflow-program-input.d.ts +6 -0
  128. package/dist/src/tools/workflow-program-input.js +1 -0
  129. package/dist/src/tracing/agent-otel-provider.js +1 -1
  130. package/dist/src/tracing/agent-otel-runtime-context.d.ts +2 -1
  131. package/dist/src/tracing/agent-otel-runtime-context.js +1 -1
  132. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  133. package/dist/src/tracing/agent-trace-context-codec.js +1 -1
  134. package/dist/src/tracing/agent-trace-state.d.ts +2 -0
  135. package/dist/src/tracing/content-attributes.js +1 -1
  136. package/dist/src/tracing/local-instrumentation-runtime.d.ts +1 -1
  137. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  138. package/dist/src/vue/index.js +1 -1
  139. package/dist/src/vue/use-eve-agent.js +1 -1
  140. package/docs/agent-config.md +1 -1
  141. package/docs/channels/chat-sdk.mdx +7 -0
  142. package/docs/channels/custom.mdx +16 -6
  143. package/docs/channels/eve.mdx +18 -18
  144. package/docs/channels/linear.mdx +7 -3
  145. package/docs/channels/overview.mdx +13 -0
  146. package/docs/channels/slack.mdx +9 -1
  147. package/docs/connections/mcp.mdx +4 -1
  148. package/docs/connections/openapi.mdx +8 -2
  149. package/docs/connections/overview.mdx +16 -13
  150. package/docs/getting-started.mdx +1 -1
  151. package/docs/guides/deployment/self-hosting.md +1 -1
  152. package/docs/guides/deployment/vercel.mdx +2 -2
  153. package/docs/guides/dev-tui.md +4 -4
  154. package/docs/guides/dynamic-capabilities.md +4 -4
  155. package/docs/guides/hooks.md +1 -1
  156. package/docs/guides/instrumentation/meta.json +4 -0
  157. package/docs/guides/instrumentation/otel.mdx +149 -0
  158. package/docs/guides/instrumentation/overview.md +199 -0
  159. package/docs/guides/instrumentation/providers.mdx +169 -0
  160. package/docs/guides/meta.json +0 -1
  161. package/docs/guides/remote-agents.md +19 -21
  162. package/docs/install-integrations.mdx +2 -4
  163. package/docs/patterns/multi-tenant-auth.md +3 -3
  164. package/docs/reference/cli.md +14 -14
  165. package/docs/reference/typescript-api.md +9 -9
  166. package/docs/subagents/index.mdx +2 -2
  167. package/docs/tools/workflows.mdx +56 -1
  168. package/package.json +1 -1
  169. package/dist/src/cli/commands/registry-package.d.ts +0 -52
  170. package/dist/src/cli/commands/registry-package.js +0 -1
  171. package/dist/src/harness/workflow-continuation-security.d.ts +0 -5
  172. package/dist/src/harness/workflow-continuation-security.js +0 -1
  173. package/dist/src/harness/workflow-interrupt-state.d.ts +0 -20
  174. package/dist/src/harness/workflow-interrupt-state.js +0 -1
  175. package/dist/src/harness/workflow-lifecycle.d.ts +0 -32
  176. package/dist/src/harness/workflow-lifecycle.js +0 -1
  177. package/dist/src/harness/workflow-sandbox.d.ts +0 -28
  178. package/dist/src/harness/workflow-sandbox.js +0 -2
  179. package/dist/src/harness/workflow-subagent-limit.d.ts +0 -28
  180. package/dist/src/harness/workflow-subagent-limit.js +0 -1
  181. package/dist/src/harness/workflow-task-state.d.ts +0 -9
  182. package/dist/src/harness/workflow-task-state.js +0 -1
  183. package/dist/src/harness/workflow-tool-description.d.ts +0 -22
  184. package/dist/src/harness/workflow-tool-description.js +0 -37
  185. package/dist/src/tools/workflow.d.ts +0 -37
  186. package/dist/src/tools/workflow.js +0 -1
  187. package/docs/guides/instrumentation-providers.md +0 -249
  188. package/docs/guides/instrumentation.md +0 -453
@@ -312,27 +312,37 @@ The projection is re-evaluated whenever adapter state changes after channel even
312
312
 
313
313
  ### Conversation audience
314
314
 
315
- Use `audience(input)` to classify who can observe the conversation. The hook runs after route authentication and before the session is created:
315
+ Use `audience(input)` to assign an observability audience. The audience controls
316
+ whether instrumentation may capture conversation content. The hook runs after
317
+ route authentication and before the session is created:
316
318
 
317
319
  ```ts
318
320
  import { defineChannel, POST } from "eve/channels";
319
321
 
320
322
  export default defineChannel({
321
323
  state: { visibility: "workspace" as "workspace" | "private" | "unknown" },
322
- audience({ state, auth }) {
324
+ audience({ state, caller }) {
323
325
  if (state.visibility === "workspace") return "public";
324
- if (auth?.principalType === "user") return "private";
326
+ if (caller.type === "principal" && caller.principal.kind === "user") return "private";
325
327
  return "unknown";
326
328
  },
327
329
  routes: [POST("/webhook", async () => new Response("ok"))],
328
330
  });
329
331
  ```
330
332
 
331
- The input contains the channel's `state`, authenticated `auth` principal, `channel`, `mode`, and `environment`. Return `"public"`, `"private"`, or `"unknown"`. Return `"unknown"` when the channel does not have enough evidence to classify confidently; consumers treat it as non-public. A missing, throwing, asynchronous, or malformed classifier also fails closed to `"unknown"`.
333
+ The input contains the channel's `state`, `caller`, `channel`, `mode`, and `environment`. A principal caller omits `principalId`, `issuer`, and `subject`, but its `attributes` come from route auth and can still contain identifying values. Return `"public"`, `"private"`, or `"unknown"`. Return `"unknown"` when the channel does not have enough evidence to classify confidently; consumers treat it as non-public. A missing, throwing, asynchronous, or malformed classifier also fails closed to `"unknown"`.
332
334
 
333
- Classification is fixed when the session is created. Continuation turns from a different caller do not reclassify an existing session. When a parent dispatches a local subagent, the child inherits the parent's audience while the framework forwards the parent's custom channel metadata separately.
335
+ When you explicitly annotate a callback, use `AudienceContext<TState>`. `AudienceInput<TState>` remains supported for existing callbacks while you migrate.
336
+
337
+ Existing callbacks can continue using `auth?.principalType` while you migrate:
338
+
339
+ ```ts
340
+ audience({ auth }) {
341
+ return auth?.principalType === "user" ? "private" : "unknown";
342
+ }
343
+ ```
334
344
 
335
- `metadata(state)` remains a channel-owned projection of custom observability fields. It no longer carries a reserved `audience` key. Channel extensions built before channel epoch 20 can still use that key; eve accepts it as a deprecated fallback and warns once, then authors should move classification to `audience(input)`.
345
+ Classification is fixed when the session is created. Continuation turns from a different caller do not reclassify an existing session. When a parent dispatches a local subagent, the child inherits the parent's audience while the framework forwards the parent's custom channel metadata separately.
336
346
 
337
347
  ## Continuation tokens
338
348
 
@@ -159,42 +159,42 @@ For the full auth model and helper list, see [Auth & route protection](../guides
159
159
 
160
160
  ## Audience
161
161
 
162
- The eve channel classifies who can observe a session when that session is created:
162
+ The eve channel assigns an observability audience when it creates a session. The
163
+ audience controls whether instrumentation may capture session content:
163
164
 
164
165
  | Session creator | Default audience |
165
166
  | ----------------------------------------- | ---------------- |
166
- | Anonymous caller | `public` |
167
+ | Anonymous caller | `unknown` |
167
168
  | `user`, `service`, or `runtime` principal | `private` |
168
169
  | Any other principal type | `unknown` |
169
170
 
170
- Anonymous HTTP surfaces are public because anyone who can reach the surface can read it. Authenticated `user`, `service`, and `runtime` sessions are private because they belong to one identified party. Other authenticated principal types remain `unknown`: trace consumers record metadata but omit content by default in preview and production.
171
+ Anonymous HTTP surfaces are `unknown` by default because reachability does not establish that their content is safe to record. Authenticated `user`, `service`, and `runtime` sessions are private because they belong to one identified party. Other authenticated principal types also remain `unknown`: trace consumers record metadata but omit content by default in preview and production. Set an explicit `audience: "public"` only for intentionally public traffic.
171
172
 
172
- Pass a constant or a function to override the default:
173
+ For a production endpoint whose conversations are all intentionally public,
174
+ set a constant audience:
173
175
 
174
176
  ```ts title="agent/channels/eve.ts"
175
- import { none, vercelOidc } from "eve/channels/auth";
177
+ import { vercelOidc } from "eve/channels/auth";
176
178
  import { eveChannel } from "eve/channels/eve";
177
179
 
178
180
  export default eveChannel({
179
181
  auth: [vercelOidc()],
180
- audience: "private",
182
+ audience: "public",
181
183
  });
182
184
  ```
183
185
 
184
- ```ts title="agent/channels/eve.ts"
185
- import { vercelOidc } from "eve/channels/auth";
186
- import { eveChannel } from "eve/channels/eve";
186
+ `audience` controls observability content capture; it does not change who may
187
+ call the endpoint. `auth` still controls access. For a classification that
188
+ depends on channel state or application-specific verified data, use a [custom
189
+ channel audience](./custom#conversation-audience).
187
190
 
188
- export default eveChannel({
189
- auth: [vercelOidc(), none()],
190
- audience({ auth, environment }) {
191
- if (auth === null) return environment === "development" ? "public" : "unknown";
192
- return "private";
193
- },
194
- });
195
- ```
191
+ You can also pass a function that receives `caller`, channel, run mode, and
192
+ deployment environment. Classification is fixed at session creation, so a later
193
+ turn from a different caller does not reclassify the session.
196
194
 
197
- The function receives the authenticated principal, channel, run mode, and deployment environment. Classification is fixed at session creation; a continuation turn from a different caller does not reclassify the session. When another eve deployment forwards a request without an accepted forwarded trace assertion, the calling deployment's principal is used for classification, so the session remains `private`. A custom [trace policy](../guides/instrumentation-providers#control-inputs-and-outputs) can still admit or deny content independently.
195
+ For a remote agent, a trusted dispatch can forward the original audience and
196
+ its trace-content ceiling. See [Preserving trace
197
+ content](../guides/remote-agents#preserving-trace-content).
198
198
 
199
199
  ## Customization
200
200
 
@@ -11,12 +11,16 @@ The Linear channel uses Linear's Agent Session surface rather than ordinary comm
11
11
  Run the registry setup from the agent directory:
12
12
 
13
13
  ```bash
14
- eve add linear
14
+ eve add channel/linear
15
15
  ```
16
16
 
17
- Select **Linear Channel** in the component checklist. **Linear MCP** is also selected by default if you want the agent to search and update Linear through MCP. Run `eve add channel/linear-agent` instead to install only the channel directly.
17
+ To let the agent search and update Linear through MCP, install the separate Linear connection:
18
18
 
19
- The flow signs you in to Vercel when needed, creates or links a Vercel project, reuses a compatible existing connector when available or provisions an app-scoped Linear Connect client, and registers `/eve/v1/linear` as a trigger destination. It then installs `@vercel/connect` and writes `agent/channels/linear.ts` with the connector UID.
19
+ ```bash
20
+ eve add connection/linear
21
+ ```
22
+
23
+ The channel setup flow signs you in to Vercel when needed, creates or links a Vercel project, reuses a compatible existing connector when available or provisions an app-scoped Linear Connect client, and registers `/eve/v1/linear` as a trigger destination. It then installs `@vercel/connect` and writes `agent/channels/linear.ts` with the connector UID.
20
24
 
21
25
  Vercel Connect creates the Linear app with the `app:assignable` and `app:mentionable` scopes required for Agent Sessions, receives and verifies `AgentSessionEvent` webhooks, and forwards them to the deployed agent. After deploying, open the Linear app in the Connect dashboard and install it in the workspace where you want to delegate work. Then delegate an issue or mention the agent in a Linear Agent Session.
22
26
 
@@ -13,6 +13,19 @@ eve ships a base HTTP channel plus first-class platform channels, and you can au
13
13
 
14
14
  After a channel normalizes input, eve runs the same agent runtime regardless of where the message came from. Tools and instructions do not need channel-specific logic.
15
15
 
16
+ ## Audience
17
+
18
+ When a channel creates a session, it assigns an observability audience:
19
+ `public`, `private`, or `unknown`. The audience controls trace content capture,
20
+ not who may call the channel. Each channel uses the visibility information it
21
+ has; `unknown` is the safe default when it cannot classify a conversation.
22
+
23
+ Route auth controls access and supplies the session principal. See [Auth &
24
+ route protection](../guides/auth-and-route-protection) for principal types and
25
+ authorization. See the [default eve HTTP channel](./eve#audience) for its
26
+ mapping, or [custom channels](./custom#conversation-audience) to classify your
27
+ own.
28
+
16
29
  ## Overlapping messages
17
30
 
18
31
  Channels default to `turnPolicy: "steer"`. When an accepted message arrives while a turn is active, eve first durably buffers the message, then cooperatively cancels the active turn and starts a replacement turn. The cancelled turn emits `turn.cancelled` followed by `session.waiting`; the replacement starts with a new turn ID. Output already streamed and completed side effects are not rolled back.
@@ -137,6 +137,14 @@ Check the delivery path in order so you can identify where a Slack event stops:
137
137
  | A preview request receives an authentication page or protection error | Check whether the branch domain is exempt or the direct Slack request URL includes `x-vercel-protection-bypass`. Slack cannot complete an interactive Vercel Authentication challenge. | Add a Deployment Protection Exception for the branch domain, or add the automation bypass query parameter to a Slack app that uses environment-variable credentials. |
138
138
  | The webhook reaches the deployment but the agent does not reply | Open the project's Vercel runtime logs, then inspect the session in **Agent Runs** when your team has access. | Use the first missing or failed stage to narrow the issue to channel dispatch, the agent run, or outbound Slack delivery. |
139
139
 
140
+ ## Audience
141
+
142
+ Slack public channels are `public`; DMs, group DMs, and private channels are
143
+ `private`. When an inbound event does not identify the conversation type, eve
144
+ checks Slack and treats an ambiguous or failed lookup as `private`. The audience
145
+ controls observability content capture, not access to the channel. See
146
+ [Audience](./overview#audience) for the shared channel model.
147
+
140
148
  ## How the channel handles inbound events
141
149
 
142
150
  ### Message hooks
@@ -501,7 +509,7 @@ The private authorization button uses the label **Sign in**, so long connection
501
509
 
502
510
  ### Proactive sessions
503
511
 
504
- Start a session without an inbound message through `ctx.to(slack, target).send(message, { auth })` from another channel, or `to(slack, target).send(message, { auth })` from a schedule `run` handler. The proactive target shape is `{ channelId, installationTeamId?, threadTs?, initialMessage? }`. Set `installationTeamId` to the app installation workspace when a function-form bot token must select an installation. This sends turn input to the agent; it is not a direct Slack post.
512
+ Start a session without an inbound message through `ctx.to(slack, target).send(message, { auth })` from another channel, or `to(slack, target).send(message, { auth })` from a schedule `run` handler. The proactive target shape is `{ channelId, installationTeamId?, threadTs?, initialMessage?, audience? }`. It defaults to `unknown`; pass `audience` only when the caller already knows the destination's visibility. Set `installationTeamId` to the app installation workspace when a function-form bot token must select an installation. This sends turn input to the agent; it is not a direct Slack post.
505
513
 
506
514
  To post without invoking the model, use `ctx.thread.post(...)` in an inbound Slack handler or `channel.thread.post(...)` in an `events` handler. Use `callSlackApi(...)` where no Slack channel context exists. For application-managed retries and deduplication, see [Durable cross-channel notifications](../patterns/durable-cross-channel-notifications).
507
515
 
@@ -125,7 +125,10 @@ const publishesNow = (input: unknown): boolean => {
125
125
  export default defineMcpClientConnection({
126
126
  url: "https://mcp.example.com/mcp",
127
127
  description: "Social publishing: draft, schedule, and manage posts.",
128
- auth: { getToken: async () => ({ token: process.env.SOCIAL_API_KEY! }) },
128
+ auth: {
129
+ credentialOwner: "app",
130
+ getToken: async () => ({ token: process.env.SOCIAL_API_KEY! }),
131
+ },
129
132
  approval: ({ toolName, toolInput }) => {
130
133
  if (DELETE_TOOLS.some((t) => toolName.includes(t))) return "user-approval";
131
134
  if (PUBLISH_TOOLS.some((t) => toolName.includes(t))) {
@@ -17,7 +17,10 @@ import { defineOpenAPIConnection } from "eve/connections";
17
17
  export default defineOpenAPIConnection({
18
18
  spec: "https://petstore3.swagger.io/api/v3/openapi.json",
19
19
  description: "Pet store inventory and orders.",
20
- auth: { getToken: async () => ({ token: process.env.PETSTORE_TOKEN! }) },
20
+ auth: {
21
+ credentialOwner: "app",
22
+ getToken: async () => ({ token: process.env.PETSTORE_TOKEN! }),
23
+ },
21
24
  });
22
25
  ```
23
26
 
@@ -102,7 +105,10 @@ import { defineOpenAPIConnection } from "eve/connections";
102
105
  export default defineOpenAPIConnection({
103
106
  spec: "https://petstore3.swagger.io/api/v3/openapi.json",
104
107
  description: "Pet store inventory and orders.",
105
- auth: { getToken: async () => ({ token: process.env.PETSTORE_TOKEN! }) },
108
+ auth: {
109
+ credentialOwner: "app",
110
+ getToken: async () => ({ token: process.env.PETSTORE_TOKEN! }),
111
+ },
106
112
  operations: { allow: ["getInventory", "placeOrder"] },
107
113
  });
108
114
  ```
@@ -69,6 +69,7 @@ export default defineMcpClientConnection({
69
69
  url: "https://mcp.linear.app/mcp",
70
70
  description: "Linear workspace.",
71
71
  auth: {
72
+ credentialOwner: "app",
72
73
  getToken: async () => ({ token: process.env.LINEAR_API_TOKEN! }),
73
74
  },
74
75
  });
@@ -76,7 +77,7 @@ export default defineMcpClientConnection({
76
77
 
77
78
  If the token has a known TTL, set `expiresAt` (milliseconds since epoch) and eve refreshes ahead of time rather than waiting for a `401`.
78
79
 
79
- When `getToken` is the only auth, `principalType` defaults to `"app"`: one shared credential keyed across all sessions. Switch to `principalType: "user"` when each end-user carries their own token.
80
+ When `getToken` is the only auth, `credentialOwner` defaults to `"app"`: one shared credential keyed across all sessions. Set `credentialOwner: "user"` when each end-user carries their own token.
80
81
 
81
82
  eve resolves and caches connection tokens per step; they never land in conversation history or reach the model.
82
83
 
@@ -86,11 +87,13 @@ A connection credential can belong to the agent or to the person using it. This
86
87
 
87
88
  | Credential owner | Use when | Auth shape |
88
89
  | ---------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
89
- | App | The agent should use one shared service, bot, installation, or app credential. | `auth: { getToken }` defaults to `principalType: "app"`, or use `connect({ connector: "linear/myagent", principalType: "app" })` with Vercel Connect. |
90
- | User | Each end-user should authorize and use their own third-party account. | `connect("linear/myagent")`, `connect({ connector: "linear/myagent", principalType: "user" })`, or `auth: { principalType: "user", getToken }`. |
90
+ | App | The agent should use one shared service, bot, installation, or app credential. | `auth: { getToken }` defaults to `credentialOwner: "app"`, or use `connect({ connector: "linear/myagent", principalType: "app" })` with Vercel Connect. |
91
+ | User | Each end-user should authorize and use their own third-party account. | `connect("linear/myagent")`, `connect({ connector: "linear/myagent", principalType: "user" })`, or `auth: { credentialOwner: "user", getToken }`. |
91
92
  | User from a job | Background work should use the same user's OAuth grant that started the work. | Start or resume the session through a channel whose route auth resolved that user, or pass an explicit user auth context when dispatching through a channel. |
92
93
 
93
- `principalType: "user"` does not mean "ask any human later." It means "key this credential to the authenticated user already attached to the eve session." If the run was started by a schedule, a same-project runtime token, `localDev()`, or another internal runtime path without an end-user principal, a user-scoped connection fails with `reason: "principal_required"` instead of starting OAuth. In that case, either authenticate the inbound channel as a user or configure the connection as app-scoped.
94
+ `credentialOwner: "user"` does not mean "ask any human later." It means "key this credential to the authenticated user already attached to the eve session." If the run was started by a schedule, a same-project runtime token, `localDev()`, or another internal runtime path without an end-user principal, a user-scoped connection fails with `reason: "principal_required"` instead of starting OAuth. In that case, either authenticate the inbound channel as a user or configure the connection as app-scoped.
95
+
96
+ `credentialOwner` is eve's field for raw getToken-only connection auth. Existing non-interactive raw `principalType` definitions still work, but are deprecated. Interactive auth and `connect()` from `@vercel/connect/eve` continue to use `principalType: "user"`; that field also remains correct for route-auth session identities.
94
97
 
95
98
  ## No auth
96
99
 
@@ -132,7 +135,7 @@ export default defineOpenAPIConnection({
132
135
  spec: "https://warehouse.example.com/openapi.json",
133
136
  description: "The caller's tenant-scoped warehouse.",
134
137
  auth: (ctx) => ({
135
- principalType: "user",
138
+ credentialOwner: "user",
136
139
  getToken: async () => ({
137
140
  token: await tenantToken(ctx.session.auth.current),
138
141
  }),
@@ -151,7 +154,7 @@ headers: {
151
154
  }
152
155
  ```
153
156
 
154
- Use `principalType: "user"` for per-user tokens so eve rejects unauthenticated callers and keys its step-local token cache by user. The resolver supplements route auth; it does not authenticate the inbound request. Static auth objects and header maps remain available when every caller shares the same configuration.
157
+ Use `credentialOwner: "user"` for per-user tokens so eve rejects unauthenticated callers and keys its step-local token cache by user. The resolver supplements route auth; it does not authenticate the inbound request. Static auth objects and header maps remain available when every caller shares the same configuration.
155
158
 
156
159
  ## Per-connection approval
157
160
 
@@ -223,16 +226,16 @@ App-scoped Connect auth is non-interactive. eve asks Vercel Connect for an app t
223
226
 
224
227
  ### Troubleshooting Vercel Connect auth
225
228
 
226
- | Symptom | What it means | Fix |
227
- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
228
- | `reason: "principal_required"` | A user-scoped connection ran without an authenticated user on the active session. | Return `principalType: "user"` from the channel's route auth, or change the connection to `principalType: "app"` if it should be shared. |
229
- | `authorization.required` appears but no UI | eve parked the turn for OAuth, but the channel or frontend is not rendering the challenge. | Render the challenge from the stream event and continue the same session after the callback. |
230
- | OAuth works locally but fails after deploy | The project may not be linked to the Connect client, or the deployed runtime may not have the expected Vercel OIDC/project scope. | Run Connect setup from the consuming project directory, link the project, deploy again, and verify the connector UID in `connect("...")`. |
231
- | A scheduled or internal run needs user OAuth | Schedules and runtime callers do not automatically carry an end-user principal. | Dispatch through a user-authenticated channel when work is user-owned, or use app-scoped auth for agent-owned background work. |
229
+ | Symptom | What it means | Fix |
230
+ | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
231
+ | `reason: "principal_required"` | A user-scoped connection ran without an authenticated user on the active session. | Return `principalType: "user"` from the channel's route auth, or use `connect({ connector, principalType: "app" })` if the Connect credential should be shared. |
232
+ | `authorization.required` appears but no UI | eve parked the turn for OAuth, but the channel or frontend is not rendering the challenge. | Render the challenge from the stream event and continue the same session after the callback. |
233
+ | OAuth works locally but fails after deploy | The project may not be linked to the Connect client, or the deployed runtime may not have the expected Vercel OIDC/project scope. | Run Connect setup from the consuming project directory, link the project, deploy again, and verify the connector UID in `connect("...")`. |
234
+ | A scheduled or internal run needs user OAuth | Schedules and runtime callers do not automatically carry an end-user principal. | Dispatch through a user-authenticated channel when work is user-owned, or use app-scoped auth for agent-owned background work. |
232
235
 
233
236
  ## Self-hosted interactive OAuth
234
237
 
235
- To run your own OAuth, use `defineInteractiveAuthorization` from `eve/connections`, which takes a three-method form and needs no Vercel Connect. eve mints a callback URL, parks (durably suspends) the turn on a framework-owned webhook, and resumes once the token comes back. Interactive auth is always `principalType: "user"`, and the factory pins that for you.
238
+ To run your own OAuth, use `defineInteractiveAuthorization` from `eve/connections`, which takes a three-method form and needs no Vercel Connect. eve mints a callback URL, parks (durably suspends) the turn on a framework-owned webhook, and resumes once the token comes back. Interactive auth is always `principalType: "user"`; `credentialOwner` applies only to getToken-only auth, and the factory pins the interactive value for you.
236
239
 
237
240
  ```ts title="agent/connections/linear.ts"
238
241
  import {
@@ -156,7 +156,7 @@ Prefer the nested layout because it keeps application files separate from the au
156
156
 
157
157
  ### Debug file discovery
158
158
 
159
- Run `eve info` when eve does not discover a file. It lists the discovered surface and diagnostics so you can check the authored slot and root-versus-subagent boundary. eve also writes inspectable artifacts under `.eve/`; see [Observability](./guides/instrumentation) and the [CLI](./reference/cli) reference.
159
+ Run `eve info` when eve does not discover a file. It lists the discovered surface and diagnostics so you can check the authored slot and root-versus-subagent boundary. eve also writes inspectable artifacts under `.eve/`; see [Instrumentation](./observability/instrumentation) and the [CLI](./reference/cli) reference.
160
160
 
161
161
  ## Install manually
162
162
 
@@ -84,5 +84,5 @@ eve dev https://your_agent.example.com
84
84
  Use these guides to secure and observe the deployed agent:
85
85
 
86
86
  - [Authentication](../auth-and-route-protection): configure the host’s route policy
87
- - [Observability](../instrumentation): export traces and diagnose runtime failures
87
+ - [Instrumentation](../../observability/instrumentation): export traces and diagnose runtime failures
88
88
  - [Sandbox](../../sandbox): select and secure a sandbox backend
@@ -158,12 +158,12 @@ Set `VERCEL_AUTOMATION_BYPASS_SECRET` locally before connecting if the deploymen
158
158
 
159
159
  Vercel detects eve and can add an **Agent Runs** tab under the project’s **Observability** view. Use it to browse sessions and inspect each conversation trace.
160
160
 
161
- The Agent Runs tab requires enablement for your Vercel team. Contact your Vercel representative if the tab doesn’t appear. For third-party tracing backends, configure [OpenTelemetry instrumentation](../instrumentation).
161
+ The Agent Runs tab requires enablement for your Vercel team. Contact your Vercel representative if the tab doesn’t appear. For third-party tracing backends, configure [OpenTelemetry instrumentation](../../observability/instrumentation).
162
162
 
163
163
  ## Continue configuring production
164
164
 
165
165
  Use these guides to secure and observe the deployed agent:
166
166
 
167
167
  - [Authentication](../auth-and-route-protection): configure who can call the deployed agent
168
- - [Observability](../instrumentation): export traces and diagnose runtime failures
168
+ - [Instrumentation](../../observability/instrumentation): export traces and diagnose runtime failures
169
169
  - [Sandbox](../../sandbox): configure resources, isolation, and network access
@@ -49,7 +49,7 @@ Pass an item address to `/add` to confirm and install that exact address without
49
49
  ```text
50
50
  /add channel/slack
51
51
  /add extension/agent-browser
52
- /add linear
52
+ /add channel/linear
53
53
  /add @acme/analytics
54
54
  ```
55
55
 
@@ -77,7 +77,7 @@ By default, the UI shows `stderr` logs. Use `/loglevel <all|stderr|sandbox|none>
77
77
 
78
78
  Every `eve dev` process writes diagnostic logs to `.eve/logs/`, regardless of the display mode. Read them with [`eve logs`](../reference/cli#eve-logs).
79
79
 
80
- Use `/traces` to inspect traces recorded during local development. See [Instrumentation](instrumentation#local-traces) for trace capture and retention settings.
80
+ Use `/traces` to inspect traces recorded during local development. See [Instrumentation](../observability/instrumentation#local-traces) for trace capture and retention settings.
81
81
 
82
82
  ## Display options
83
83
 
@@ -87,7 +87,7 @@ Use `eve dev` flags to control tool calls, reasoning, subagents, connection auth
87
87
  eve dev --tools full --reasoning collapsed --logs all
88
88
  ```
89
89
 
90
- Use `--host` and `--port` to bind the local server, or `--no-ui` to run without the terminal UI. See the [`eve dev` CLI reference](../reference/cli#eve-dev) for the complete option list, accepted values, and defaults.
90
+ Use `--host` and `--port` to bind the local server, or `--no-ui` to run without the terminal UI. Set `EVE_TUI_RENDER_MARKDOWN=0` to show assistant and subagent responses without Markdown parsing or styling; `1` (the default) enables Markdown rendering. See the [`eve dev` CLI reference](../reference/cli#eve-dev) for the complete option list, accepted values, and defaults.
91
91
 
92
92
  ## Connect to a deployment
93
93
 
@@ -108,6 +108,6 @@ For a Vercel deployment that needs authentication, run `/vc:login` and follow th
108
108
 
109
109
  ## What to read next
110
110
 
111
- - [Instrumentation](./instrumentation): traces, OpenTelemetry, and diagnostics.
111
+ - [Instrumentation](../observability/instrumentation): traces, OpenTelemetry, and diagnostics.
112
112
  - [CLI](../reference/cli): commands and flags.
113
113
  - [Agent Client Protocol (ACP)](../protocols/acp): drive the same agent from ACP clients such as Zed instead of the TUI.
@@ -136,9 +136,9 @@ shadows the session selection for that turn, including when the turn handler
136
136
  returns `null`. If a resolver throws or returns an invalid definition, eve logs the
137
137
  failure and omits the subagent.
138
138
 
139
- The resolved set applies to local and remote direct delegation. Background subagents are not
140
- exposed inside the model-authored `Workflow` tool. eve
141
- also checks availability again before starting the child, so a stale or
139
+ The resolved set applies to local and remote direct delegation. An authored workflow tool can
140
+ also call a selected subagent through `ctx.agent`. A generated program can call it through the
141
+ provided `workflow` tool. eve checks availability again before starting the child, so a stale or
142
142
  manually constructed call fails with `SUBAGENT_UNAVAILABLE`. Treat conditional
143
143
  availability as capability composition, not as the only authorization
144
144
  boundary: sensitive child tools still need their own authorization and
@@ -178,7 +178,7 @@ export default defineDynamic({
178
178
  description: `${account.label} (${account.accountId})`,
179
179
  instanceKey: account.accountId,
180
180
  auth: {
181
- principalType: "user",
181
+ credentialOwner: "user",
182
182
  getToken: ({ principal }) => mintAccountToken(principal, account),
183
183
  },
184
184
  }),
@@ -50,7 +50,7 @@ export default githubChannel({
50
50
 
51
51
  A GitHub channel event handler cannot fire for a Slack-owned session, so platform-specific side effects do not depend on an early-return guard. On a built-in channel, an authored handler replaces that channel's default handler for the same event key. Check the channel page before overriding events that deliver replies, progress, errors, or human-input prompts.
52
52
 
53
- Use `ctx.channel.kind` inside a global hook only when the operation is otherwise agent-wide and conditional handling is intentional. For typed channel metadata in dynamic resolvers or instrumentation, import the channel definition and narrow with `isChannel`; see [Instrumentation](./instrumentation#runtime-context).
53
+ Use `ctx.channel.kind` inside a global hook only when the operation is otherwise agent-wide and conditional handling is intentional. For typed channel metadata in dynamic resolvers or instrumentation, import the channel definition and narrow with `isChannel`; see [Add runtime context](../observability/instrumentation#add-runtime-context).
54
54
 
55
55
  ## Hook structure and context
56
56
 
@@ -0,0 +1,4 @@
1
+ {
2
+ "title": "Observability",
3
+ "pages": ["overview", "providers", "otel"]
4
+ }
@@ -0,0 +1,149 @@
1
+ ---
2
+ title: "OpenTelemetry"
3
+ description: "Configure OpenTelemetry destinations, content capture, and managed exports with Instrumentation Providers."
4
+ url: "/observability/otel"
5
+ ---
6
+
7
+ <Callout type="warning" title="Experimental">
8
+ This API is experimental and may change without a deprecation period.
9
+ </Callout>
10
+
11
+ Use the built-in APIs from `eve/instrumentation/otel` to configure eve's
12
+ OpenTelemetry pipeline. This page requires the experimental
13
+ [Instrumentation Providers](./instrumentation-providers) layout.
14
+
15
+ ## Configure OpenTelemetry
16
+
17
+ OpenTelemetry configuration has two parts:
18
+
19
+ - `otel()` declares process-wide settings such as the resource, sampler,
20
+ propagators, and trace capture policy. Declare it at most once.
21
+ - `otelIntegration()` adds one destination. Declare one file per exporter or
22
+ processor chain.
23
+
24
+ Add `agent/instrumentation/otel.ts` when you need process-wide settings or
25
+ want to control the content eve writes to OpenTelemetry spans:
26
+
27
+ ```ts title="agent/instrumentation/otel.ts"
28
+ import { otel } from "eve/instrumentation/otel";
29
+
30
+ export default otel({
31
+ resource: { "deployment.environment": process.env.VERCEL_ENV ?? "development" },
32
+ tracePolicy: ({ audience, environment }) => ({
33
+ emit: true,
34
+ recordInputs: audience === "public" || environment === "development",
35
+ recordOutputs: audience === "public" || environment === "development",
36
+ }),
37
+ });
38
+ ```
39
+
40
+ The OpenTelemetry `tracePolicy` is a capture ceiling shared by every OTel
41
+ destination. A destination cannot restore content excluded by this policy. It
42
+ does not affect lifecycle-event providers created with `defineInstrumentation()`.
43
+
44
+ ## Add an OpenTelemetry destination
45
+
46
+ Most agents only need a destination:
47
+
48
+ ```ts title="agent/instrumentation/braintrust.ts"
49
+ import { BraintrustExporter } from "@braintrust/otel";
50
+ import { otelIntegration } from "eve/instrumentation/otel";
51
+
52
+ export default otelIntegration({
53
+ traceExporter: new BraintrustExporter({ filterAISpans: true }),
54
+ });
55
+ ```
56
+
57
+ Pass `spanProcessors` to `otelIntegration()` when a custom destination needs
58
+ filtering or transformation. `exportPolicy` is for the built-in
59
+ `localTraces()` and `agentRuns()` destinations below.
60
+
61
+ ## Trace topology
62
+
63
+ OpenTelemetry destinations receive the following trace topology for an ordinary
64
+ agent turn:
65
+
66
+ ```text
67
+ invoke_agent <agent>
68
+ └── agent.step
69
+ ├── chat <model>
70
+ └── agent.action
71
+ └── execute_tool <tool>
72
+ ```
73
+
74
+ Each turn starts a new trace. The first subagent trace links to its caller with
75
+ `eve.link.type=agent.dispatch`. Use `gen_ai.conversation.id` to find the traces
76
+ for one conversation in your destination's span-search surface.
77
+
78
+ ## Manage built-in destinations
79
+
80
+ The provider layout has two environment-specific defaults:
81
+
82
+ - `local` records local traces during `eve dev`.
83
+ - `agent-runs` exports to Vercel Agent Runs in preview and production
84
+ deployments.
85
+
86
+ Omitting these files preserves the defaults. Reconfigure a destination by
87
+ exporting `localTraces()` or `agentRuns()` from the matching file. Disable one
88
+ explicitly:
89
+
90
+ ```ts title="agent/instrumentation/local.ts"
91
+ import { disableInstrumentation } from "eve/instrumentation";
92
+
93
+ export default disableInstrumentation();
94
+ ```
95
+
96
+ ## Filter a managed destination
97
+
98
+ `localTraces()` and `agentRuns()` accept an `exportPolicy`. It filters spans
99
+ and attributes before that destination's processors receive them:
100
+
101
+ ```ts title="agent/instrumentation/agent-runs.ts"
102
+ import { agentRuns } from "eve/instrumentation/otel";
103
+
104
+ export default agentRuns({
105
+ exportPolicy: {
106
+ span: ({ name }) => name !== "internal.cache.refresh",
107
+ attribute: ({ key }) => (key === "customer.id" ? { action: "drop" } : { action: "keep" }),
108
+ },
109
+ });
110
+ ```
111
+
112
+ Return `false` from `span` to omit that span from this destination. Return
113
+ `{ action: "keep" }`, `{ action: "drop" }`, or
114
+ `{ action: "replace", value }` from `attribute` to retain, remove, or change
115
+ one attribute.
116
+
117
+ ### Further narrow a built-in destination
118
+
119
+ Use the content redactors to further narrow what a built-in destination
120
+ receives after the process-wide `otel({ tracePolicy })` has admitted a trace.
121
+ For example, keep the spans in Agent Runs while redacting their inputs and
122
+ outputs unless the session is public:
123
+
124
+ ```ts title="agent/instrumentation/agent-runs.ts"
125
+ import {
126
+ agentRuns,
127
+ composeSpanExportPolicies,
128
+ redactSpanInputs,
129
+ redactSpanOutputs,
130
+ } from "eve/instrumentation/otel";
131
+
132
+ export default agentRuns({
133
+ exportPolicy: composeSpanExportPolicies(
134
+ redactSpanInputs(({ audience }) => audience !== "public"),
135
+ redactSpanOutputs(({ audience }) => audience !== "public"),
136
+ ),
137
+ });
138
+ ```
139
+
140
+ `redactSpanInputs()` removes eve's known prompt, instruction, document, and
141
+ tool-argument attributes. `redactSpanOutputs()` removes response, reasoning,
142
+ tool-result, exception, and status attributes. They narrow only this
143
+ destination; they do not mutate spans sent to another destination.
144
+
145
+ ## What to read next
146
+
147
+ - [Instrumentation Providers](./instrumentation-providers): add lifecycle-event providers.
148
+ - [Instrumentation](../observability/instrumentation): configure the current single-file API.
149
+ - [Local development](../guides/dev-tui): inspect local traces in the TUI.