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
@@ -13,152 +13,120 @@ The channel file stem becomes the channel id, so `agent/channels/internal-webhoo
13
13
 
14
14
  ## Define a channel
15
15
 
16
- ```ts
16
+ Pass the platform's conversation identity to each operation:
17
+
18
+ ```ts title="agent/channels/support.ts"
17
19
  import { defineChannel, GET, POST } from "eve/channels";
18
20
 
19
21
  export default defineChannel({
20
22
  routes: [
21
- POST("/message", async (req, { send }) => {
22
- const body = await req.json();
23
- const session = await send(body.message, {
24
- auth: null,
25
- continuationToken: body.token,
26
- });
23
+ POST("/threads/:threadId/messages", async (request, { from, params }) => {
24
+ const body = await request.json();
25
+ const source = from(params.threadId);
26
+
27
+ if (body.message === "/new") {
28
+ return Response.json(await source.reset({ reason: "User requested /new" }));
29
+ }
27
30
 
31
+ const session = await source.send(body.message, { auth: null });
28
32
  return Response.json({ sessionId: session.id });
29
33
  }),
30
- GET("/sessions/:sessionId/stream", async (_req, { getSession, params }) => {
31
- const session = getSession(params.sessionId);
32
- const stream = await session.getEventStream();
33
34
 
35
+ POST("/threads/:threadId/cancel", async (_request, { from, params }) =>
36
+ Response.json(await from(params.threadId).cancel()),
37
+ ),
38
+ POST("/threads/:threadId/compact", async (_request, { from, params }) =>
39
+ Response.json(await from(params.threadId).compact()),
40
+ ),
41
+ POST("/threads/:threadId/clear", async (_request, { from, params }) =>
42
+ Response.json(await from(params.threadId).clear()),
43
+ ),
44
+
45
+ GET("/sessions/:sessionId/stream", async (_request, { attachSession, params }) => {
46
+ const stream = await attachSession(params.sessionId).getEventStream();
34
47
  return new Response(stream, {
35
48
  headers: { "content-type": "application/x-ndjson; charset=utf-8" },
36
49
  });
37
50
  }),
38
51
  ],
52
+
39
53
  events: {
40
- "message.completed"(event, channel, ctx) {
41
- // deliver completed messages back to the surface that owns this channel
54
+ "message.completed"(event, _channel, ctx) {
55
+ console.log(ctx.session.id, event.message);
42
56
  },
43
57
  },
44
58
  });
45
59
  ```
46
60
 
47
- Declare routes with the `POST()` and `GET()` helpers. Each route handler receives the raw `Request` and a helpers object:
48
-
49
- - `send(message, { auth, continuationToken, state?, title? })` starts or resumes a session. `title` overrides the new workflow session's display title without changing the model message. Returns a `Session`.
50
- - `cancel({ continuationToken, turnId? })` requests cancellation of the active turn on the session that owns the token. See [Cancel a turn](#cancel-a-turn).
51
- - `clear({ continuationToken })` removes the model-message history while preserving the session and its durable resources. See [Clear session context](#clear-session-context).
52
- - `compact({ continuationToken })` queues context compaction for the session that owns the token without sending model input. See [Compact a session](#compact-a-session).
53
- - `reset({ continuationToken, reason? })` retires the session that owns the token so the next `send()` starts a fresh session. See [Reset a session](#reset-a-session).
54
- - `getSession(sessionId)` looks up an existing session. The returned `Session` exposes `getEventStream({ startIndex? })` for streaming, `getStreamTailIndex()` for resolving the durable tail when a route wants to serve bounded reads, and `cancel({ turnId? })` for session-id-addressed cancellation.
55
- - `receive(channel, ...)` hands inbound work to a different channel for cross-channel hand-off.
56
- - `params` holds route parameters extracted from the path pattern.
57
- - `waitUntil(promise)` extends the request lifetime for background work.
58
- - `requestIp` is the client IP, or `null` when the host cannot provide it.
59
-
60
- Event handlers like `"message.completed"` are declared under the `events` key. They receive `(eventData, channel, ctx)`, where `eventData` is the event payload, `channel` carries platform handles and session continuation operations, and `ctx` is the eve `SessionContext`. Every channel kind shares this signature. The one exception is `session.failed`, which receives only `(eventData, channel)` with no `ctx`.
61
-
62
- ## Cancel a turn
63
-
64
- A stop route cancels a session's in-flight turn with the `cancel` helper, addressed by the same channel-local continuation token used with `send()`:
65
-
66
- ```ts
67
- import { defineChannel, POST } from "eve/channels";
68
-
69
- export default defineChannel({
70
- routes: [
71
- POST("/threads/:threadId/stop", async (_req, { cancel, params }) => {
72
- const result = await cancel({ continuationToken: params.threadId });
73
- return Response.json(result);
74
- }),
75
- ],
76
- });
77
- ```
78
-
79
- Both result statuses are successful. `"accepted"` means the cancellation request was consumed, not that the observed turn will cancel; confirmation is `turn.cancelled` followed by `session.waiting` on the event stream. `"no_active_turn"` covers an unknown token and a session with nothing to cancel — idle, parked, or already completed.
61
+ Each route receives these operation surfaces:
80
62
 
81
- Semantics:
63
+ - `from(address)` binds `send`, `respond`, `cancel`, `compact`, `clear`, and `reset` to a channel-local continuation address.
64
+ - `resolveSession(address)` snapshots the session currently owning a channel-local continuation address.
65
+ - `attachSession(sessionId)` creates an I/O-free handle pinned to one durable session ID.
66
+ - `to(channel, target).send(message, options)` hands work to another authored channel.
67
+ - `params`, `waitUntil`, and `requestIp` provide request metadata and lifetime control.
82
68
 
83
- - `cancel` never starts a session, sends input, or clears history. The session parks and accepts the next message normally.
84
- - Pass `turnId` (stamped on every turn-scoped stream event) to guard against stale stop requests. A mismatched guard is consumed as a benign no-op and cannot cancel a newer turn.
85
- - The helper addresses only this channel's sessions; it cannot cancel a session owned by another channel.
86
- - Cancellation stops work without replacement input. Partial streamed output and completed side effects remain observable, and active local or remote subagents receive cancellation recursively.
87
- - The route owns authentication of the inbound stop request, exactly as for `send()`.
69
+ Event handlers receive `(eventData, channel, ctx)`. `ctx.session.id` identifies
70
+ the exact session, while `channel.continuation` exposes the current address and
71
+ `rekey()` when this channel needs to move it. `session.failed` receives only
72
+ `(eventData, channel)` because it runs outside session context; its event data
73
+ contains `sessionId` directly.
88
74
 
89
- When you already hold a `Session` — returned by `send()` or `getSession(sessionId)` — call `session.cancel({ turnId? })` to request the same cancellation addressed by session id.
75
+ `channel.continuation.token` is always the channel-local address accepted by
76
+ `from()`, `resolveSession()`, and `rekey()`. Framework namespace prefixes are not
77
+ part of the authored channel API.
90
78
 
91
- ## Clear session context
79
+ ## Channel operations and session handles
92
80
 
93
- Call `clear` with the channel-local continuation token to remove a session's durable model-message history without replacing the session:
81
+ Channel operations are dynamic: every call targets whichever session currently
82
+ owns the address. Only `send()` can create a session when the address is unowned.
94
83
 
95
84
  ```ts
96
- import { defineChannel, POST } from "eve/channels";
85
+ const source = from(threadId);
97
86
 
98
- export default defineChannel({
99
- routes: [
100
- POST("/threads/:threadId/clear", async (_req, { clear, params }) => {
101
- const result = await clear({ continuationToken: params.threadId });
102
- return Response.json(result);
103
- }),
104
- ],
105
- });
106
- ```
107
-
108
- `"accepted"` means the clear was queued. The stream emits `context.cleared` followed by `session.waiting`, after which the next ordinary message resumes the same session with no prior model messages. The system prompt, configured tools and skills, durable state, limits, continuation-token ownership, and session-scoped sandbox remain. `"no_active_session"` means the token has no current owner.
109
-
110
- ## Compact a session
111
-
112
- Call `compact` with the channel-local continuation token to summarize durable conversation history without delivering a command to the model:
113
-
114
- ```ts
115
- import { defineChannel, POST } from "eve/channels";
87
+ const session = await source.send("Hello", { auth });
88
+ await source.respond(inputResponses, { auth });
89
+ await source.cancel({ turnId });
90
+ await source.compact();
91
+ await source.clear();
92
+ await source.reset({ reason: "Start over" });
116
93
 
117
- export default defineChannel({
118
- routes: [
119
- POST("/threads/:threadId/compact", async (_req, { compact, params }) => {
120
- const result = await compact({ continuationToken: params.threadId });
121
- return Response.json(result);
122
- }),
123
- ],
124
- });
94
+ const currentSession = await resolveSession(threadId);
125
95
  ```
126
96
 
127
- `"accepted"` means the durable session queued the operation. A successful compaction emits `compaction.requested` followed by `compaction.completed`, then the operation returns through `session.waiting`. If summarization fails, the stream returns through `session.waiting` without `compaction.completed` and preserves the previous history. If a turn is active, eve runs the compaction after that turn settles; it does not cancel the turn. `"no_active_session"` means the token has no current owner. Both outcomes are successful, and compaction never starts a session or appends a synthetic user message.
128
-
129
- ## Reset a session
130
-
131
- Identity-addressed channels can consume commands such as `/new` in their route, without sending the command to the model. Call `reset` with the same channel-local continuation token used by `send()`:
97
+ `Session` is fixed: every call targets exactly one durable ID. It never creates,
98
+ follows, or resolves a replacement.
132
99
 
133
100
  ```ts
134
- import { defineChannel, POST } from "eve/channels";
135
-
136
- export default defineChannel({
137
- routes: [
138
- POST("/messages", async (request, { reset, send }) => {
139
- const body = await request.json();
101
+ const session = attachSession(sessionId);
102
+
103
+ await session.send("Follow up", { auth });
104
+ await session.respond(inputResponses, { auth });
105
+ await session.cancel({ turnId });
106
+ await session.compact();
107
+ await session.clear();
108
+ await session.reset({ reason: "Retire this session" });
109
+ await session.getEventStream({ startIndex: 12 });
110
+ ```
140
111
 
141
- if (body.message.trim().toLowerCase() === "/new") {
142
- await reset({
143
- continuationToken: body.conversationId,
144
- reason: "User requested /new",
145
- });
146
- return Response.json({ message: "Started a new conversation." });
147
- }
112
+ Attaching does no lookup. The first operation reports whether the ID is active.
113
+ Call `resolveSession(address)` only when you explicitly need to snapshot an
114
+ address's current owner as a fixed handle.
148
115
 
149
- const session = await send(body.message, {
150
- auth: null,
151
- continuationToken: body.conversationId,
152
- });
153
- return Response.json({ sessionId: session.id });
154
- }),
155
- ],
156
- });
157
- ```
116
+ ## Operation semantics
158
117
 
159
- `reset` returns `{ status: "reset", previousSessionId }` when it observed an owner, or `{ status: "no_active_session" }` when the token was already free. Both outcomes are successful. It terminally cancels the observed workflow run and waits until its non-retained continuation hook no longer blocks reuse, so the next `send()` using the same token creates a new session with fresh history and state.
118
+ - `cancel` cooperatively stops the active turn. Confirm it with `turn.cancelled`
119
+ followed by `session.waiting`; the session accepts another message afterward.
120
+ - `compact` summarizes model context without adding a synthetic user message. A
121
+ success emits `compaction.requested`, `compaction.completed`, then `session.waiting`.
122
+ - `clear` removes model-message history in place. It preserves the system prompt,
123
+ skills, tools, durable state, limits, address ownership, and session sandbox.
124
+ - `reset` terminally retires the current session. A later address `send()` creates
125
+ a fresh session; a fixed `Session` handle remains pinned to the retired ID.
160
126
 
161
- The replacement session owns a new session-scoped sandbox. eve initializes it lazily on that session's first sandbox use, so it never reuses the prior session's workspace or sandbox state. Resetting does not clear history in place, roll back tool calls, or delete the previous run or its sandbox; normal retention and backend cleanup policies still apply. Side effects or partial output that were already committed remain committed. Authenticate and deduplicate inbound command webhooks before calling this helper: a delayed duplicate `/new` can otherwise reset a newer session that has already reclaimed the same token.
127
+ Control operations never create a session. Unknown or inactive targets return a
128
+ benign no-active status. Authenticate and deduplicate command webhooks before
129
+ calling `reset`, because a delayed duplicate can retire a newer address owner.
162
130
 
163
131
  ## CORS
164
132
 
@@ -188,19 +156,19 @@ import { defineChannel, WS } from "eve/channels";
188
156
 
189
157
  export default defineChannel({
190
158
  routes: [
191
- WS("/voice/ws", async (_req, { send }) => ({
159
+ WS("/voice/ws", async (_req, { from }) => ({
192
160
  async message(_peer, message) {
193
- await send(message.text(), {
194
- auth: null,
195
- continuationToken: "voice-demo",
196
- });
161
+ await from("voice-demo").send(message.text(), { auth: null });
197
162
  },
198
163
  })),
199
164
  ],
200
165
  });
201
166
  ```
202
167
 
203
- `WS()` handlers receive the same helpers as HTTP route handlers: `send`, `cancel`, `clear`, `compact`, `reset`, `getSession`, `receive`, `params`, `waitUntil`, and `requestIp`. The returned hooks are eve-owned structural types compatible with Nitro/H3 websocket routing, including `upgrade`, `open`, `message`, `close`, and `error`.
168
+ `WS()` handlers receive the same `from`, `to`, and `attachSession` operations,
169
+ `params`, `waitUntil`, and `requestIp` arguments as HTTP route handlers. The
170
+ returned hooks are eve-owned structural types compatible with Nitro/H3 websocket
171
+ routing, including `upgrade`, `open`, `message`, `close`, and `error`.
204
172
 
205
173
  ### Node upgrade server escape hatch
206
174
 
@@ -222,7 +190,7 @@ The bridge server does not listen on its own port. It receives only upgrade even
222
190
 
223
191
  ## Cross-channel hand-off
224
192
 
225
- Route handlers can start a session on a different channel via `args.receive(channel, ...)`. Use this when an inbound request on one channel should pivot the conversation onto another, such as an incident webhook that opens an investigation thread in Slack.
193
+ Route handlers can start a session on a different channel via `ctx.to(channel, target).send(message, options)`. Use this when an inbound request on one channel should pivot the conversation onto another, such as an incident webhook that opens an investigation thread in Slack.
226
194
 
227
195
  ```ts
228
196
  import { defineChannel, POST } from "eve/channels";
@@ -230,20 +198,20 @@ import slack from "./slack";
230
198
 
231
199
  export default defineChannel({
232
200
  routes: [
233
- POST("/incident", async (req, args) => {
201
+ POST("/incident", async (req, ctx) => {
234
202
  const incident = await req.json();
235
203
 
236
- args.waitUntil(
237
- args.receive(slack, {
238
- message: `Investigate ${incident.reference}: ${incident.title}`,
239
- target: { channelId: "C0123ABC" },
240
- auth: {
241
- authenticator: "incidentio",
242
- principalType: "service",
243
- principalId: incident.actor.id,
244
- attributes: { reference: incident.reference, severity: incident.severity },
245
- },
246
- }),
204
+ ctx.waitUntil(
205
+ ctx
206
+ .to(slack, { channelId: "C0123ABC" })
207
+ .send(`Investigate ${incident.reference}: ${incident.title}`, {
208
+ auth: {
209
+ authenticator: "incidentio",
210
+ principalType: "service",
211
+ principalId: incident.actor.id,
212
+ attributes: { reference: incident.reference, severity: incident.severity },
213
+ },
214
+ }),
247
215
  );
248
216
 
249
217
  return new Response("ok");
@@ -254,9 +222,9 @@ export default defineChannel({
254
222
 
255
223
  Semantics:
256
224
 
257
- - The target channel's authored `receive(input, { send })` hook owns the continuation-token format and initial state. Callers supply only `{ message, target, auth }`.
225
+ - The target channel's authored `receive(input, { from })` hook owns the continuation-token format and initial state. Callers supply the target to `to(...)`, then the message and auth to `send(...)`.
258
226
  - `auth` flows through to `session.auth.initiator` so the target's event handlers and the agent's tools can read who started the session.
259
- - Calling `args.receive(...)` does not also start a session on the current channel. The inbound channel's response is whatever the route handler returns explicitly.
227
+ - Calling `ctx.to(...).send(...)` does not also start a session on the current channel. The inbound channel's response is whatever the route handler returns explicitly.
260
228
  - The first argument is the target channel module's default export. Import it directly from `agent/channels/<name>.ts`. Identity is matched by reference.
261
229
 
262
230
  ## Channel metadata
@@ -281,11 +249,10 @@ export default defineChannel({
281
249
  },
282
250
 
283
251
  routes: [
284
- POST("/start", async (req, { send }) => {
252
+ POST("/start", async (req, { from }) => {
285
253
  const body = await req.json();
286
- await send(body.message, {
254
+ await from(body.token).send(body.message, {
287
255
  auth: null,
288
- continuationToken: body.token,
289
256
  state: { topic: body.topic, contextMessages: body.context, internalCounter: 0 },
290
257
  });
291
258
 
@@ -306,7 +273,7 @@ When a parent agent dispatches a subagent, the framework forwards the parent's c
306
273
 
307
274
  ## Continuation tokens
308
275
 
309
- Each call to `send(message, { auth, continuationToken, state?, title? })` from a channel route addresses a session by its channel-local raw token. The framework prepends the channel name, derived from the file stem under `agent/channels/`, before handing the token to the runtime.
276
+ Each channel operation accepts a channel-local token. The framework prepends the channel name, derived from the file stem under `agent/channels/`, before handing the token to the runtime.
310
277
 
311
278
  ```ts
312
279
  import { slackContinuationToken } from "eve/channels/slack";
@@ -318,11 +285,11 @@ twilioContinuationToken("+15551234567", "+15557654321"); // "+15551234567:+15557
318
285
 
319
286
  Custom channels write their own function that joins the identity fields. The framework derives nothing for you; the channel owns its token format.
320
287
 
321
- When the identity that should address a session is not known until later, the channel can re-key the parked session by calling `session.setContinuationToken(...)`. Pass the channel-local raw token; the runtime preserves the current channel namespace.
288
+ When the identity that should address a session is not known until later, re-key the live address with `channel.continuation?.rekey(rawToken)`. The runtime preserves the current channel namespace.
322
289
 
323
290
  Re-keying changes the address of the current session. `reset` is different: it terminally retires the current session and makes its existing address available to a later `send()`. `cancel` is narrower still: it stops only the active turn and leaves the session, history, and continuation-token ownership intact.
324
291
 
325
- The `context(state, session)` config option builds the per-step `channel` argument handed to every event handler. It receives the channel's live adapter `state` and a `SessionHandle`, and returns the channel-owned context (thread handles, API clients, late-bound callbacks). The framework injects [`ChannelSessionOps`](#define-a-channel) and passes the result as the second positional argument to each handler. Closing over `session` lets the factory register callbacks that re-key the session later. State mutations made through the returned context are written back to adapter state.
292
+ The `context(state, session)` config option builds the per-step `channel` argument handed to every event handler. It receives the channel's live adapter `state` and a `SessionHandle`, and returns the channel-owned context (thread handles, API clients, late-bound callbacks). The framework injects [`ChannelContinuationOps`](#define-a-channel) and passes the result as the second positional argument to each handler. Closing over `session` lets the factory register callbacks that re-key the address later. State mutations made through the returned context are written back to adapter state.
326
293
 
327
294
  ```ts
328
295
  import { defineChannel } from "eve/channels";
@@ -336,7 +303,7 @@ defineChannel<{ ref: string | null }>({
336
303
  state,
337
304
  registerAnchor(ref: string) {
338
305
  state.ref = ref;
339
- session.setContinuationToken(ref);
306
+ session.continuation?.rekey(ref);
340
307
  },
341
308
  };
342
309
  },
@@ -353,15 +320,17 @@ At the next workflow boundary, the runtime claims the new park hook before relea
353
320
 
354
321
  ## File uploads
355
322
 
356
- `send()` accepts `string | UserContent`. To include file attachments, pass a `UserContent` array mixing text and file parts:
323
+ `from(address).send()` accepts a `message` containing `string | UserContent`, while
324
+ `Session.send()` accepts `string | UserContent` directly. To include file
325
+ attachments, pass a `UserContent` array mixing text and file parts:
357
326
 
358
327
  ```ts
359
- await send(
328
+ await from(continuationToken).send(
360
329
  [
361
330
  { type: "text", text: body.message },
362
331
  { type: "file", data: imageBytes, mediaType: "image/png" },
363
332
  ],
364
- { auth, continuationToken },
333
+ { auth },
365
334
  );
366
335
  ```
367
336
 
@@ -377,8 +346,8 @@ defineChannel({
377
346
  },
378
347
 
379
348
  routes: [
380
- POST("/webhook", async (req, { send }) => {
381
- await send(
349
+ POST("/webhook", async (req, { from }) => {
350
+ await from(continuationToken).send(
382
351
  [
383
352
  { type: "text", text: message.text },
384
353
  ...message.attachments.map((a) => ({
@@ -387,7 +356,10 @@ defineChannel({
387
356
  mediaType: a.mediaType,
388
357
  })),
389
358
  ],
390
- { auth, continuationToken, state },
359
+ {
360
+ auth,
361
+ state,
362
+ },
391
363
  );
392
364
  }),
393
365
  ],
@@ -90,7 +90,7 @@ HITL renders as Discord components. Confirmations and options become buttons, `d
90
90
 
91
91
  ### Proactive sessions
92
92
 
93
- Start a session without an inbound interaction through `receive(discord, { message, target, auth })` from a schedule `run` handler, or `args.receive(discord, ...)` from another channel. The proactive target shape is `{ channelId, conversationId?, initialMessage? }`. Either path needs a bot token, supplied by Connect or `DISCORD_BOT_TOKEN`.
93
+ Start a session without an inbound interaction through `to(discord, target).send(message, { auth })` from a schedule `run` handler, or `ctx.to(discord, target).send(message, { auth })` from another channel. The proactive target shape is `{ channelId, conversationId?, initialMessage? }`. Either path needs a bot token, supplied by Connect or `DISCORD_BOT_TOKEN`.
94
94
 
95
95
  ### Attachments
96
96
 
@@ -20,68 +20,112 @@ export default eveChannel({
20
20
 
21
21
  ## Routes
22
22
 
23
- 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:
23
+ The application exposes a health route plus eve channel routes that inspect the agent, create sessions, send follow-ups, control sessions, and stream events:
24
24
 
25
- - `GET /eve/v1/health`
26
- - `GET /eve/v1/info`
27
- - `POST /eve/v1/session` (start a session)
25
+ - `GET /eve/v1/health` (check whether the application is reachable)
26
+ - `GET /eve/v1/info` (inspect the agent)
27
+ - `POST /eve/v1/session` (start a session and send its first message)
28
28
  - `POST /eve/v1/session/:sessionId` (send a follow-up)
29
29
  - `POST /eve/v1/session/:sessionId/cancel` (cancel the in-flight turn)
30
- - `POST /eve/v1/session/clear` (clear the continuation owner's model history)
31
- - `POST /eve/v1/session/compact` (compact the continuation owner's context)
32
- - `POST /eve/v1/session/reset` (retire the continuation owner)
33
- - `GET /eve/v1/session/:sessionId/stream` (stream events, NDJSON)
30
+ - `POST /eve/v1/session/:sessionId/clear` (clear the session's model history)
31
+ - `POST /eve/v1/session/:sessionId/compact` (compact the session's context)
32
+ - `POST /eve/v1/session/:sessionId/reset` (retire the session)
33
+ - `GET /eve/v1/session/:sessionId/stream` (stream events as NDJSON)
34
34
 
35
- Start a session with a minimal body. The response returns `sessionId` and the `continuationToken` you reuse for follow-ups:
35
+ The session routes use only durable session IDs. Create a session explicitly, then put its returned ID in every follow-up, control, and stream path.
36
+
37
+ ### Start and continue a session
36
38
 
37
39
  ```bash
38
40
  curl -X POST https://<deployment>/eve/v1/session \
39
41
  -H "Content-Type: application/json" \
40
42
  -d '{"message":"What is the weather in Paris?"}'
41
- # {"continuationToken":"eve:7f3c...","ok":true,"sessionId":"ses_01h..."}
43
+ # {"ok":true,"sessionId":"wrun_A","status":"accepted"}
44
+
45
+ curl -X POST https://<deployment>/eve/v1/session/wrun_A \
46
+ -H "Content-Type: application/json" \
47
+ -d '{"message":"How about tomorrow?"}'
48
+ ```
49
+
50
+ The first request requires `message`. A follow-up request accepts exactly one of
51
+ `message` or `inputResponses`; use the latter to answer a pending HITL request:
52
+
53
+ ```bash
54
+ curl -X POST https://<deployment>/eve/v1/session/wrun_A \
55
+ -H "Content-Type: application/json" \
56
+ -d '{"inputResponses":[{"requestId":"req_A","optionId":"approve"}]}'
42
57
  ```
43
58
 
44
- Stream that session's events as newline-delimited JSON (`application/x-ndjson; charset=utf-8`), one event object per line:
59
+ Sending a message to an unknown or terminal session ID returns `409` with
60
+ `{"code":"session_not_active","error":"The session is no longer active.","ok":false}`.
61
+ TypeScript clients expose the stable code as `ClientError.code`. The route never
62
+ creates or follows a replacement session.
63
+
64
+ ### Stream events
65
+
66
+ Stream responses are newline-delimited JSON (`application/x-ndjson; charset=utf-8`), one event object per line:
45
67
 
46
68
  ```bash
47
- curl -N https://<deployment>/eve/v1/session/ses_01h.../stream
69
+ curl -N https://<deployment>/eve/v1/session/wrun_A/stream
48
70
  # {"type":"turn.started",...}
49
71
  # {"type":"message.appended","data":{"messageDelta":"It is ",...}}
50
72
  # {"type":"message.completed",...}
51
73
  ```
52
74
 
75
+ ### Cancel a turn
76
+
53
77
  Cancel a session's in-flight turn with an empty body, or scope the cancel to the turn you observed by passing the `turnId` stamped on that turn's stream events:
54
78
 
55
79
  ```bash
56
- curl -X POST https://<deployment>/eve/v1/session/ses_01h.../cancel
57
- # {"ok":true,"sessionId":"ses_01h...","status":"accepted"}
80
+ curl -X POST https://<deployment>/eve/v1/session/wrun_A/cancel
81
+ # {"ok":true,"sessionId":"wrun_A","status":"accepted"}
82
+ ```
83
+
84
+ Cancellation is asynchronous: `"accepted"` means the live session durably queued the request. Confirm an actual cancellation 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. Content emitted before cancellation stays on the event stream, while durable model history keeps only content that had already settled. The session accepts the next message normally.
85
+
86
+ An accepted cancellation returns HTTP `202` with `sessionId`. An inactive target
87
+ returns HTTP `200` with `{"ok":true,"status":"no_active_turn"}`.
88
+
89
+ A live session also returns `"accepted"` when it is already parked; the driver consumes that late or duplicate cancel as a no-op. An unknown or terminal session returns `"no_active_turn"`. A `turnId` naming any other turn is likewise accepted and consumed as a no-op, so a guarded cancel racing a turn boundary cannot stop a turn the caller never saw.
90
+
91
+ ### Clear context
92
+
93
+ Clear one session's model-message history without replacing the session:
94
+
95
+ ```bash
96
+ curl -X POST https://<deployment>/eve/v1/session/wrun_A/clear
97
+ # {"ok":true,"sessionId":"wrun_A","status":"accepted"}
58
98
  ```
59
99
 
60
- 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.
100
+ An accepted clear emits `context.cleared` followed by `session.waiting`. The next message uses the same session without prior model messages; the system prompt, tools, skills, durable state, limits, and session-scoped sandbox remain.
101
+
102
+ ### Compact context
61
103
 
62
- Clear the model-message history of the session that owns a continuation token:
104
+ Compact one session's context without sending a message:
63
105
 
64
106
  ```bash
65
- curl -X POST https://<deployment>/eve/v1/session/clear \
66
- -H "Content-Type: application/json" \
67
- -d '{"continuationToken":"eve:7f3c..."}'
68
- # {"ok":true,"sessionId":"ses_01h...","status":"accepted"}
107
+ curl -X POST https://<deployment>/eve/v1/session/wrun_A/compact
108
+ # {"ok":true,"sessionId":"wrun_A","status":"accepted"}
69
109
  ```
70
110
 
71
- 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.
111
+ Compaction is asynchronous. A successful operation emits `compaction.requested` and `compaction.completed`, then returns through `session.waiting`. When a turn is active, compaction waits for it to settle. If summarization fails, the session still returns to `session.waiting` with its previous history.
72
112
 
73
- Compact the session that owns a continuation token without sending a message:
113
+ ### Reset a session
114
+
115
+ Reset terminally retires the exact session ID:
74
116
 
75
117
  ```bash
76
- curl -X POST https://<deployment>/eve/v1/session/compact \
118
+ curl -X POST https://<deployment>/eve/v1/session/wrun_A/reset \
77
119
  -H "Content-Type: application/json" \
78
- -d '{"continuationToken":"eve:7f3c..."}'
79
- # {"ok":true,"sessionId":"ses_01h...","status":"accepted"}
120
+ -d '{"reason":"Start over"}'
121
+ # {"ok":true,"previousSessionId":"wrun_A","status":"reset"}
80
122
  ```
81
123
 
82
- 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.
124
+ After reset, the old ID cannot accept another message. Start a replacement explicitly with `POST /eve/v1/session`.
125
+
126
+ The control routes never create sessions. `compact`, `clear`, and `reset` return `"no_active_session"` when the ID is already inactive. Session message and control request/response bodies do not accept or return continuation tokens. For compatibility, the streamed `session.waiting` event retains `data.continuationToken`: it is the channel-local token for a channel-addressed session and the immutable session ID for an ID-only session. New clients should continue through their fixed session handle instead of reading this field.
83
127
 
84
- See [Sessions, runs & streaming](../concepts/sessions-runs-and-streaming) for the full request and stream flow, including the complete event set.
128
+ See [Sessions, runs & streaming](../concepts/sessions-runs-and-streaming) for the complete event set, operation results, and cursor behavior.
85
129
 
86
130
  ## CORS
87
131
 
@@ -137,9 +181,8 @@ export default eveChannel({
137
181
  };
138
182
  },
139
183
  events: {
140
- "message.completed"(eventData, channel, ctx) {
184
+ "message.completed"(eventData, _channel, ctx) {
141
185
  console.log("eve response completed", {
142
- continuationToken: channel.continuationToken,
143
186
  sessionId: ctx.session.id,
144
187
  });
145
188
  },
@@ -147,11 +190,14 @@ export default eveChannel({
147
190
  });
148
191
  ```
149
192
 
193
+ `onMessage` must return an auth result. A successful canonical eve HTTP message
194
+ always dispatches and therefore always produces or continues a session.
195
+
150
196
  ## Clients
151
197
 
152
198
  The browser side of this API lives in the [Frontend](../guides/frontend/overview) docs, where `useEveAgent` drives the eve channel from React UI.
153
199
 
154
- For scripts, server-to-server calls, evals, tests, and custom clients, use the [TypeScript SDK](../guides/client/overview). It wraps the session routes, continuation token, stream cursor, and reconnect loop.
200
+ For scripts, server-to-server calls, evals, tests, and custom clients, use the [TypeScript SDK](../guides/client/overview). It wraps the ID-addressed session routes, stream cursor, and reconnect loop.
155
201
 
156
202
  ## What to read next
157
203
 
@@ -103,7 +103,7 @@ GitHub comments have no interactive button or card affordance. A human-in-the-lo
103
103
 
104
104
  ### Proactive sessions
105
105
 
106
- Start a session without an inbound comment invocation through `receive(github, { message, target, auth })` from a schedule `run` handler, or `args.receive(github, ...)` from another channel. The target requires `owner`, `repo`, and exactly one of `issueNumber` or `pullRequestNumber`.
106
+ Start a session without an inbound comment invocation through `to(github, target).send(message, { auth })` from a schedule `run` handler, or `ctx.to(github, target).send(message, { auth })` from another channel. The target requires `owner`, `repo`, and exactly one of `issueNumber` or `pullRequestNumber`.
107
107
 
108
108
  ### Attachments
109
109
 
@@ -160,7 +160,7 @@ await channel.linear.updateSession({
160
160
 
161
161
  ## Proactive sessions
162
162
 
163
- Use the channel's `receive` target to continue an existing Agent Session or create one from a Linear issue or root comment. The target accepts an existing `agentSessionId`, or an `issueId` or root `commentId` to create a new session before sending the message. The example below runs from a schedule; a route handler uses the same target shape through its own `receive` helper.
163
+ Use the channel's proactive target to continue an existing Agent Session or create one from a Linear issue or root comment. The target accepts an existing `agentSessionId`, or an `issueId` or root `commentId` to create a new session before sending the message. The example below runs from a schedule; a route handler uses the same target shape through `ctx.to(...)`.
164
164
 
165
165
  ```ts
166
166
  import { defineSchedule } from "eve/schedules";
@@ -169,15 +169,13 @@ import linear from "../channels/linear";
169
169
 
170
170
  export default defineSchedule({
171
171
  cron: "0 14 * * 1",
172
- async run({ receive, waitUntil, appAuth }) {
172
+ async run({ to, waitUntil, appAuth }) {
173
173
  waitUntil(
174
- receive(linear, {
174
+ to(linear, {
175
+ issueId: "EVE-123",
176
+ initialActivity: "Preparing the status update.",
177
+ }).send("Post a concise status update with blockers and next actions.", {
175
178
  auth: appAuth,
176
- message: "Post a concise status update with blockers and next actions.",
177
- target: {
178
- issueId: "EVE-123",
179
- initialActivity: "Preparing the status update.",
180
- },
181
179
  }),
182
180
  );
183
181
  },