eve 0.30.8 → 0.31.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 (211) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +5 -6
  3. package/dist/src/acp/adapter.d.ts +10 -4
  4. package/dist/src/acp/adapter.js +1 -1
  5. package/dist/src/channel/adapter-context.d.ts +1 -1
  6. package/dist/src/channel/adapter.d.ts +2 -4
  7. package/dist/src/channel/adapter.js +1 -1
  8. package/dist/src/channel/channel-address.d.ts +58 -0
  9. package/dist/src/channel/channel-address.js +1 -0
  10. package/dist/src/channel/channel-operations.d.ts +72 -0
  11. package/dist/src/channel/channel-operations.js +1 -0
  12. package/dist/src/channel/compiled-channel.d.ts +10 -6
  13. package/dist/src/channel/cross-channel-receive.d.ts +13 -25
  14. package/dist/src/channel/cross-channel-receive.js +2 -2
  15. package/dist/src/channel/receive-target.d.ts +1 -2
  16. package/dist/src/channel/routes.d.ts +21 -149
  17. package/dist/src/channel/schedule.d.ts +1 -1
  18. package/dist/src/channel/schedule.js +1 -1
  19. package/dist/src/channel/send-input.d.ts +6 -0
  20. package/dist/src/channel/send-input.js +1 -0
  21. package/dist/src/channel/session.d.ts +44 -30
  22. package/dist/src/channel/session.js +1 -1
  23. package/dist/src/channel/types.d.ts +8 -35
  24. package/dist/src/chunks/{use-eve-agent-DDoDDmJ2.js → use-eve-agent-CF5D6jSV.js} +339 -367
  25. package/dist/src/chunks/{use-eve-agent-Bx-ONuyb.js → use-eve-agent-DbYZLG0h.js} +342 -368
  26. package/dist/src/cli/commands/agent-prompt/build-and-verify.md +1 -2
  27. package/dist/src/cli/commands/channel-add-conflicts.js +1 -1
  28. package/dist/src/cli/commands/info.d.ts +1 -1
  29. package/dist/src/cli/commands/info.js +1 -1
  30. package/dist/src/cli/dev/tui/runner.d.ts +1 -1
  31. package/dist/src/cli/dev/tui/runner.js +1 -1
  32. package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
  33. package/dist/src/cli/dev/tui/tui.js +1 -1
  34. package/dist/src/cli/invoke/invoke.d.ts +1 -1
  35. package/dist/src/cli/invoke/invoke.js +1 -1
  36. package/dist/src/cli/invoke/result.d.ts +0 -11
  37. package/dist/src/cli/invoke/result.js +1 -1
  38. package/dist/src/client/client-error.d.ts +2 -0
  39. package/dist/src/client/client-error.js +1 -1
  40. package/dist/src/client/client.d.ts +7 -14
  41. package/dist/src/client/client.js +1 -1
  42. package/dist/src/client/eve-agent-store.d.ts +4 -4
  43. package/dist/src/client/eve-agent-store.js +1 -1
  44. package/dist/src/client/index.d.ts +2 -1
  45. package/dist/src/client/index.js +1 -1
  46. package/dist/src/client/message-response.d.ts +2 -7
  47. package/dist/src/client/message-response.js +1 -1
  48. package/dist/src/client/open-stream.js +1 -1
  49. package/dist/src/client/session-controls.d.ts +29 -0
  50. package/dist/src/client/session-controls.js +1 -0
  51. package/dist/src/client/session-utils.d.ts +0 -20
  52. package/dist/src/client/session-utils.js +1 -1
  53. package/dist/src/client/session.d.ts +26 -90
  54. package/dist/src/client/session.js +1 -1
  55. package/dist/src/client/sessions.d.ts +20 -0
  56. package/dist/src/client/sessions.js +1 -0
  57. package/dist/src/client/types.d.ts +26 -47
  58. package/dist/src/compiler/normalize-subagent.js +1 -1
  59. package/dist/src/evals/cli/eval-client.js +1 -1
  60. package/dist/src/evals/context.js +1 -1
  61. package/dist/src/evals/session.d.ts +7 -6
  62. package/dist/src/evals/session.js +1 -1
  63. package/dist/src/evals/types.d.ts +9 -9
  64. package/dist/src/execution/agent-handle-dispatch.js +1 -1
  65. package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
  66. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  67. package/dist/src/execution/remote-agent-dispatch.d.ts +1 -3
  68. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  69. package/dist/src/execution/runtime-context.js +1 -1
  70. package/dist/src/execution/runtime-errors.d.ts +1 -1
  71. package/dist/src/execution/session-command-token.d.ts +2 -0
  72. package/dist/src/execution/session-command-token.js +1 -1
  73. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  74. package/dist/src/execution/subagent-hitl-proxy.js +1 -1
  75. package/dist/src/execution/turn-control-receiver.d.ts +2 -2
  76. package/dist/src/execution/turn-workflow.js +1 -1
  77. package/dist/src/execution/workflow-entry.js +1 -1
  78. package/dist/src/execution/workflow-runtime.js +1 -1
  79. package/dist/src/harness/cancelled-turn-emission.d.ts +1 -1
  80. package/dist/src/harness/cancelled-turn-emission.js +1 -1
  81. package/dist/src/harness/emission.d.ts +1 -1
  82. package/dist/src/harness/emission.js +1 -1
  83. package/dist/src/harness/handles/prompt.d.ts +22 -3
  84. package/dist/src/harness/handles/prompt.js +1 -1
  85. package/dist/src/harness/handles/store.d.ts +0 -5
  86. package/dist/src/harness/handles/store.js +1 -1
  87. package/dist/src/harness/runtime-actions.js +1 -1
  88. package/dist/src/harness/session-limit-enforcement.js +1 -1
  89. package/dist/src/harness/tool-loop.js +1 -1
  90. package/dist/src/internal/application/package.js +1 -1
  91. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  92. package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
  93. package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.d.ts +15 -0
  94. package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.js +1 -0
  95. package/dist/src/internal/nitro/dev-runtime-source-snapshot.d.ts +14 -2
  96. package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
  97. package/dist/src/internal/nitro/host/dev-server-http.js +1 -1
  98. package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +2 -5
  99. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  100. package/dist/src/internal/nitro/routes/channel-route-context.d.ts +4 -3
  101. package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
  102. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  103. package/dist/src/protocol/cancel-turn.d.ts +9 -4
  104. package/dist/src/protocol/cancel-turn.js +1 -1
  105. package/dist/src/protocol/message.d.ts +4 -14
  106. package/dist/src/protocol/message.js +2 -2
  107. package/dist/src/protocol/reset-session.d.ts +1 -1
  108. package/dist/src/protocol/routes.d.ts +27 -47
  109. package/dist/src/protocol/routes.js +1 -1
  110. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +19 -21
  111. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  112. package/dist/src/public/channels/discord/discordChannel.d.ts +4 -4
  113. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  114. package/dist/src/public/channels/eve.d.ts +11 -10
  115. package/dist/src/public/channels/eve.js +1 -1
  116. package/dist/src/public/channels/github/dispatch.d.ts +8 -8
  117. package/dist/src/public/channels/github/dispatch.js +1 -1
  118. package/dist/src/public/channels/github/githubChannel.d.ts +3 -3
  119. package/dist/src/public/channels/github/githubChannel.js +1 -1
  120. package/dist/src/public/channels/github/pr-context.d.ts +1 -1
  121. package/dist/src/public/channels/index.d.ts +1 -1
  122. package/dist/src/public/channels/linear/linearChannel.d.ts +3 -3
  123. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  124. package/dist/src/public/channels/slack/index.d.ts +1 -1
  125. package/dist/src/public/channels/slack/interactions.d.ts +3 -4
  126. package/dist/src/public/channels/slack/interactions.js +1 -1
  127. package/dist/src/public/channels/slack/session-operations.d.ts +37 -0
  128. package/dist/src/public/channels/slack/session-operations.js +1 -0
  129. package/dist/src/public/channels/slack/slackChannel.d.ts +55 -74
  130. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  131. package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -3
  132. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  133. package/dist/src/public/channels/telegram/telegramChannel.d.ts +4 -4
  134. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  135. package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -3
  136. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  137. package/dist/src/public/definitions/callback-context.d.ts +1 -2
  138. package/dist/src/public/definitions/channel.d.ts +21 -86
  139. package/dist/src/public/definitions/channel.js +1 -1
  140. package/dist/src/public/definitions/remote-agent.js +1 -1
  141. package/dist/src/public/definitions/schedule.d.ts +16 -16
  142. package/dist/src/public/schedules/index.d.ts +1 -1
  143. package/dist/src/react/use-eve-agent.d.ts +7 -4
  144. package/dist/src/react/use-eve-agent.js +1 -1
  145. package/dist/src/runtime/agent/bootstrap-model-utils.d.ts +11 -0
  146. package/dist/src/runtime/agent/bootstrap-model-utils.js +1 -1
  147. package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
  148. package/dist/src/runtime/agent/mock-model-fixtures.js +2 -2
  149. package/dist/src/runtime/prompt/compose.js +1 -1
  150. package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
  151. package/dist/src/runtime/types.d.ts +2 -2
  152. package/dist/src/services/inspect-application.d.ts +1 -1
  153. package/dist/src/services/inspect-application.js +1 -1
  154. package/dist/src/setup/channel-add-conflicts.js +1 -1
  155. package/dist/src/setup/scaffold/create/project.js +1 -1
  156. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  157. package/dist/src/setup/scaffold/create/web-template.js +29 -17
  158. package/dist/src/shared/channel-definition.d.ts +7 -7
  159. package/dist/src/shared/schedule-definition.d.ts +2 -2
  160. package/dist/src/svelte/index.js +1 -1
  161. package/dist/src/svelte/use-eve-agent.d.ts +8 -5
  162. package/dist/src/svelte/use-eve-agent.js +1 -1
  163. package/dist/src/vue/index.js +1 -1
  164. package/dist/src/vue/use-eve-agent.d.ts +8 -5
  165. package/dist/src/vue/use-eve-agent.js +1 -1
  166. package/docs/README.md +6 -6
  167. package/docs/channels/chat-sdk.mdx +5 -6
  168. package/docs/channels/custom.mdx +116 -144
  169. package/docs/channels/discord.mdx +1 -1
  170. package/docs/channels/eve.mdx +76 -30
  171. package/docs/channels/github.mdx +1 -1
  172. package/docs/channels/linear.mdx +6 -8
  173. package/docs/channels/overview.mdx +2 -2
  174. package/docs/channels/slack.mdx +46 -15
  175. package/docs/channels/telegram.mdx +1 -1
  176. package/docs/channels/twilio.mdx +1 -1
  177. package/docs/concepts/default-harness.md +11 -3
  178. package/docs/concepts/execution-model-and-durability.mdx +17 -5
  179. package/docs/concepts/sessions-runs-and-streaming.md +42 -16
  180. package/docs/evals/cases.mdx +3 -3
  181. package/docs/evals/targets.mdx +1 -1
  182. package/docs/guides/auth-and-route-protection.md +2 -1
  183. package/docs/guides/client/continuations.mdx +50 -77
  184. package/docs/guides/client/messages.mdx +29 -33
  185. package/docs/guides/client/output-schema.mdx +7 -14
  186. package/docs/guides/client/overview.mdx +40 -11
  187. package/docs/guides/client/streaming.mdx +17 -23
  188. package/docs/guides/frontend/nuxt.mdx +1 -1
  189. package/docs/guides/frontend/overview.mdx +40 -36
  190. package/docs/guides/frontend/sveltekit.mdx +1 -1
  191. package/docs/guides/frontend/use-eve-agent-svelte.mdx +19 -23
  192. package/docs/guides/frontend/use-eve-agent-vue.mdx +21 -25
  193. package/docs/guides/instrumentation.md +1 -1
  194. package/docs/patterns/dynamic-scheduling.md +16 -15
  195. package/docs/schedules.mdx +10 -11
  196. package/docs/subagents.mdx +1 -1
  197. package/docs/tools/human-in-the-loop.md +1 -1
  198. package/docs/tutorial/ship-it.mdx +1 -1
  199. package/package.json +1 -1
  200. package/dist/src/channel/cancel.d.ts +0 -6
  201. package/dist/src/channel/cancel.js +0 -1
  202. package/dist/src/channel/clear-session.d.ts +0 -4
  203. package/dist/src/channel/clear-session.js +0 -1
  204. package/dist/src/channel/compact-session.d.ts +0 -4
  205. package/dist/src/channel/compact-session.js +0 -1
  206. package/dist/src/channel/reset-session.d.ts +0 -6
  207. package/dist/src/channel/reset-session.js +0 -1
  208. package/dist/src/channel/resolve-active-session.d.ts +0 -4
  209. package/dist/src/channel/resolve-active-session.js +0 -1
  210. package/dist/src/channel/send.d.ts +0 -6
  211. package/dist/src/channel/send.js +0 -1
@@ -25,16 +25,17 @@ const { data } = useEveAgent();
25
25
 
26
26
  ## What it returns
27
27
 
28
- | Property | Type | Description |
29
- | --------- | -------------------------------------------- | ------------------------------------------------------------------------- |
30
- | `data` | `ComputedRef<TData>` | Projected state. With the default reducer, `EveMessageData` (`messages`). |
31
- | `status` | `ComputedRef<UseEveAgentStatus>` | `"ready"`, `"submitted"`, `"streaming"`, or `"error"`. |
32
- | `error` | `ComputedRef<Error \| undefined>` | Last transport-level error. |
33
- | `events` | `ComputedRef<readonly MessageStreamEvent[]>` | Raw server events for this session. |
34
- | `session` | `ComputedRef<SessionState>` | Snapshot of session state. |
35
- | `send` | `(input: SendTurnPayload) => Promise<void>` | Send text or a full turn (multi-part, attachments, HITL responses). |
36
- | `stop` | `() => void` | Abort the client's in-flight stream. |
37
- | `reset` | `() => void` | Clear state and start a new session. |
28
+ | Property | Type | Description |
29
+ | --------- | ---------------------------------------------- | ------------------------------------------------------------------------- |
30
+ | `data` | `ComputedRef<TData>` | Projected state. With the default reducer, `EveMessageData` (`messages`). |
31
+ | `status` | `ComputedRef<UseEveAgentStatus>` | `"ready"`, `"submitted"`, `"streaming"`, or `"error"`. |
32
+ | `error` | `ComputedRef<Error \| undefined>` | Last transport-level error. |
33
+ | `events` | `ComputedRef<readonly MessageStreamEvent[]>` | Raw server events for this session. |
34
+ | `session` | `ComputedRef<ClientSessionState \| undefined>` | Fixed session ID and stream cursor. |
35
+ | `send` | `(message, options?) => Promise<void>` | Send text or a multi-part message. |
36
+ | `respond` | `(inputResponses, options?) => Promise<void>` | Answer pending HITL input requests. |
37
+ | `stop` | `() => void` | Abort the client's in-flight stream. |
38
+ | `reset` | `() => void` | Clear state and start a new session. |
38
39
 
39
40
  The first five are `ComputedRef`s; the rest are methods. Destructure whatever you need, since refs keep their reactivity through destructuring. Read them with `.value` in `<script>`, and unwrapped in `<template>`.
40
41
 
@@ -52,7 +53,7 @@ async function handleSubmit() {
52
53
  const text = message.value.trim();
53
54
  if (!text) return;
54
55
  message.value = "";
55
- await send({ message: text });
56
+ await send(text);
56
57
  }
57
58
  </script>
58
59
 
@@ -77,24 +78,22 @@ async function onFileChange(event: Event) {
77
78
  if (!file) return;
78
79
  const bytes = new Uint8Array(await file.arrayBuffer());
79
80
  const base64 = btoa(String.fromCodePoint(...bytes));
80
- await send({
81
- message: [
82
- { type: "text", text: "Describe this image." },
83
- { type: "file", data: `data:${file.type};base64,${base64}`, mediaType: file.type },
84
- ],
85
- });
81
+ await send([
82
+ { type: "text", text: "Describe this image." },
83
+ { type: "file", data: `data:${file.type};base64,${base64}`, mediaType: file.type },
84
+ ]);
86
85
  }
87
86
  </script>
88
87
  ```
89
88
 
90
89
  ## Human-in-the-loop prompts
91
90
 
92
- A tool opts into approval with `approval` ([Tools](../../tools)). When it triggers, the pending request shows up as a `dynamic-tool` part on the latest message at `part.toolMetadata?.eve?.inputRequest`. Read it, then answer through the same session with `send({ inputResponses })`:
91
+ A tool opts into approval with `approval` ([Tools](../../tools)). When it triggers, the pending request shows up as a `dynamic-tool` part on the latest message at `part.toolMetadata?.eve?.inputRequest`. Read it, then answer through the same session with `respond(inputResponses)`:
93
92
 
94
93
  ```ts
95
94
  import type { EveDynamicToolPart, EveMessagePart } from "eve/vue";
96
95
 
97
- const { data, send } = useEveAgent();
96
+ const { data, respond } = useEveAgent();
98
97
 
99
98
  const isDynamicToolPart = (part: EveMessagePart): part is EveDynamicToolPart =>
100
99
  part.type === "dynamic-tool";
@@ -106,9 +105,7 @@ const request = data.value.messages
106
105
  .find((value) => value !== undefined);
107
106
 
108
107
  if (request) {
109
- await send({
110
- inputResponses: [{ requestId: request.requestId, optionId: "approve" }],
111
- });
108
+ await respond([{ requestId: request.requestId, optionId: "approve" }]);
112
109
  }
113
110
  ```
114
111
 
@@ -143,11 +140,10 @@ const agent = useEveAgent({
143
140
 
144
141
  ## Attach page context per turn
145
142
 
146
- `clientContext` adds ephemeral context for the next model call and nothing more. Strings (or an array of strings) become user-role context messages; an object is JSON-serialized into one. It rides along with a message or HITL response, never dispatches a turn on its own, and never lands in durable session history. Pass it to `send()`:
143
+ `clientContext` adds ephemeral context for the next model call and nothing more. Strings (or an array of strings) become user-role context messages; an object is JSON-serialized into one. It rides along with a message or HITL response, never dispatches a turn on its own, and never lands in durable session history. Pass it in the second argument to `send()` or `respond()`:
147
144
 
148
145
  ```ts
149
- await send({
150
- message: "What should I do on this screen?",
146
+ await send("What should I do on this screen?", {
151
147
  clientContext: { route: "/billing", plan: "pro", seatsUsed: 4 },
152
148
  });
153
149
  ```
@@ -181,7 +181,7 @@ When `eve build` fails on discovery errors, the CLI prints the full diagnostics
181
181
  | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
182
182
  | Tool not discovered (the model never sees it) | Run `eve info`. Confirm the file is in the right slot (`agent/tools/<name>.ts`) and default-exports `defineTool(...)`, and check `.eve/diagnostics.json` for shape errors. `schedules/` are root-only. |
183
183
  | Model won't call a tool it should | Tighten the tool `description` and `inputSchema`; put procedural guidance in a [skill](../skills), not the description. Confirm it's in the active set with `eve info`. |
184
- | Stuck on `session.waiting` | The turn is parked on an approval, a question, or a connection sign-in. Answer it, or POST a follow-up with the `continuationToken` (a stale token is rejected). |
184
+ | Stuck on `session.waiting` | The turn is parked for input. Answer the pending approval or question, or POST a follow-up to `/eve/v1/session/:sessionId`. |
185
185
  | 401 on production routes | Expected: auth fails closed. Replace `placeholderAuth()` with your route policy. Use `vercelOidc()` only for Vercel-issued tokens; otherwise configure `httpBasic()`, JWT/OIDC helpers, or a custom `AuthFn`. See [Auth and route protection](./auth-and-route-protection). |
186
186
  | Build fails with discovery errors | Read the printed diagnostics and `.eve/diagnostics.json`; confirm the root-vs-subagent boundary is valid and secrets come from env vars. |
187
187
 
@@ -35,7 +35,7 @@ import { scheduleStore } from "../lib/schedule-store";
35
35
 
36
36
  export default defineSchedule({
37
37
  cron: "* * * * *",
38
- run({ receive, waitUntil }) {
38
+ run({ to, waitUntil }) {
39
39
  waitUntil(
40
40
  (async () => {
41
41
  const jobs = await scheduleStore.claimDue({
@@ -47,25 +47,26 @@ export default defineSchedule({
47
47
  await Promise.all(
48
48
  jobs.map(async (job) => {
49
49
  try {
50
- await receive(slack, {
51
- message: [
50
+ await to(slack, { channelId: job.channelId }).send(
51
+ [
52
52
  `Run dynamic schedule ${job.id}.`,
53
53
  "Complete this tenant-owned task:",
54
54
  job.prompt,
55
55
  ].join("\n\n"),
56
- target: { channelId: job.channelId },
57
- auth: {
58
- attributes: {
59
- tenantId: job.tenantId,
60
- role: job.ownerRole,
61
- scheduleId: job.id,
56
+ {
57
+ auth: {
58
+ attributes: {
59
+ tenantId: job.tenantId,
60
+ role: job.ownerRole,
61
+ scheduleId: job.id,
62
+ },
63
+ authenticator: job.authenticator,
64
+ ...(job.issuer ? { issuer: job.issuer } : {}),
65
+ principalId: job.ownerId,
66
+ principalType: "user",
62
67
  },
63
- authenticator: job.authenticator,
64
- ...(job.issuer ? { issuer: job.issuer } : {}),
65
- principalId: job.ownerId,
66
- principalType: "user",
67
68
  },
68
- });
69
+ );
69
70
  await scheduleStore.complete(job);
70
71
  } catch (error) {
71
72
  await scheduleStore.release(job, { error, retryAt: new Date(Date.now() + 300_000) });
@@ -78,7 +79,7 @@ export default defineSchedule({
78
79
  });
79
80
  ```
80
81
 
81
- `waitUntil` keeps the cron invocation alive until claiming and handoff settle. `receive` starts the same durable runtime used by inbound channel messages.
82
+ `waitUntil` keeps the cron invocation alive until claiming and handoff settle. `to(...).send(...)` starts the same durable runtime used by inbound channel messages.
82
83
 
83
84
  This example uses Slack because it has a proactive target of `{ channelId }`. Any channel that implements `receive` can replace it.
84
85
 
@@ -19,7 +19,7 @@ interface ScheduleDefinition {
19
19
  }
20
20
 
21
21
  interface ScheduleHandlerArgs {
22
- receive: CrossChannelReceiveFn; // hand the work off to a channel
22
+ to: ScheduleToFn; // select a channel target, then send
23
23
  waitUntil: (task: Promise<unknown>) => void; // keep the cron task alive past return
24
24
  appAuth: SessionAuthContext; // pre-built app principal
25
25
  }
@@ -56,7 +56,7 @@ Sweep stale workflow state.
56
56
 
57
57
  ## Handler form (`run`)
58
58
 
59
- Use a handler when the schedule needs to deliver to a channel, branch on conditions, or compute its arguments at fire time. The handler is in full control. It has no channel of its own, so it passes the work to one with `receive`.
59
+ Use a handler when the schedule needs to deliver to a channel, branch on conditions, or compute its arguments at fire time. The handler is in full control. It has no channel of its own, so it selects a channel target with `to(...)` and sends through the returned handle.
60
60
 
61
61
  ```ts title="agent/schedules/critical-alerts.ts"
62
62
  import { defineSchedule } from "eve/schedules";
@@ -65,13 +65,12 @@ import slack from "../channels/slack";
65
65
 
66
66
  export default defineSchedule({
67
67
  cron: "* * * * *",
68
- async run({ receive, waitUntil, appAuth }) {
68
+ async run({ to, waitUntil, appAuth }) {
69
69
  waitUntil(
70
- receive(slack, {
71
- message: "Check for new critical alerts. Report only when there are any.",
72
- target: { channelId: "C0123ABC" },
73
- auth: appAuth,
74
- }),
70
+ to(slack, { channelId: "C0123ABC" }).send(
71
+ "Check for new critical alerts. Report only when there are any.",
72
+ { auth: appAuth },
73
+ ),
75
74
  );
76
75
  },
77
76
  });
@@ -79,9 +78,9 @@ export default defineSchedule({
79
78
 
80
79
  The agent does not have to deliver a message on every run. When a prompt makes delivery conditional, as in the alert check above, eve tells the agent how to finish successfully without sending anything to the channel. Frequent polling schedules do not need a separate filter or delivery setting.
81
80
 
82
- - `receive(channel, { message, target, auth })`: starts a session on another channel. Same contract as a route handler's `args.receive`.
83
- - `waitUntil(promise)`: extends the cron task's lifetime so the parked session and any in-flight fetches settle before the task ends. Wrap the `receive` call in it.
84
- - `appAuth`: the app principal (`{ authenticator: "app", principalId: "eve:app", principalType: "runtime" }`). Pass it as `receive(..., { auth: appAuth })` for work the agent does on its own behalf.
81
+ - `to(channel, target).send(message, { auth })`: starts a session on another channel. It has the same contract as a route handler's `ctx.to(...)` handle.
82
+ - `waitUntil(promise)`: extends the cron task's lifetime so the parked session and any in-flight fetches settle before the task ends. Wrap the `send` call in it.
83
+ - `appAuth`: the app principal (`{ authenticator: "app", principalId: "eve:app", principalType: "runtime" }`). Pass it as `to(...).send(..., { auth: appAuth })` for work the agent does on its own behalf.
85
84
 
86
85
  A handler-form session runs on the same durable runtime engine as any other session, so it can park (durably suspend), for instance when the channel handoff is waiting for a Slack reply. Only markdown task mode is barred from waiting.
87
86
 
@@ -192,7 +192,7 @@ Without the opt-in, delegated children run as one-shot tasks: they answer once a
192
192
 
193
193
  With it enabled, a child parks after answering instead of terminating, keeping its session and conversation history alive. A failed child turn can also leave the child parked — its latest status shows the error and the parent may message it again. Pass a parked child's `agentId` to the same subagent tool with a new `message` to continue that session. Omitting `agentId` (or passing an empty string or `null`) always starts a new child, and an `agentId` that matches no known agent falls back to starting a new child rather than failing. Passing a known `agentId` through a different subagent tool fails with `AGENT_MISMATCH`, and messaging a child that is still starting or working on its previous request fails with `AGENT_BUSY` — wait for its result before continuing it.
194
194
 
195
- On every model call, eve injects a system message containing an `<agents>` block listing the currently parked (resumable) children — each entry carries the `agentId`, name, and latest status. It is a per-call injection, not part of the conversation history: it always reflects the current state, never accumulates stale copies, and children that are starting or running do not appear until they park again.
195
+ Whenever the set of parked (resumable) children changes, eve appends a framework-injected note to the conversation — labeled `[Agents]` and carrying an `<agents>` block — listing each child's `agentId`, name, and latest status. The static system prompt tells the model the note is injected by eve, not written by the user. The note is appended only when the listing changes (an append-only design that preserves the provider prompt cache), the most recent note is authoritative, and children that are starting or running do not appear until they park again.
196
196
 
197
197
  The parent holds agent handles only for its session lifetime. When the parent session ends, eve terminates its local children. Remote children are not terminated on parent shutdown — that is a known gap: a parked remote child stays alive on its own deployment until that deployment's own lifecycle ends it. For [remote agents](./guides/remote-agents), both deployments must run the same eve version to use agent messaging.
198
198
 
@@ -58,7 +58,7 @@ Gating a side effect on approval is also how you make non-idempotent work safe a
58
58
 
59
59
  ### Skipping approval for schedule-dispatched turns
60
60
 
61
- `session.auth.current` identifies the caller of this turn. Markdown schedules use the app principal (`authenticator: "app"`, `principalId: "eve:app"`, `principalType: "runtime"`) automatically. A `run` schedule must pass its `appAuth` to `receive(...)` for the child session to use that principal. Match all three fields to skip approval for automated turns while still prompting when a person calls the same tool:
61
+ `session.auth.current` identifies the caller of this turn. Markdown schedules use the app principal (`authenticator: "app"`, `principalId: "eve:app"`, `principalType: "runtime"`) automatically. A `run` schedule must pass its `appAuth` to `send(...)` for the child session to use that principal. Match all three fields to skip approval for automated turns while still prompting when a person calls the same tool:
62
62
 
63
63
  ```ts title="agent/tools/refund_charge.ts"
64
64
  import { defineTool } from "eve/tools";
@@ -43,7 +43,7 @@ export function AgentChat() {
43
43
  event.preventDefault();
44
44
  const data = new FormData(event.currentTarget);
45
45
  const message = String(data.get("q") ?? "").trim();
46
- if (message) void agent.send({ message });
46
+ if (message) void agent.send(message);
47
47
  }}
48
48
  >
49
49
  {agent.data.messages.map((message) => (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.30.8",
3
+ "version": "0.31.0",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [
@@ -1,6 +0,0 @@
1
- import type { CancelFn } from "#channel/routes.js";
2
- import type { Runtime } from "#channel/types.js";
3
- /**
4
- * Builds the route-handler `cancel` helper for one channel.
5
- */
6
- export declare function createCancelFn(runtime: Runtime, channelName: string): CancelFn;
@@ -1 +0,0 @@
1
- function createCancelFn(e,t){return async n=>await e.dispatchContinuation({command:{kind:`cancel`,turnId:n.turnId},continuationToken:`${t}:${n.continuationToken}`})}export{createCancelFn};
@@ -1,4 +0,0 @@
1
- import type { ClearFn } from "#channel/routes.js";
2
- import type { Runtime } from "#channel/types.js";
3
- /** Builds a channel-scoped context-clear helper. */
4
- export declare function createClearFn(runtime: Runtime, channelName: string): ClearFn;
@@ -1 +0,0 @@
1
- function createClearFn(e,t){return async n=>await e.dispatchContinuation({command:{kind:`clear`},continuationToken:`${t}:${n.continuationToken}`})}export{createClearFn};
@@ -1,4 +0,0 @@
1
- import type { CompactFn } from "#channel/routes.js";
2
- import type { Runtime } from "#channel/types.js";
3
- /** Builds a channel-scoped manual compaction helper. */
4
- export declare function createCompactFn(runtime: Runtime, channelName: string): CompactFn;
@@ -1 +0,0 @@
1
- function createCompactFn(e,t){return async n=>await e.dispatchContinuation({command:{kind:`compact`},continuationToken:`${t}:${n.continuationToken}`})}export{createCompactFn};
@@ -1,6 +0,0 @@
1
- import type { ResetFn } from "#channel/routes.js";
2
- import type { Runtime } from "#channel/types.js";
3
- /**
4
- * Builds a channel-scoped session reset helper.
5
- */
6
- export declare function createResetFn(runtime: Runtime, channelName: string): ResetFn;
@@ -1 +0,0 @@
1
- function createResetFn(e,t){return async n=>{let r=`${t}:${n.continuationToken}`;return await e.dispatchContinuation({command:{kind:`reset`,reason:n.reason},continuationToken:r})}}export{createResetFn};
@@ -1,4 +0,0 @@
1
- import type { ResolveActiveSessionFn } from "#channel/routes.js";
2
- import type { Runtime } from "#channel/types.js";
3
- /** Builds a channel-scoped lookup for the active owner of a continuation token. */
4
- export declare function createResolveActiveSessionFn(runtime: Runtime, channelName: string): ResolveActiveSessionFn;
@@ -1 +0,0 @@
1
- function createResolveActiveSessionFn(e,t){return({continuationToken:n})=>e.resolveContinuation(`${t}:${n}`)}export{createResolveActiveSessionFn};
@@ -1,6 +0,0 @@
1
- import type { ChannelAdapter } from "#channel/adapter.js";
2
- import type { Runtime } from "#channel/types.js";
3
- import type { SendFn } from "#channel/routes.js";
4
- export declare function createSendFn<TState = undefined>(runtime: Runtime, adapter: ChannelAdapter<any>, channelName: string, metadata?: {
5
- readonly requestId?: string;
6
- }): SendFn<TState>;
@@ -1 +0,0 @@
1
- import{createSession}from"#channel/session.js";import{RuntimeNoActiveSessionError,isRuntimeSessionOwnershipConflictError}from"#execution/runtime-errors.js";import{serializeUrlFilePart}from"#internal/attachments/url-refs.js";function createSendFn(r,i,a,o={}){return async(s,c)=>{let l=c,{auth:u,callback:d,caller:f,capabilities:p,initiatorAuth:m,state:h,title:g}=l,_=l.intent??`resume-or-start`,v=l.mode??`conversation`,y=l.continuationToken,b=`${a}:${y}`,{message:x,inputResponses:S,context:C,outputSchema:w}=normalizeSendInput(s),T=serializeUrlFilePartsInMessage(x),E={auth:u,caller:f,kind:`send`,payload:{inputResponses:S,message:T,context:C,outputSchema:w},requestId:o.requestId},dispatch=async()=>{let t=await r.dispatchContinuation({command:E,continuationToken:b});return t.status===`accepted`?createSession(t.sessionId,y,r):void 0},D=await dispatch();if(D!==void 0)return D;if(_===`resume`)throw new RuntimeNoActiveSessionError(b);if(S&&S.length>0)throw Error(`Cannot deliver inputResponses — the target session was not found via continuation token.`);let O={adapter:h?{...i,state:{...i.state,...h}}:i,auth:u,capabilities:p??(v===`conversation`?{requestInput:!0}:void 0),channelName:a,callback:d,continuationToken:b,input:{message:T??``,context:C,outputSchema:w},mode:v,requestId:o.requestId,title:g};m!==void 0&&(O.initiatorAuth=m);try{return createSession((await r.createSession(O)).sessionId,y,r)}catch(e){if(!isRuntimeSessionOwnershipConflictError(e))throw e;let t=await dispatch();if(t!==void 0)return t;throw e}}}function serializeUrlFilePartsInMessage(e){if(e===void 0||typeof e==`string`)return e;let t=!1,n=e.map(e=>e.type===`file`&&e.data instanceof URL&&e.data.protocol!==`data:`?(t=!0,{...e,data:serializeUrlFilePart(e.data)}):e);return t?n:e}function normalizeSendInput(e){return typeof e==`string`||Array.isArray(e)?{message:e}:e}export{createSendFn};